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) { t.Skip() 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)) } */