Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9d8d7fa
Add minimum classes for sc-transactions implementation (element versi…
IRomanchuk06 Mar 22, 2025
bbd5206
Basic structures, transaction_manager init, remove epoch, supplement …
IRomanchuk06 Mar 23, 2025
1d0fc23
Add transaction-related methods (.h), use sc_* types
IRomanchuk06 Mar 24, 2025
29cd498
Add sc_transaction_clear
IRomanchuk06 Mar 24, 2025
84f8bac
Implemented initialization method for the manager and transaction cre…
IRomanchuk06 Mar 24, 2025
ba1ff66
Fix link error, correct sc_transaction_manager vars name
IRomanchuk06 Mar 25, 2025
6e28a24
Change element version handling
IRomanchuk06 Mar 25, 2025
1a5d43d
Upgrade .gitignore
IRomanchuk06 Mar 25, 2025
2967adc
Connect txn and buffer, init for buffer
IRomanchuk06 Mar 25, 2025
a4df08d
Highlighted 4 types of operation, flags to track sc-element field cha…
IRomanchuk06 Mar 26, 2025
c433d47
Tests for buffer (add created element)
IRomanchuk06 Mar 26, 2025
06a7dcb
Implementation of transaction_buffer
IRomanchuk06 Mar 28, 2025
a418e36
Replace sc_addr pointers with their hash values in lists
IRomanchuk06 Mar 30, 2025
5ca1034
Generation of id's for elements versions using monitor_table
IRomanchuk06 Mar 30, 2025
c3e7cb1
Refactor
IRomanchuk06 Mar 30, 2025
f97767e
Linear version history
IRomanchuk06 Apr 3, 2025
fd3440b
Transaction buffer operations, refactor
IRomanchuk06 Apr 3, 2025
8e01f63
Add txn buffer tests, format code, refactor
IRomanchuk06 Apr 5, 2025
96e1c8f
Fix txn buffer content save, tests for sc_transaction
IRomanchuk06 Apr 5, 2025
af0f29a
Tests fix
IRomanchuk06 Apr 9, 2025
ae7903c
Transaction manager queue handling
IRomanchuk06 Apr 9, 2025
e6e59d8
Use transaction manager as global, transaction queue add, queue handl…
IRomanchuk06 Apr 10, 2025
795c295
Add implementation of wrapper methods for managing GThread threads
IRomanchuk06 Apr 10, 2025
61b1539
Use wrapper methods for threads in manager
IRomanchuk06 Apr 10, 2025
cfd7d8d
External memory allocation for the manager
IRomanchuk06 Apr 10, 2025
6cf6c41
Manager ini returns sc_result
IRomanchuk06 Apr 10, 2025
90fb0e5
Manager tests
IRomanchuk06 Apr 10, 2025
8f972be
Fix txn buffer init and destroy
IRomanchuk06 Apr 10, 2025
6143ff4
Rename txn manager, use var for txn id, highligh the methods for the api
IRomanchuk06 Apr 11, 2025
63c29a9
Init txn manager with sc-memory
IRomanchuk06 Apr 11, 2025
6c0bcee
Update tests
IRomanchuk06 Apr 11, 2025
40e6e49
Context is assigned to a transaction, update tests
IRomanchuk06 Apr 11, 2025
fbea119
Add example of operation on sc-memory within a transaction
IRomanchuk06 Apr 11, 2025
04b869b
Remove redundant flags
IRomanchuk06 Apr 16, 2025
2d56991
Use segment for store element version history
IRomanchuk06 May 6, 2025
7f4f263
Update
IRomanchuk06 May 7, 2025
271ad88
Add sc_storage_get_element_data_by_addr
IRomanchuk06 May 7, 2025
21f83c7
Fix cyclic inclusion of file headers
IRomanchuk06 May 7, 2025
1a46dac
New_elements list in txn_bufer store sc_element_data
IRomanchuk06 May 7, 2025
9e5440d
Txn use element data copy in operations, new elements created immedia…
IRomanchuk06 May 8, 2025
37dd131
Base txn operations, tests, correct manager init
IRomanchuk06 May 12, 2025
a32c7e4
Transaction validation process logic
IRomanchuk06 May 12, 2025
43a1959
Txn commit logic, fix sc-element init, txn state, add version logic (…
IRomanchuk06 May 13, 2025
9d6304b
Delete element txn logic, format code
IRomanchuk06 May 13, 2025
9cc97a1
Add sc_thread_sleep (glib)
IRomanchuk06 May 13, 2025
2ce15b7
Fix txn_manager init, fix txn validation, rewrite buffer tests, start…
IRomanchuk06 May 13, 2025
5ce3646
Fix deadlock in txn_handler and intersect
IRomanchuk06 May 14, 2025
6310a81
Fix monitor lock in txn operation
IRomanchuk06 May 14, 2025
e71d400
Benchmark tests
IRomanchuk06 May 15, 2025
0911739
Txn operations return sc_addr
IRomanchuk06 May 20, 2025
8d97092
Merge branch 'ostis-ai:main' into feat/sc_memory_knowledge_sync
IRomanchuk06 Oct 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "sc_element_version.h"
14 changes: 14 additions & 0 deletions sc-memory/sc-core/src/sc-store/sc-transaction/sc_element_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef SC_ELEMENT_VERSION_H
#define SC_ELEMENT_VERSION_H

#include "sc-core/sc_types.h"

typedef struct sc_element_version {
void* data;
sc_uint64 version_id;
struct sc_element_version* prev_version;
struct sc_element_version* next_version;
sc_bool is_committed;
} sc_element_version;

#endif
24 changes: 24 additions & 0 deletions sc-memory/sc-core/src/sc-store/sc-transaction/sc_transaction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "sc_transaction.h"

#include <sc-core/sc-base/sc_allocator.h>

sc_transaction* sc_transaction_create(const sc_uint64* txn_id) {
sc_transaction *txn = sc_mem_new(sc_transaction, 1);
if (txn == NULL) {
return NULL;
}

txn->transaction_id = *txn_id;
txn->is_committed = SC_FALSE;
txn->element_count = 0;
sc_list_init(&txn->elements);
return txn;
}

void sc_transaction_destroy(sc_transaction* txn) {
if (txn != NULL) {
sc_list_clear(txn->elements);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sc_list_clear(txn->elements);
sc_list_destroy(txn->elements);


sc_mem_free(txn);
}
}
34 changes: 34 additions & 0 deletions sc-memory/sc-core/src/sc-store/sc-transaction/sc_transaction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef SC_TRANSACTION_H
#define SC_TRANSACTION_H

#include <sc-core/sc-container/sc_list.h>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider including "sc_element.h" so that the type sc_element is defined for sc_transaction_add_element.


typedef struct sc_transaction {
sc_uint64 transaction_id;
sc_bool is_committed;
sc_list* elements;
sc_uint32 element_count;
} sc_transaction;

sc_transaction* sc_transaction_create(const sc_uint64* txn_id);
// create a new transaction
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use another style for code strings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly should be adjusted to match the required code style?

void sc_transaction_destroy(sc_transaction* txn);
// destroy the given transaction

void sc_transaction_add_element(sc_transaction* txn, sc_element* element);
// add element to track in transaction (based on "touched" elements, manager will try to commit or rollback transaction)
void sc_transaction_commit(sc_transaction* txn);
// apply all operations of the transaction on sc-memory
void sc_transaction_rollback(sc_transaction* txn);
// rollback the transaction operations

sc_bool sc_transaction_validate(sc_transaction* txn);
// check if the transaction can be applied based on element versions and free segments
void sc_transaction_merge(sc_transaction* txn);
// check versions of all elements in the transaction and try to merge them
void sc_transaction_apply(sc_transaction* txn);
// apply all operations (merged versions, allocated spaces) to sc-memory
void sc_transaction_clear(sc_transaction* txn);
// deletes all transaction items and clears them without performing a commit

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "sc_transaction_manager.h"

#include <sc-core/sc-base/sc_allocator.h>

sc_transaction_manager * transaction_manager = null_ptr;

sc_transaction_manager* sc_transaction_manager_initialize() {
if (sc_transaction_manager_is_initialized()) {
return transaction_manager;
}

transaction_manager = sc_mem_new(sc_transaction_manager, 1);
if (!sc_transaction_manager_is_initialized()) {
return null_ptr;
}

transaction_manager->current_sc_transaction = null_ptr;
sc_queue_init(transaction_manager->sc_transaction_queue);
sc_monitor_init(transaction_manager->sc_monitor);
transaction_manager->transaction_counter = 0;

return transaction_manager;
}

sc_bool sc_transaction_manager_is_initialized() {
return transaction_manager != null_ptr;
}

void sc_transaction_shutdown() {
if (transaction_manager != null_ptr) {
sc_transaction_manager_destroy();
}
}

void sc_transaction_manager_destroy() {
if (transaction_manager != null_ptr) {
sc_monitor_acquire_write(transaction_manager->sc_monitor);
sc_queue_destroy(transaction_manager->sc_transaction_queue);
sc_monitor_release_write(transaction_manager->sc_monitor);

sc_monitor_destroy(transaction_manager->sc_monitor);

sc_mem_free(transaction_manager);
transaction_manager = null_ptr;
}
}

sc_transaction* sc_transaction_manager_transaction_new() {
if (!sc_transaction_manager_is_initialized()) {
return null_ptr;
}

sc_monitor_acquire_write(transaction_manager->sc_monitor);
const sc_uint64 txn_id = transaction_manager->transaction_counter++;
sc_monitor_release_write(transaction_manager->sc_monitor);

return sc_transaction_create(&txn_id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef SC_TRANSACTION_MANAGER_H
#define SC_TRANSACTION_MANAGER_H

#include "sc_transaction.h"
#include "sc-store/sc-base/sc_monitor_private.h"

typedef struct sc_transaction_manager {
sc_transaction*current_sc_transaction;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a space between the * and current_sc_transaction (i.e., change sc_transaction*current_sc_transaction to sc_transaction* current_sc_transaction) for better readability.

Suggested change
sc_transaction*current_sc_transaction;
sc_transaction* current_sc_transaction;

sc_queue* sc_transaction_queue;
sc_monitor* sc_monitor;
sc_uint64 transaction_counter;
} sc_transaction_manager;

sc_transaction_manager* sc_transaction_manager_initialize();
// create and initialize the transaction manager
sc_bool sc_transaction_manager_is_initialized();
// check if the transaction manager is initialized
void sc_transaction_shutdown();
// shutdown the transaction manager

sc_transaction* sc_transaction_manager_transaction_new();
// create a new empty sc-transaction
void sc_transaction_manager_transaction_add(sc_transaction* txn);
// add transaction to the queue and start operations when the thread is ready
void sc_transaction_manager_transaction_execute();
// try to execute the transaction and wait till it's finished

void sc_transaction_manager_destroy();
// destroy the transaction manager

#endif
3 changes: 3 additions & 0 deletions sc-memory/sc-core/src/sc-store/sc_element.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define _sc_element_h_

#include "sc-core/sc_types.h"
#include "sc-transaction/sc_element_version.h"

struct _sc_arc_info
{
Expand Down Expand Up @@ -65,6 +66,8 @@ struct _sc_element

sc_uint32 incoming_arcs_count;
sc_uint32 outgoing_arcs_count;

sc_element_version* current_version;
};

#endif
95 changes: 95 additions & 0 deletions sc-memory/sc-core/tests/units/common/test_sc_transaction_core.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <gtest/gtest.h>
#include <pthread.h>
#include <sc-memory/test/sc_test.hpp>

extern "C" {
#include <sc-store/sc-transaction/sc_transaction_manager.h>
}

struct TransactionThreadData {
transaction_manager* manager;
int thread_id;
};

void* transaction_thread(void* arg) {
auto* data = static_cast<TransactionThreadData*>(arg);
transaction_manager* manager = data->manager;

sc_element_version version = {};
log_version_change(manager, &version);

if (data->thread_id % 2 == 0) {
commit_transaction(manager);
} else {
rollback_transaction(manager);
}

return nullptr;
}

TEST_F(ScMemoryTest, MultiThreadedTransactionTest) {
transaction_manager manager;
initialize_transaction_manager(&manager);

const int NUM_THREADS = 10;
pthread_t threads[NUM_THREADS];
TransactionThreadData thread_data[NUM_THREADS];

for (int i = 0; i < NUM_THREADS; ++i) {
thread_data[i].manager = &manager;
thread_data[i].thread_id = i;
pthread_create(&threads[i], nullptr, transaction_thread, &thread_data[i]);
}

for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], nullptr);
}

EXPECT_EQ(manager.current_transaction, nullptr);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test refers to manager.current_transaction but the structure defines current_sc_transaction; please ensure consistent naming.


EXPECT_NE(manager.log_head, nullptr);
}

TEST_F(ScMemoryTest, MultiThreadedTransactionLogTest) {
transaction_manager manager;
initialize_transaction_manager(&manager);

const int NUM_THREADS = 5;
pthread_t threads[NUM_THREADS];
TransactionThreadData thread_data[NUM_THREADS];

for (int i = 0; i < NUM_THREADS; ++i) {
thread_data[i].manager = &manager;
thread_data[i].thread_id = i;
pthread_create(&threads[i], nullptr, transaction_thread, &thread_data[i]);
}

for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], nullptr);
}

EXPECT_NE(manager.log_head, nullptr);
}

TEST_F(ScMemoryTest, TransactionManagerTests) {
transaction_manager manager;
initialize_transaction_manager(&manager);

const int NUM_THREADS = 20;
pthread_t threads[NUM_THREADS];
TransactionThreadData thread_data[NUM_THREADS];

for (int i = 0; i < NUM_THREADS; ++i) {
thread_data[i].manager = &manager;
thread_data[i].thread_id = i;
pthread_create(&threads[i], nullptr, transaction_thread, &thread_data[i]);
}

for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], nullptr);
}

EXPECT_EQ(manager.current_transaction, nullptr);

EXPECT_NE(manager.log_head, nullptr);
}
Loading