1243 lines
26 KiB
Go
1243 lines
26 KiB
Go
|
|
package treerack
|
||
|
|
|
||
|
|
import "testing"
|
||
|
|
|
||
|
|
func veq(a [][]int, b [][]int) bool {
|
||
|
|
if len(a) != len(b) {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := range a {
|
||
|
|
if len(a[i]) != len(b[i]) {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
for j := range a[i] {
|
||
|
|
if a[i][j] != b[i][j] {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestArena(t *testing.T) {
|
||
|
|
test := func(fixedPage bool) func(*testing.T) {
|
||
|
|
return func(t *testing.T) {
|
||
|
|
t.Run("len", func(t *testing.T) {
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
if a.len() != 0 {
|
||
|
|
t.Fatal(a.len())
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("length", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
if a.len() != 1<<6 {
|
||
|
|
t.Fatal(a.len())
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("length over multiple pages", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(84, 1, 2)
|
||
|
|
if a.len() != 1<<7 {
|
||
|
|
t.Fatal(a.len())
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("has", func(t *testing.T) {
|
||
|
|
t.Run("empty query", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
if !a.has(42) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("query too long", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
if a.has(42, 1, 2, 3) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("no values at index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(84, 1, 2)
|
||
|
|
if a.has(42, 1, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("query does not match single", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
if a.has(42, 1, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("query does not match multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
if a.has(42, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match single", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
if !a.has(42, 1, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
if !a.has(42, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.set(3, 1, 3)
|
||
|
|
a.del(3, 1, 2)
|
||
|
|
if !a.has(3, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
if a.has(3, 1, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("negative index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
if a.has(-3, 1, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("beyond available range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
if a.has(84, 1, 2) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("get", func(t *testing.T) {
|
||
|
|
t.Run("query too long", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
r := a.get(42, 1, 2, 3)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero query no items at index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(84, 1, 2)
|
||
|
|
a.set(84, 1, 3)
|
||
|
|
r := a.get(42)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero query one item", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero query multiple items", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 3}, {1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("query does not match single", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
r := a.get(42, 1, 1)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("query does not match multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
r := a.get(42, 1, 1)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match single", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
r := a.get(42, 1, 2)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
a.set(42, 1, 3)
|
||
|
|
r := a.get(42, 1)
|
||
|
|
if !veq(r, [][]int{{1, 3}, {1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.set(3, 1, 3)
|
||
|
|
a.del(3, 1, 2)
|
||
|
|
r := a.get(3, 1)
|
||
|
|
if !veq(r, [][]int{{1, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
r := a.get(3, 1, 2)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("negative index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
r := a.get(-3, 1, 2)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("beyond available range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
r := a.get(84, 1, 2)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("set", func(t *testing.T) {
|
||
|
|
t.Run("alloc from zero", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("alloc multiple from zero", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(84, 1, 2)
|
||
|
|
r := a.get(84)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("alloc", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(84, 1, 3)
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
r = a.get(84)
|
||
|
|
if !veq(r, [][]int{{1, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("same value", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("alloc multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(42, 1, 2)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(160, 1, 3)
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
r = a.get(160)
|
||
|
|
if !veq(r, [][]int{{1, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("do not split records", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(0, 1, 2)
|
||
|
|
r := a.get(0)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(1, 1, 3)
|
||
|
|
r = a.get(0)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
r = a.get(1)
|
||
|
|
if !veq(r, [][]int{{1, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(1, 1, 2)
|
||
|
|
a.set(1, 1, 3)
|
||
|
|
a.del(1, 1, 2)
|
||
|
|
a.set(1, 1, 4)
|
||
|
|
r := a.get(1)
|
||
|
|
if !veq(r, [][]int{{1, 4}, {1, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("negative index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(-3, 1, 2)
|
||
|
|
r := a.get(-3, 1, 2)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("del", func(t *testing.T) {
|
||
|
|
t.Run("query too long", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.del(42, 1, 2, 3, 4)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.del(42, 1, 2, 3)
|
||
|
|
r := a.get(42)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("empty at index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.del(84, 1, 2, 3)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("no match", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.del(42, 1, 2, 4)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2, 3}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match single", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.set(42, 1, 2, 4)
|
||
|
|
a.del(42, 1, 2, 3)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 2, 4}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match multiple", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.set(42, 1, 2, 4)
|
||
|
|
a.set(42, 2, 2, 4)
|
||
|
|
a.del(42, 1, 2)
|
||
|
|
r := a.get(42)
|
||
|
|
if !veq(r, [][]int{{2, 2, 4}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("match all", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(3, p, fixedPage)
|
||
|
|
a.set(42, 1, 2, 3)
|
||
|
|
a.set(42, 1, 2, 4)
|
||
|
|
a.set(42, 2, 2, 4)
|
||
|
|
a.del(42)
|
||
|
|
r := a.get(42)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("trim start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 1)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.set(3, 2, 1)
|
||
|
|
if len(a.a) != 3 {
|
||
|
|
t.Fatal(a.a)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3, 1, 1)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{2, 1}, {1, 2}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(a.a) != 2 {
|
||
|
|
t.Fatal(len(a.a))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("trim end", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 1)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.set(3, 2, 1)
|
||
|
|
if len(a.a) != 3 {
|
||
|
|
t.Fatal(a.a)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3, 2, 1)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{1, 2}, {1, 1}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(a.a) != 2 {
|
||
|
|
t.Fatal(len(a.a))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("trim start and end", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 1)
|
||
|
|
a.set(3, 2, 1)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
if len(a.a) != 3 {
|
||
|
|
t.Fatal(a.a)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3, 1)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{2, 1}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(a.a) != 1 {
|
||
|
|
t.Fatal(len(a.a))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("trim all", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 1)
|
||
|
|
a.set(3, 2, 1)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
if len(a.a) != 3 {
|
||
|
|
t.Fatal(a.a)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3)
|
||
|
|
r := a.get(3)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(a.a) != 0 {
|
||
|
|
t.Fatal(len(a.a))
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 4) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 1)
|
||
|
|
a.set(3, 2, 1)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.del(3, 1, 1)
|
||
|
|
a.del(3, 1, 2)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{2, 1}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.del(3, 1, 2)
|
||
|
|
r := a.get(3, 1, 2)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("negative index", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.del(-3, 1, 2)
|
||
|
|
r := a.get(3, 1, 2)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("beyond available range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.set(3, 1, 2)
|
||
|
|
a.del(84, 1, 2)
|
||
|
|
r := a.get(3)
|
||
|
|
if !veq(r, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("prune", func(t *testing.T) {
|
||
|
|
t.Run("empty", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
a.prune(3, 72)
|
||
|
|
if a.o != 0 || a.l != 0 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
r := a.get(3)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(3, 3)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero range below available", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(-3, -3)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("zero range above available", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(a.len()+3, a.len()+3)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("invalid range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(3, -3)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 9)
|
||
|
|
if a.o != 8 || a.l != 16 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 9; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 9; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("start from negative range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(-3, 9)
|
||
|
|
if a.o != 8 || a.l != 16 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 9; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 9; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("end", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(3, a.len())
|
||
|
|
if a.o != 0 || a.l != 8 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 3; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 3; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("end without dropping a page", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(9, a.len())
|
||
|
|
if a.o != 0 || a.l != 16 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 9; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 9; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("end to out of range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(3, a.len()+3)
|
||
|
|
if a.o != 0 || a.l != 8 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 3; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 3; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("middle", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 12; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(3, 9)
|
||
|
|
if a.o != 0 || a.l != 16 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 3; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 3; i < 9; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 9; i < 12; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("multiple pages from start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 36)
|
||
|
|
if a.o != 32 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 36; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 36; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("end", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(36, a.len())
|
||
|
|
if a.o != 0 || a.l != 40 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 36; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 36; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("middle", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(36, 54)
|
||
|
|
if a.o != 0 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 36; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 36; i < 54; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 54; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("again", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 36)
|
||
|
|
a.prune(9, 42)
|
||
|
|
if a.o != 40 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 42; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 42; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("again within pruned range", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 36)
|
||
|
|
a.prune(9, 27)
|
||
|
|
if a.o != 32 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 36; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 36; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 1 || len(r[0]) != 2 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("ops after pruned start", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 36)
|
||
|
|
if a.len() != 88 {
|
||
|
|
t.Fatal(a.len())
|
||
|
|
}
|
||
|
|
|
||
|
|
if a.has(18, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
|
||
|
|
if !a.has(42, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
|
||
|
|
r := a.get(18)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 42}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(18, 1, 18)
|
||
|
|
r = a.get(18)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(42, 1, 24)
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 24}, {1, 42}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(18, 1, 18)
|
||
|
|
r = a.get(18)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(42, 1)
|
||
|
|
r = a.get(42)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("ops after pruned end", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(54, a.len())
|
||
|
|
if a.len() != 56 {
|
||
|
|
t.Fatal(a.len())
|
||
|
|
}
|
||
|
|
|
||
|
|
if a.has(72, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
|
||
|
|
if !a.has(42, 1) {
|
||
|
|
t.Fatal()
|
||
|
|
}
|
||
|
|
|
||
|
|
r := a.get(72)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 42}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(72, 1, 72)
|
||
|
|
r = a.get(72)
|
||
|
|
if !veq(r, [][]int{{1, 72}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(42, 1, 24)
|
||
|
|
r = a.get(42)
|
||
|
|
if !veq(r, [][]int{{1, 24}, {1, 42}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(72, 1, 72)
|
||
|
|
r = a.get(72)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(42, 1)
|
||
|
|
r = a.get(42)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start within trimmed", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 54; i++ {
|
||
|
|
a.del(i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 36)
|
||
|
|
if a.o != 32 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 54; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 54; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if !veq(r, [][]int{{1, i}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("after trim start beyond trimmed", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 8) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
for i := 0; i < 84; i++ {
|
||
|
|
a.set(i, 1, i)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 36; i++ {
|
||
|
|
a.del(i)
|
||
|
|
}
|
||
|
|
|
||
|
|
a.prune(0, 54)
|
||
|
|
if a.o != 48 || a.l != 88 {
|
||
|
|
t.Fatal(a.o, a.l)
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 0; i < 54; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if len(r) != 0 {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for i := 54; i < 84; i++ {
|
||
|
|
r := a.get(i)
|
||
|
|
if !veq(r, [][]int{{1, i}}) {
|
||
|
|
t.Fatal(r)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("example", func(t *testing.T) {
|
||
|
|
p := newPool(func() []int { return make([]int, 1<<6) })
|
||
|
|
a := newArena(2, p, fixedPage)
|
||
|
|
v := a.get(42)
|
||
|
|
if len(v) != 0 {
|
||
|
|
t.Fatal("unexpected values")
|
||
|
|
}
|
||
|
|
|
||
|
|
if a.has(3, 1, 2) {
|
||
|
|
t.Fatal("unexpected values")
|
||
|
|
}
|
||
|
|
|
||
|
|
a.set(3, 1, 2, 3)
|
||
|
|
v = a.get(3)
|
||
|
|
if !veq(v, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(v)
|
||
|
|
}
|
||
|
|
|
||
|
|
if !a.has(3, 1, 2) {
|
||
|
|
t.Fatal("values not found")
|
||
|
|
}
|
||
|
|
|
||
|
|
v = a.get(3, 1)
|
||
|
|
if !veq(v, [][]int{{1, 2}}) {
|
||
|
|
t.Fatal(v)
|
||
|
|
}
|
||
|
|
|
||
|
|
if !a.has(3, 1) {
|
||
|
|
t.Fatal("values not found")
|
||
|
|
}
|
||
|
|
|
||
|
|
v = a.get(3, 1, 3)
|
||
|
|
if !veq(v, nil) {
|
||
|
|
t.Fatal(v)
|
||
|
|
}
|
||
|
|
|
||
|
|
if a.has(3, 1, 3) {
|
||
|
|
t.Fatal("unexpected values")
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3, 2)
|
||
|
|
if !a.has(3, 1) {
|
||
|
|
t.Fatal("values not found")
|
||
|
|
}
|
||
|
|
|
||
|
|
a.del(3, 1, 2)
|
||
|
|
if a.has(3, 1, 2) {
|
||
|
|
t.Fatal("unexpected values")
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Run("fixed page", test(true))
|
||
|
|
t.Run("variable page", test(false))
|
||
|
|
}
|