make GSI less shit
This commit is contained in:
@@ -8,6 +8,7 @@ import "../rocksdb"
|
||||
|
||||
// UpdateItem — fetch existing item, apply update plan, write back
|
||||
// Uses EXCLUSIVE lock (write operation)
|
||||
// ATOMICITY: Uses WriteBatch to ensure base item + all GSI updates are atomic
|
||||
//
|
||||
// Returns:
|
||||
// - old_item: the item BEFORE mutations (if it existed), for ReturnValues
|
||||
@@ -59,7 +60,7 @@ update_item :: proc(
|
||||
return nil, nil, .Serialization_Error
|
||||
}
|
||||
existing_item = decoded
|
||||
// Save old item for ReturnValues
|
||||
// Save old item for ReturnValues (and for GSI cleanup)
|
||||
old_item = item_deep_copy(existing_item)
|
||||
} else if get_err == .NotFound || existing_encoded == nil {
|
||||
// Item doesn't exist yet — start with just the key attributes
|
||||
@@ -109,9 +110,46 @@ update_item :: proc(
|
||||
}
|
||||
defer delete(encoded_item)
|
||||
|
||||
// Write back to RocksDB
|
||||
put_err := rocksdb.db_put(&engine.db, storage_key, encoded_item)
|
||||
if put_err != .None {
|
||||
// --- ATOMIC WRITE BATCH: base item + all GSI updates ---
|
||||
batch, batch_err := rocksdb.batch_create()
|
||||
if batch_err != .None {
|
||||
item_destroy(&existing_item)
|
||||
if old, has := old_item.?; has {
|
||||
old_copy := old
|
||||
item_destroy(&old_copy)
|
||||
}
|
||||
return nil, nil, .RocksDB_Error
|
||||
}
|
||||
defer rocksdb.batch_destroy(&batch)
|
||||
|
||||
// Add base item write to batch
|
||||
rocksdb.batch_put(&batch, storage_key, encoded_item)
|
||||
|
||||
// Add old GSI entry deletions to batch (if item existed before)
|
||||
if old, has := old_item.?; has {
|
||||
gsi_del_err := gsi_batch_delete_entries(&batch, table_name, old, &metadata)
|
||||
if gsi_del_err != .None {
|
||||
item_destroy(&existing_item)
|
||||
old_copy := old
|
||||
item_destroy(&old_copy)
|
||||
return nil, nil, gsi_del_err
|
||||
}
|
||||
}
|
||||
|
||||
// Add new GSI entry writes to batch
|
||||
gsi_write_err := gsi_batch_write_entries(&batch, table_name, existing_item, &metadata)
|
||||
if gsi_write_err != .None {
|
||||
item_destroy(&existing_item)
|
||||
if old, has := old_item.?; has {
|
||||
old_copy := old
|
||||
item_destroy(&old_copy)
|
||||
}
|
||||
return nil, nil, gsi_write_err
|
||||
}
|
||||
|
||||
// Write batch atomically - ALL or NOTHING
|
||||
write_err := rocksdb.batch_write(&engine.db, &batch)
|
||||
if write_err != .None {
|
||||
item_destroy(&existing_item)
|
||||
if old, has := old_item.?; has {
|
||||
old_copy := old
|
||||
@@ -120,12 +158,6 @@ update_item :: proc(
|
||||
return nil, nil, .RocksDB_Error
|
||||
}
|
||||
|
||||
// --- GSI maintenance: delete old entries, write new entries ---
|
||||
if old, has := old_item.?; has {
|
||||
gsi_delete_entries(engine, table_name, old, &metadata)
|
||||
}
|
||||
gsi_write_entries(engine, table_name, existing_item, &metadata)
|
||||
|
||||
new_item = existing_item
|
||||
return old_item, new_item, .None
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user