diff --git a/part/map_test.go b/part/map_test.go index 55e23fe..85a0f91 100644 --- a/part/map_test.go +++ b/part/map_test.go @@ -368,19 +368,38 @@ func TestMapTxn(t *testing.T) { assert.Equal(t, 88, v) tree = txn.Commit() - // Transaction can be reused after commit + // Transaction can be reused after commit (singleton case) + assert.Nil(t, tree.tree.root) + assert.False(t, tree.hasTree) txn.Set("baz", 99) - mp = maps.Collect(txn.All()) - assert.Len(t, mp, 2) - assert.Equal(t, map[string]int{"bar": 88, "baz": 99}, mp) mp = maps.Collect(tree.All()) assert.Len(t, mp, 1) assert.Equal(t, map[string]int{"bar": 88}, mp) + mp = maps.Collect(txn.All()) + assert.Len(t, mp, 2) + assert.Equal(t, map[string]int{"bar": 88, "baz": 99}, mp) + // Set again since All() bumps txnID + txn.Set("baz", 99) tree = txn.Commit() + + // Transaction can be reused after commit (non-singleton case) + assert.NotNil(t, tree.tree.root) + assert.True(t, tree.hasTree) + txn.Set("baz", 999) + mp = maps.Collect(tree.All()) assert.Len(t, mp, 2) assert.Equal(t, map[string]int{"bar": 88, "baz": 99}, mp) + + mp = maps.Collect(txn.All()) + assert.Len(t, mp, 2) + assert.Equal(t, map[string]int{"bar": 88, "baz": 999}, mp) + + tree = txn.Commit() + mp = maps.Collect(tree.All()) + assert.Len(t, mp, 2) + assert.Equal(t, map[string]int{"bar": 88, "baz": 999}, mp) } func TestUint64Map(t *testing.T) { diff --git a/part/tree.go b/part/tree.go index 7134549..24ea5e6 100644 --- a/part/tree.go +++ b/part/tree.go @@ -19,7 +19,7 @@ type Tree[T any] struct { size int // the number of objects in the tree opts options prevTxn *atomic.Pointer[Txn[T]] // the previous txn for reusing the allocation - prevTxnID uint64 // the transaction ID that produced this tree + nextTxnID uint64 // the next transaction ID to use } // New constructs a new tree. @@ -74,7 +74,7 @@ func (t *Tree[T]) Txn() *Txn[T] { txn.rootWatch = t.rootWatch txn.size = t.size txn.prevTxn = t.prevTxn - txn.txnID = t.prevTxnID + 1 + txn.txnID = t.nextTxnID return txn } diff --git a/part/txn.go b/part/txn.go index b6f484e..4d4936d 100644 --- a/part/txn.go +++ b/part/txn.go @@ -65,7 +65,7 @@ func (txn *Txn[T]) Clone() Tree[T] { rootWatch: txn.rootWatch, size: txn.size, prevTxn: txn.prevTxn, - prevTxnID: txn.txnID, + nextTxnID: txn.txnID, } } @@ -185,13 +185,14 @@ func (txn *Txn[T]) Commit() Tree[T] { validateTree(txn.oldRoot, nil, nil, txn.txnID) validateTree(txn.root, nil, txn.watches, txn.txnID) } + txn.txnID++ t := Tree[T]{ opts: txn.opts, root: txn.root, rootWatch: newRootWatch, size: txn.size, prevTxn: txn.prevTxn, - prevTxnID: txn.txnID, + nextTxnID: txn.txnID, } // Store this txn in the tree to reuse the allocation next time. t.prevTxn.Store(txn)