OLD | NEW |
1 package gtreap | 1 package gtreap |
2 | 2 |
3 import ( | 3 import ( |
4 "bytes" | 4 "bytes" |
5 "testing" | 5 "testing" |
6 ) | 6 ) |
7 | 7 |
8 func stringCompare(a, b interface{}) int { | 8 func stringCompare(a, b interface{}) int { |
9 return bytes.Compare([]byte(a.(string)), []byte(b.(string))) | 9 return bytes.Compare([]byte(a.(string)), []byte(b.(string))) |
10 } | 10 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 func load(x *Treap, arr []string) *Treap { | 92 func load(x *Treap, arr []string) *Treap { |
93 for i, s := range arr { | 93 for i, s := range arr { |
94 x = x.Upsert(s, i) | 94 x = x.Upsert(s, i) |
95 } | 95 } |
96 return x | 96 return x |
97 } | 97 } |
98 | 98 |
99 func visitExpect(t *testing.T, x *Treap, start string, arr []string) { | 99 type treapVisitor func(x *Treap, pivot Item, visitor ItemVisitor) |
| 100 |
| 101 func visitExpect(t *testing.T, x *Treap, v treapVisitor, start string, arr []str
ing) { |
100 n := 0 | 102 n := 0 |
101 » x.VisitAscend(start, func(i Item) bool { | 103 » v(x, start, func(i Item) bool { |
102 if i.(string) != arr[n] { | 104 if i.(string) != arr[n] { |
103 t.Errorf("expected visit item: %v, saw: %v", arr[n], i) | 105 t.Errorf("expected visit item: %v, saw: %v", arr[n], i) |
104 } | 106 } |
105 n++ | 107 n++ |
106 return true | 108 return true |
107 }) | 109 }) |
108 if n != len(arr) { | 110 if n != len(arr) { |
109 t.Errorf("expected # visit callbacks: %v, saw: %v", len(arr), n) | 111 t.Errorf("expected # visit callbacks: %v, saw: %v", len(arr), n) |
| 112 panic(nil) |
110 } | 113 } |
111 } | 114 } |
112 | 115 |
113 func TestVisit(t *testing.T) { | 116 func testVisitImpl(t *testing.T, fn treapVisitor) { |
114 x := NewTreap(stringCompare) | 117 x := NewTreap(stringCompare) |
115 » visitExpect(t, x, "a", []string{}) | 118 » visitExpect(t, x, fn, "a", []string{}) |
116 | 119 |
117 x = load(x, []string{"e", "d", "c", "c", "a", "b", "a"}) | 120 x = load(x, []string{"e", "d", "c", "c", "a", "b", "a"}) |
118 | 121 |
119 visitX := func() { | 122 visitX := func() { |
120 » » visitExpect(t, x, "a", []string{"a", "b", "c", "d", "e"}) | 123 » » visitExpect(t, x, fn, "a", []string{"a", "b", "c", "d", "e"}) |
121 » » visitExpect(t, x, "a1", []string{"b", "c", "d", "e"}) | 124 » » visitExpect(t, x, fn, "a1", []string{"b", "c", "d", "e"}) |
122 » » visitExpect(t, x, "b", []string{"b", "c", "d", "e"}) | 125 » » visitExpect(t, x, fn, "b", []string{"b", "c", "d", "e"}) |
123 » » visitExpect(t, x, "b1", []string{"c", "d", "e"}) | 126 » » visitExpect(t, x, fn, "b1", []string{"c", "d", "e"}) |
124 » » visitExpect(t, x, "c", []string{"c", "d", "e"}) | 127 » » visitExpect(t, x, fn, "c", []string{"c", "d", "e"}) |
125 » » visitExpect(t, x, "c1", []string{"d", "e"}) | 128 » » visitExpect(t, x, fn, "c1", []string{"d", "e"}) |
126 » » visitExpect(t, x, "d", []string{"d", "e"}) | 129 » » visitExpect(t, x, fn, "d", []string{"d", "e"}) |
127 » » visitExpect(t, x, "d1", []string{"e"}) | 130 » » visitExpect(t, x, fn, "d1", []string{"e"}) |
128 » » visitExpect(t, x, "e", []string{"e"}) | 131 » » visitExpect(t, x, fn, "e", []string{"e"}) |
129 » » visitExpect(t, x, "f", []string{}) | 132 » » visitExpect(t, x, fn, "f", []string{}) |
130 } | 133 } |
131 visitX() | 134 visitX() |
132 | 135 |
133 var y *Treap | 136 var y *Treap |
134 y = x.Upsert("f", 1) | 137 y = x.Upsert("f", 1) |
135 y = y.Delete("a") | 138 y = y.Delete("a") |
136 y = y.Upsert("cc", 2) | 139 y = y.Upsert("cc", 2) |
137 y = y.Delete("c") | 140 y = y.Delete("c") |
138 | 141 |
139 » visitExpect(t, y, "a", []string{"b", "cc", "d", "e", "f"}) | 142 » visitExpect(t, y, fn, "a", []string{"b", "cc", "d", "e", "f"}) |
140 » visitExpect(t, y, "a1", []string{"b", "cc", "d", "e", "f"}) | 143 » visitExpect(t, y, fn, "a1", []string{"b", "cc", "d", "e", "f"}) |
141 » visitExpect(t, y, "b", []string{"b", "cc", "d", "e", "f"}) | 144 » visitExpect(t, y, fn, "b", []string{"b", "cc", "d", "e", "f"}) |
142 » visitExpect(t, y, "b1", []string{"cc", "d", "e", "f"}) | 145 » visitExpect(t, y, fn, "b1", []string{"cc", "d", "e", "f"}) |
143 » visitExpect(t, y, "c", []string{"cc", "d", "e", "f"}) | 146 » visitExpect(t, y, fn, "c", []string{"cc", "d", "e", "f"}) |
144 » visitExpect(t, y, "c1", []string{"cc", "d", "e", "f"}) | 147 » visitExpect(t, y, fn, "c1", []string{"cc", "d", "e", "f"}) |
145 » visitExpect(t, y, "d", []string{"d", "e", "f"}) | 148 » visitExpect(t, y, fn, "d", []string{"d", "e", "f"}) |
146 » visitExpect(t, y, "d1", []string{"e", "f"}) | 149 » visitExpect(t, y, fn, "d1", []string{"e", "f"}) |
147 » visitExpect(t, y, "e", []string{"e", "f"}) | 150 » visitExpect(t, y, fn, "e", []string{"e", "f"}) |
148 » visitExpect(t, y, "f", []string{"f"}) | 151 » visitExpect(t, y, fn, "f", []string{"f"}) |
149 » visitExpect(t, y, "z", []string{}) | 152 » visitExpect(t, y, fn, "z", []string{}) |
150 | 153 |
151 // an uninitialized treap | 154 // an uninitialized treap |
152 z := NewTreap(stringCompare) | 155 z := NewTreap(stringCompare) |
153 | 156 |
154 // a treap to force left traversal of min | 157 // a treap to force left traversal of min |
155 lmt := NewTreap(stringCompare) | 158 lmt := NewTreap(stringCompare) |
156 lmt = lmt.Upsert("b", 2) | 159 lmt = lmt.Upsert("b", 2) |
157 lmt = lmt.Upsert("a", 1) | 160 lmt = lmt.Upsert("a", 1) |
158 | 161 |
159 // The x treap should be unchanged. | 162 // The x treap should be unchanged. |
(...skipping 18 matching lines...) Expand all Loading... |
178 t.Error("expected max of nil") | 181 t.Error("expected max of nil") |
179 } | 182 } |
180 if lmt.Min() != "a" { | 183 if lmt.Min() != "a" { |
181 t.Errorf("expected min of a") | 184 t.Errorf("expected min of a") |
182 } | 185 } |
183 if lmt.Max() != "b" { | 186 if lmt.Max() != "b" { |
184 t.Errorf("expeced max of b") | 187 t.Errorf("expeced max of b") |
185 } | 188 } |
186 } | 189 } |
187 | 190 |
188 func visitExpectEndAtC(t *testing.T, x *Treap, start string, arr []string) { | 191 func TestVisit(t *testing.T) { |
| 192 » testVisitImpl(t, func(x *Treap, pivot Item, visitor ItemVisitor) { |
| 193 » » x.VisitAscend(pivot, visitor) |
| 194 » }) |
| 195 } |
| 196 |
| 197 func TestVisitIter(t *testing.T) { |
| 198 » testVisitImpl(t, func(x *Treap, pivot Item, visitor ItemVisitor) { |
| 199 » » it := x.Iterator(pivot) |
| 200 » » for { |
| 201 » » » i, ok := it.Next() |
| 202 » » » if !ok || !visitor(i) { |
| 203 » » » » return |
| 204 » » » } |
| 205 » » } |
| 206 » }) |
| 207 } |
| 208 |
| 209 func visitExpectEndAtC(t *testing.T, x *Treap, fn treapVisitor, start string, ar
r []string) { |
189 n := 0 | 210 n := 0 |
190 x.VisitAscend(start, func(i Item) bool { | 211 x.VisitAscend(start, func(i Item) bool { |
191 if stringCompare(i, "c") > 0 { | 212 if stringCompare(i, "c") > 0 { |
192 return false | 213 return false |
193 } | 214 } |
194 if i.(string) != arr[n] { | 215 if i.(string) != arr[n] { |
195 t.Errorf("expected visit item: %v, saw: %v", arr[n], i) | 216 t.Errorf("expected visit item: %v, saw: %v", arr[n], i) |
196 } | 217 } |
197 n++ | 218 n++ |
198 return true | 219 return true |
199 }) | 220 }) |
200 if n != len(arr) { | 221 if n != len(arr) { |
201 t.Errorf("expected # visit callbacks: %v, saw: %v", len(arr), n) | 222 t.Errorf("expected # visit callbacks: %v, saw: %v", len(arr), n) |
202 } | 223 } |
203 } | 224 } |
204 | 225 |
205 func TestVisitEndEarly(t *testing.T) { | 226 func testVisitEndEarlyImpl(t *testing.T, fn treapVisitor) { |
206 x := NewTreap(stringCompare) | 227 x := NewTreap(stringCompare) |
207 » visitExpectEndAtC(t, x, "a", []string{}) | 228 » visitExpectEndAtC(t, x, fn, "a", []string{}) |
208 | 229 |
209 x = load(x, []string{"e", "d", "c", "c", "a", "b", "a", "e"}) | 230 x = load(x, []string{"e", "d", "c", "c", "a", "b", "a", "e"}) |
210 | 231 |
211 visitX := func() { | 232 visitX := func() { |
212 » » visitExpectEndAtC(t, x, "a", []string{"a", "b", "c"}) | 233 » » visitExpectEndAtC(t, x, fn, "a", []string{"a", "b", "c"}) |
213 » » visitExpectEndAtC(t, x, "a1", []string{"b", "c"}) | 234 » » visitExpectEndAtC(t, x, fn, "a1", []string{"b", "c"}) |
214 » » visitExpectEndAtC(t, x, "b", []string{"b", "c"}) | 235 » » visitExpectEndAtC(t, x, fn, "b", []string{"b", "c"}) |
215 » » visitExpectEndAtC(t, x, "b1", []string{"c"}) | 236 » » visitExpectEndAtC(t, x, fn, "b1", []string{"c"}) |
216 » » visitExpectEndAtC(t, x, "c", []string{"c"}) | 237 » » visitExpectEndAtC(t, x, fn, "c", []string{"c"}) |
217 » » visitExpectEndAtC(t, x, "c1", []string{}) | 238 » » visitExpectEndAtC(t, x, fn, "c1", []string{}) |
218 » » visitExpectEndAtC(t, x, "d", []string{}) | 239 » » visitExpectEndAtC(t, x, fn, "d", []string{}) |
219 » » visitExpectEndAtC(t, x, "d1", []string{}) | 240 » » visitExpectEndAtC(t, x, fn, "d1", []string{}) |
220 » » visitExpectEndAtC(t, x, "e", []string{}) | 241 » » visitExpectEndAtC(t, x, fn, "e", []string{}) |
221 » » visitExpectEndAtC(t, x, "f", []string{}) | 242 » » visitExpectEndAtC(t, x, fn, "f", []string{}) |
222 } | 243 } |
223 visitX() | 244 visitX() |
224 } | 245 } |
225 | 246 |
| 247 func TestVisitEndEarly(t *testing.T) { |
| 248 testVisitEndEarlyImpl(t, func(x *Treap, pivot Item, visitor ItemVisitor)
{ |
| 249 x.VisitAscend(pivot, visitor) |
| 250 }) |
| 251 } |
| 252 |
| 253 func TestVisitEndEarlyIter(t *testing.T) { |
| 254 testVisitEndEarlyImpl(t, func(x *Treap, pivot Item, visitor ItemVisitor)
{ |
| 255 it := x.Iterator(pivot) |
| 256 for { |
| 257 i, ok := it.Next() |
| 258 if !ok || !visitor(i) { |
| 259 return |
| 260 } |
| 261 } |
| 262 }) |
| 263 } |
| 264 |
226 func TestPriorityAfterUpsert(t *testing.T) { | 265 func TestPriorityAfterUpsert(t *testing.T) { |
227 // See https://github.com/steveyen/gtreap/issues/3 found by icexin. | 266 // See https://github.com/steveyen/gtreap/issues/3 found by icexin. |
228 | 267 |
229 var check func(n *node, level int, expectedPriority map[string]int) | 268 var check func(n *node, level int, expectedPriority map[string]int) |
230 check = func(n *node, level int, expectedPriority map[string]int) { | 269 check = func(n *node, level int, expectedPriority map[string]int) { |
231 if n == nil { | 270 if n == nil { |
232 return | 271 return |
233 } | 272 } |
234 if n.priority != expectedPriority[n.item.(string)] { | 273 if n.priority != expectedPriority[n.item.(string)] { |
235 t.Errorf("wrong priority") | 274 t.Errorf("wrong priority") |
(...skipping 14 matching lines...) Expand all Loading... |
250 }) | 289 }) |
251 | 290 |
252 s = s.Upsert("m", 4) | 291 s = s.Upsert("m", 4) |
253 | 292 |
254 check(s.root, 0, map[string]int{ | 293 check(s.root, 0, map[string]int{ |
255 "m": 20, | 294 "m": 20, |
256 "l": 18, | 295 "l": 18, |
257 "n": 19, | 296 "n": 19, |
258 }) | 297 }) |
259 } | 298 } |
OLD | NEW |