package pfile import ( "testing" ) type IndexState struct { FreeList []uint64 AllocList map[[2]uint64][]uint64 } func (idx *Index) Assert(t *testing.T, state IndexState) { t.Helper() idx.fList.Assert(t, state.FreeList...) idx.aList.Assert(t, state.AllocList) } func TestIndex(t *testing.T) { pf, idx := newForTesting(t) defer pf.Close() idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{}, }) p0 := uint64(0) l := (&changeListBuilder{}). Store(1, 1, pageDataSize+1). Build() idx.StageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{}, }) // Unstage a change: free-list gets pages back. idx.UnstageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{p0, p0 + 1}, AllocList: map[[2]uint64][]uint64{}, }) // Stage a change: free-list entries are used again. l = (*changeListBuilder)(&l). Clear(). Store(1, 1, pageDataSize+1). Store(2, 2, pageDataSize-1). Store(3, 3, pageDataSize). Build() idx.StageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{}, }) // Apply changes: alloc-list is updated. idx.ApplyChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{ {1, 1}: {p0, p0 + 1}, {2, 2}: {p0 + 2}, {3, 3}: {p0 + 3}, }, }) // Clear some things. l = (*changeListBuilder)(&l). Clear(). Store(1, 1, pageDataSize). Delete(2, 2). Build() idx.StageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{ {3, 3}: {p0 + 3}, }, }) // Ustaging will push the staged page p0+4 into the free list. idx.UnstageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{p0 + 4}, AllocList: map[[2]uint64][]uint64{ {1, 1}: {p0, p0 + 1}, {2, 2}: {p0 + 2}, {3, 3}: {p0 + 3}, }, }) idx.StageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{}, AllocList: map[[2]uint64][]uint64{ {3, 3}: {p0 + 3}, }, }) idx.ApplyChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{p0, p0 + 1, p0 + 2}, AllocList: map[[2]uint64][]uint64{ {1, 1}: {p0 + 4}, {3, 3}: {p0 + 3}, }, }) // Duplicate updates. l = (*changeListBuilder)(&l). Clear(). Store(2, 2, pageDataSize). Store(3, 3, pageDataSize+1). Store(3, 3, pageDataSize). Build() idx.StageChanges(l) idx.Assert(t, IndexState{ FreeList: []uint64{p0 + 2}, AllocList: map[[2]uint64][]uint64{ {1, 1}: {p0 + 4}, }, }) }