From 5a23c84907c969ec7f1b9512026794c4ec5e353e Mon Sep 17 00:00:00 2001 From: Alexey Feldgendler Date: Fri, 13 Sep 2019 21:14:00 +0300 Subject: [PATCH 1/2] Added Clone method to Txn to create an independent copy of a transaction --- iradix.go | 14 ++++++++++++++ iradix_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/iradix.go b/iradix.go index e5e6e57..156a9e9 100644 --- a/iradix.go +++ b/iradix.go @@ -86,6 +86,20 @@ func (t *Tree) Txn() *Txn { return txn } +// Clone makes an independent copy of the transaction. The new transaction +// does not track any nodes and has TrackMutate turned off. +func (t *Txn) Clone() *Txn { + // reset the writable node cache to avoid leaking future writes into the clone + t.writable = nil + + txn := &Txn{ + root: t.root, + snap: t.snap, + size: t.size, + } + return txn +} + // TrackMutate can be used to toggle if mutations are tracked. If this is enabled // then notifications will be issued for affected internal nodes and leaves when // the transaction is committed. diff --git a/iradix_test.go b/iradix_test.go index cd0b1c6..6311f5e 100644 --- a/iradix_test.go +++ b/iradix_test.go @@ -1774,3 +1774,33 @@ func TestIterateLowerBoundFuzz(t *testing.T) { t.Error(err) } } + +func TestClone(t *testing.T) { + r := New() + + t1 := r.Txn() + t1.Insert([]byte("foo"), 7) + t2 := t1.Clone() + + t1.Insert([]byte("bar"), 42) + t2.Insert([]byte("baz"), 43) + + if val, ok := t1.Get([]byte("foo")); !ok || val != 7 { + t.Fatalf("bad foo in t1") + } + if val, ok := t2.Get([]byte("foo")); !ok || val != 7 { + t.Fatalf("bad foo in t2") + } + if val, ok := t1.Get([]byte("bar")); !ok || val != 42 { + t.Fatalf("bad bar in t1") + } + if _, ok := t2.Get([]byte("bar")); ok { + t.Fatalf("bar found in t2") + } + if _, ok := t1.Get([]byte("baz")); ok { + t.Fatalf("baz found in t1") + } + if val, ok := t2.Get([]byte("baz")); !ok || val != 43 { + t.Fatalf("bad baz in t2") + } +} From 56f5bef4b39cac512418ffbb2352d8ea69fbc343 Mon Sep 17 00:00:00 2001 From: Alexey Feldgendler Date: Wed, 18 Mar 2020 18:22:38 +0100 Subject: [PATCH 2/2] Improved doc comment for Txn.Clone Co-Authored-By: Paul Banks --- iradix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iradix.go b/iradix.go index 156a9e9..168bda7 100644 --- a/iradix.go +++ b/iradix.go @@ -87,7 +87,7 @@ func (t *Tree) Txn() *Txn { } // Clone makes an independent copy of the transaction. The new transaction -// does not track any nodes and has TrackMutate turned off. +// does not track any nodes and has TrackMutate turned off. The cloned transaction will contain any uncommitted writes in the original transaction but further mutations to either will be independent and result in different radix trees on Commit. A cloned transaction may be passed to another goroutine and mutated there independently however each transaction may only be mutated in a single thread. func (t *Txn) Clone() *Txn { // reset the writable node cache to avoid leaking future writes into the clone t.writable = nil