Skip to content

Commit 00c8969

Browse files
committed
Decompose the interface
trying to decouple the interface a bit further, inversing the interface injection again. Signed-off-by: Thomas Jungblut <[email protected]>
1 parent 2e6b37b commit 00c8969

File tree

5 files changed

+70
-66
lines changed

5 files changed

+70
-66
lines changed

internal/freelist/array.go

+4-11
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@ import (
88
)
99

1010
type array struct {
11-
*shared
12-
1311
ids []common.Pgid // all free and available free page ids.
1412
}
1513

1614
func (f *array) Init(ids common.Pgids) {
1715
f.ids = ids
18-
f.reindex()
1916
}
2017

21-
func (f *array) Allocate(txid common.Txid, n int) common.Pgid {
18+
func (f *array) alloc(txid common.Txid, n int, allocs *map[common.Pgid]common.Txid, cache *map[common.Pgid]struct{}) common.Pgid {
2219
if len(f.ids) == 0 {
2320
return 0
2421
}
@@ -49,9 +46,9 @@ func (f *array) Allocate(txid common.Txid, n int) common.Pgid {
4946

5047
// Remove from the free cache.
5148
for i := common.Pgid(0); i < common.Pgid(n); i++ {
52-
delete(f.cache, initial+i)
49+
delete(*cache, initial+i)
5350
}
54-
f.allocs[initial] = txid
51+
(*allocs)[initial] = txid
5552
return initial
5653
}
5754

@@ -99,9 +96,5 @@ func (f *array) mergeSpans(ids common.Pgids) {
9996
}
10097

10198
func NewArrayFreelist() Interface {
102-
a := &array{
103-
shared: newShared(),
104-
}
105-
a.Interface = a
106-
return a
99+
return newShared(&array{})
107100
}

internal/freelist/freelist.go

+37-28
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,24 @@ type ReadWriter interface {
1616
EstimatedWritePageSize() int
1717
}
1818

19-
type Interface interface {
20-
ReadWriter
21-
19+
type allocator interface {
2220
// Init initializes this freelist with the given list of pages.
2321
Init(ids common.Pgids)
2422

25-
// Allocate tries to allocate the given number of contiguous pages
26-
// from the free list pages. It returns the starting page ID if
27-
// available; otherwise, it returns 0.
28-
Allocate(txid common.Txid, numPages int) common.Pgid
29-
30-
// Count returns the number of free and pending pages.
31-
Count() int
32-
3323
// FreeCount returns the number of free pages.
3424
FreeCount() int
3525

36-
// PendingCount returns the number of pending pages.
37-
PendingCount() int
26+
// freePageIds returns the IDs of all free pages.
27+
freePageIds() common.Pgids
3828

29+
// mergeSpans is merging the given pages into the freelist
30+
mergeSpans(ids common.Pgids)
31+
32+
// TODO(thomas): this is necessary to decouple, but leaks internals
33+
alloc(txid common.Txid, numPages int, allocs *map[common.Pgid]common.Txid, cache *map[common.Pgid]struct{}) common.Pgid
34+
}
35+
36+
type txManager interface {
3937
// AddReadonlyTXID adds a given read-only transaction id for pending page tracking.
4038
AddReadonlyTXID(txid common.Txid)
4139

@@ -45,6 +43,32 @@ type Interface interface {
4543
// ReleasePendingPages releases any pages associated with closed read-only transactions.
4644
ReleasePendingPages()
4745

46+
// pendingPageIds returns all pending pages by transaction id.
47+
pendingPageIds() map[common.Txid]*txPending
48+
49+
// release moves all page ids for a transaction id (or older) to the freelist.
50+
release(txId common.Txid)
51+
52+
// releaseRange moves pending pages allocated within an extent [begin,end] to the free list.
53+
releaseRange(begin, end common.Txid)
54+
}
55+
56+
type Interface interface {
57+
ReadWriter
58+
allocator
59+
txManager
60+
61+
// Allocate tries to allocate the given number of contiguous pages
62+
// from the free list pages. It returns the starting page ID if
63+
// available; otherwise, it returns 0.
64+
Allocate(txid common.Txid, numPages int) common.Pgid
65+
66+
// Count returns the number of free and pending pages.
67+
Count() int
68+
69+
// PendingCount returns the number of pending pages.
70+
PendingCount() int
71+
4872
// Free releases a page and its overflow for a given transaction id.
4973
// If the page is already free then a panic will occur.
5074
Free(txId common.Txid, p *common.Page)
@@ -64,19 +88,4 @@ type Interface interface {
6488

6589
// NoSyncReload reads the freelist from Pgids and filters out pending items.
6690
NoSyncReload(pgIds common.Pgids)
67-
68-
// freePageIds returns the IDs of all free pages.
69-
freePageIds() common.Pgids
70-
71-
// pendingPageIds returns all pending pages by transaction id.
72-
pendingPageIds() map[common.Txid]*txPending
73-
74-
// release moves all page ids for a transaction id (or older) to the freelist.
75-
release(txId common.Txid)
76-
77-
// releaseRange moves pending pages allocated within an extent [begin,end] to the free list.
78-
releaseRange(begin, end common.Txid)
79-
80-
// mergeSpans is merging the given pages into the freelist
81-
mergeSpans(ids common.Pgids)
8291
}

internal/freelist/hashmap.go

+11-14
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
type pidSet map[common.Pgid]struct{}
1313

1414
type hashMap struct {
15-
*shared
16-
1715
freePagesCount uint64 // count of free pages(hashmap version)
1816
freemaps map[uint64]pidSet // key is the size of continuous pages(span), value is a set which contains the starting pgids of same size
1917
forwardMap map[common.Pgid]uint64 // key is start pgid, value is its span size
@@ -54,11 +52,9 @@ func (f *hashMap) Init(pgids common.Pgids) {
5452
if size != 0 && start != 0 {
5553
f.addSpan(start, size)
5654
}
57-
58-
f.reindex()
5955
}
6056

61-
func (f *hashMap) Allocate(txid common.Txid, n int) common.Pgid {
57+
func (f *hashMap) alloc(txid common.Txid, n int, allocs *map[common.Pgid]common.Txid, cache *map[common.Pgid]struct{}) common.Pgid {
6258
if n == 0 {
6359
return 0
6460
}
@@ -69,10 +65,10 @@ func (f *hashMap) Allocate(txid common.Txid, n int) common.Pgid {
6965
// remove the span
7066
f.delSpan(pid, uint64(n))
7167

72-
f.allocs[pid] = txid
68+
(*allocs)[pid] = txid
7369

7470
for i := common.Pgid(0); i < common.Pgid(n); i++ {
75-
delete(f.cache, pid+i)
71+
delete(*cache, pid+i)
7672
}
7773
return pid
7874
}
@@ -88,15 +84,15 @@ func (f *hashMap) Allocate(txid common.Txid, n int) common.Pgid {
8884
// remove the initial
8985
f.delSpan(pid, size)
9086

91-
f.allocs[pid] = txid
87+
(*allocs)[pid] = txid
9288

9389
remain := size - uint64(n)
9490

9591
// add remain span
9692
f.addSpan(pid+common.Pgid(n), remain)
9793

9894
for i := common.Pgid(0); i < common.Pgid(n); i++ {
99-
delete(f.cache, pid+i)
95+
delete(*cache, pid+i)
10096
}
10197
return pid
10298
}
@@ -280,13 +276,14 @@ func (f *hashMap) idsFromBackwardMap() map[common.Pgid]struct{} {
280276
return ids
281277
}
282278

283-
func NewHashMapFreelist() Interface {
284-
hm := &hashMap{
285-
shared: newShared(),
279+
func newHashMap() *hashMap {
280+
return &hashMap{
286281
freemaps: make(map[uint64]pidSet),
287282
forwardMap: make(map[common.Pgid]uint64),
288283
backwardMap: make(map[common.Pgid]uint64),
289284
}
290-
hm.Interface = hm
291-
return hm
285+
}
286+
287+
func NewHashMapFreelist() Interface {
288+
return newShared(newHashMap())
292289
}

internal/freelist/hashmap_test.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func TestFreelistHashmap_mergeWithExist(t *testing.T) {
8686
},
8787
}
8888
for _, tt := range tests {
89-
f := newTestHashMapFreelist()
89+
f := newHashMap()
9090
f.Init(tt.ids)
9191

9292
f.mergeWithExistingSpan(tt.pgid)
@@ -107,7 +107,7 @@ func TestFreelistHashmap_mergeWithExist(t *testing.T) {
107107
}
108108

109109
func TestFreelistHashmap_GetFreePageIDs(t *testing.T) {
110-
f := newTestHashMapFreelist()
110+
f := newHashMap()
111111

112112
N := int32(100000)
113113
fm := make(map[common.Pgid]uint64)
@@ -129,7 +129,7 @@ func TestFreelistHashmap_GetFreePageIDs(t *testing.T) {
129129
}
130130

131131
func Benchmark_freelist_hashmapGetFreePageIDs(b *testing.B) {
132-
f := newTestHashMapFreelist()
132+
f := newHashMap()
133133
N := int32(100000)
134134
fm := make(map[common.Pgid]uint64)
135135
i := int32(0)
@@ -148,8 +148,3 @@ func Benchmark_freelist_hashmapGetFreePageIDs(b *testing.B) {
148148
f.freePageIds()
149149
}
150150
}
151-
152-
func newTestHashMapFreelist() *hashMap {
153-
f := NewHashMapFreelist()
154-
return f.(*hashMap)
155-
}

internal/freelist/shared.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,32 @@ type txPending struct {
1616
}
1717

1818
type shared struct {
19-
Interface
19+
allocator
2020

2121
readonlyTXIDs []common.Txid // all readonly transaction IDs.
2222
allocs map[common.Pgid]common.Txid // mapping of Txid that allocated a pgid.
2323
cache map[common.Pgid]struct{} // fast lookup of all free and pending page ids.
2424
pending map[common.Txid]*txPending // mapping of soon-to-be free page ids by tx.
2525
}
2626

27-
func newShared() *shared {
27+
func newShared(a allocator) Interface {
2828
return &shared{
29-
pending: make(map[common.Txid]*txPending),
30-
allocs: make(map[common.Pgid]common.Txid),
31-
cache: make(map[common.Pgid]struct{}),
29+
allocator: a,
30+
pending: make(map[common.Txid]*txPending),
31+
allocs: make(map[common.Pgid]common.Txid),
32+
cache: make(map[common.Pgid]struct{}),
3233
}
3334
}
3435

36+
func (t *shared) Init(ids common.Pgids) {
37+
t.allocator.Init(ids)
38+
t.reindex()
39+
}
40+
41+
func (t *shared) Allocate(txid common.Txid, n int) common.Pgid {
42+
return t.allocator.alloc(txid, n, &t.allocs, &t.cache)
43+
}
44+
3545
func (t *shared) pendingPageIds() map[common.Txid]*txPending {
3646
return t.pending
3747
}

0 commit comments

Comments
 (0)