aboutsummaryrefslogtreecommitdiff
path: root/ref/store/memory/transaction.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-05-24 13:41:34 +0000
committerGravatar Runxi Yu2026-05-24 14:12:35 +0000
commit947bf81a33c6e4e5d21c8b36f9317fe00b84f6ae (patch)
tree67824655ef9dbf2d941dae06d59ea29a1e32d458 /ref/store/memory/transaction.go
parentREADME: Update (diff)
signatureNo signature
ref/store/memory: Simple memory-backed ref store v0.1.175
Diffstat (limited to 'ref/store/memory/transaction.go')
-rw-r--r--ref/store/memory/transaction.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/ref/store/memory/transaction.go b/ref/store/memory/transaction.go
new file mode 100644
index 00000000..81ae01ef
--- /dev/null
+++ b/ref/store/memory/transaction.go
@@ -0,0 +1,97 @@
+package memory
+
+import (
+ objectid "codeberg.org/lindenii/furgit/object/id"
+ refstore "codeberg.org/lindenii/furgit/ref/store"
+)
+
+// Transaction stages in-memory updates for one atomic commit.
+type Transaction struct {
+ store *Store
+ ops []queuedUpdate
+}
+
+var _ refstore.Transaction = (*Transaction)(nil)
+
+// BeginTransaction creates one new in-memory transaction.
+//
+//nolint:ireturn
+func (store *Store) BeginTransaction() (refstore.Transaction, error) {
+ return &Transaction{
+ store: store,
+ ops: make([]queuedUpdate, 0, 8),
+ }, nil
+}
+
+// Create queues a detached reference creation.
+func (tx *Transaction) Create(name string, newID objectid.ObjectID) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateCreate, newID: newID})
+}
+
+// Update queues a detached reference update.
+func (tx *Transaction) Update(name string, newID, oldID objectid.ObjectID) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateReplace, newID: newID, oldID: oldID})
+}
+
+// Delete queues a detached reference deletion.
+func (tx *Transaction) Delete(name string, oldID objectid.ObjectID) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateDelete, oldID: oldID})
+}
+
+// Verify queues a detached reference verification.
+func (tx *Transaction) Verify(name string, oldID objectid.ObjectID) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateVerify, oldID: oldID})
+}
+
+// CreateSymbolic queues a symbolic reference creation.
+func (tx *Transaction) CreateSymbolic(name, newTarget string) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateCreateSymbolic, newTarget: newTarget})
+}
+
+// UpdateSymbolic queues a symbolic reference update.
+func (tx *Transaction) UpdateSymbolic(name, newTarget, oldTarget string) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateReplaceSymbolic, newTarget: newTarget, oldTarget: oldTarget})
+}
+
+// DeleteSymbolic queues a symbolic reference deletion.
+func (tx *Transaction) DeleteSymbolic(name, oldTarget string) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateDeleteSymbolic, oldTarget: oldTarget})
+}
+
+// VerifySymbolic queues a symbolic reference verification.
+func (tx *Transaction) VerifySymbolic(name, oldTarget string) error {
+ return tx.queue(queuedUpdate{name: name, kind: updateVerifySymbolic, oldTarget: oldTarget})
+}
+
+// Commit validates and applies the queued updates atomically.
+func (tx *Transaction) Commit() error {
+ tx.store.mu.Lock()
+ defer tx.store.mu.Unlock()
+
+ prepared, err := prepareUpdates(tx.store.refs, tx.ops)
+ if err != nil {
+ return err
+ }
+
+ next := cloneRefs(tx.store.refs)
+ applyPreparedUpdates(next, prepared)
+ tx.store.refs = next
+
+ return nil
+}
+
+// Abort abandons the transaction.
+func (tx *Transaction) Abort() error {
+ return nil
+}
+
+func (tx *Transaction) queue(op queuedUpdate) error {
+ err := validateQueuedUpdate(op)
+ if err != nil {
+ return err
+ }
+
+ tx.ops = append(tx.ops, op)
+
+ return nil
+}