Skip to content

Commit

Permalink
rollback alloc map: remove all page ids which are allocated by the txid
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Wang <[email protected]>
  • Loading branch information
ahrtr committed Aug 12, 2024
1 parent 9e2c06f commit 2928979
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
29 changes: 29 additions & 0 deletions internal/freelist/array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"reflect"
"testing"

"github.com/stretchr/testify/require"

"go.etcd.io/bbolt/internal/common"
)

Expand Down Expand Up @@ -50,3 +52,30 @@ func TestFreelistArray_allocate(t *testing.T) {
t.Fatalf("exp=%v; got=%v", exp, f.freePageIds())
}
}

func Test_Freelist_Array_Rollback(t *testing.T) {
f := newTestArrayFreelist()

f.Init([]common.Pgid{3, 5, 6, 7, 12, 13})

f.Free(100, common.NewPage(20, 0, 0, 1))
f.Allocate(100, 3)
f.Free(100, common.NewPage(25, 0, 0, 0))
f.Allocate(100, 2)

require.Equal(t, map[common.Pgid]common.Txid{5: 100, 12: 100}, f.allocs)
require.Equal(t, map[common.Txid]*txPending{100: &txPending{
ids: []common.Pgid{20, 21, 25},
alloctx: []common.Txid{0, 0, 0},
}}, f.pending)

f.Rollback(100)

require.Equal(t, map[common.Pgid]common.Txid{}, f.allocs)
require.Equal(t, map[common.Txid]*txPending{}, f.pending)
}

func newTestArrayFreelist() *array {
f := NewArrayFreelist()
return f.(*array)
}
23 changes: 23 additions & 0 deletions internal/freelist/hashmap_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package freelist

import (
"github.com/stretchr/testify/require"
"math/rand"
"reflect"
"sort"
Expand Down Expand Up @@ -128,6 +129,28 @@ func TestFreelistHashmap_GetFreePageIDs(t *testing.T) {
}
}

func Test_Freelist_Hashmap_Rollback(t *testing.T) {
f := newTestHashMapFreelist()

f.Init([]common.Pgid{3, 5, 6, 7, 12, 13})

f.Free(100, common.NewPage(20, 0, 0, 1))
f.Allocate(100, 3)
f.Free(100, common.NewPage(25, 0, 0, 0))
f.Allocate(100, 2)

require.Equal(t, map[common.Pgid]common.Txid{5: 100, 12: 100}, f.allocs)
require.Equal(t, map[common.Txid]*txPending{100: &txPending{
ids: []common.Pgid{20, 21, 25},
alloctx: []common.Txid{0, 0, 0},
}}, f.pending)

f.Rollback(100)

require.Equal(t, map[common.Pgid]common.Txid{}, f.allocs)
require.Equal(t, map[common.Txid]*txPending{}, f.pending)
}

func Benchmark_freelist_hashmapGetFreePageIDs(b *testing.B) {
f := newTestHashMapFreelist()
N := int32(100000)
Expand Down
7 changes: 7 additions & 0 deletions internal/freelist/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ func (t *shared) Rollback(txid common.Txid) {
}
// Remove pages from pending list and mark as free if allocated by txid.
delete(t.pending, txid)

// Remove pgids which are allocated by this txid
for pgid, tid := range t.allocs {
if tid == txid {
delete(t.allocs, pgid)
}
}
}

func (t *shared) AddReadonlyTXID(tid common.Txid) {
Expand Down

0 comments on commit 2928979

Please sign in to comment.