140 lines
2.5 KiB
Go
140 lines
2.5 KiB
Go
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},
|
|
},
|
|
})
|
|
}
|