github.com/sunvim/utils@v0.1.0/patricia/patricia_sparse_test.go (about) 1 // Copyright (c) 2014 The go-patricia AUTHORS 2 // 3 // Use of this source code is governed by The MIT License 4 // that can be found in the LICENSE file. 5 6 package patricia 7 8 import ( 9 "bytes" 10 "errors" 11 "fmt" 12 "strings" 13 "testing" 14 ) 15 16 const ( 17 success = true 18 failure = false 19 ) 20 21 type testData struct { 22 key string 23 value interface{} 24 retVal bool 25 } 26 27 // Tests ----------------------------------------------------------------------- 28 29 func TestTrie_InsertDifferentPrefixes(t *testing.T) { 30 trie := NewTrie() 31 32 data := []testData{ 33 {"Pepaneeeeeeeeeeeeee", "Pepan Zdepan", success}, 34 {"Honzooooooooooooooo", "Honza Novak", success}, 35 {"Jenikuuuuuuuuuuuuuu", "Jenik Poustevnicek", success}, 36 } 37 38 for _, v := range data { 39 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 40 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 41 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 42 } 43 } 44 } 45 46 func TestTrie_InsertDuplicatePrefixes(t *testing.T) { 47 trie := NewTrie() 48 49 data := []testData{ 50 {"Pepan", "Pepan Zdepan", success}, 51 {"Pepan", "Pepan Zdepan", failure}, 52 } 53 54 for _, v := range data { 55 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 56 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 57 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 58 } 59 } 60 } 61 62 func TestTrie_InsertVariousPrefixes(t *testing.T) { 63 trie := NewTrie() 64 65 data := []testData{ 66 {"Pepan", "Pepan Zdepan", success}, 67 {"Pepin", "Pepin Omacka", success}, 68 {"Honza", "Honza Novak", success}, 69 {"Jenik", "Jenik Poustevnicek", success}, 70 {"Pepan", "Pepan Dupan", failure}, 71 {"Karel", "Karel Pekar", success}, 72 {"Jenik", "Jenik Poustevnicek", failure}, 73 {"Pepanek", "Pepanek Zemlicka", success}, 74 } 75 76 for _, v := range data { 77 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 78 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 79 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 80 } 81 } 82 } 83 84 func TestTrie_InsertAndMatchPrefix(t *testing.T) { 85 trie := NewTrie() 86 t.Log("INSERT prefix=by week") 87 trie.Insert(Prefix("by week"), 2) 88 t.Log("INSERT prefix=by") 89 trie.Insert(Prefix("by"), 1) 90 91 if !trie.Match(Prefix("by")) { 92 t.Error("MATCH prefix=by, expected=true, got=false") 93 } 94 } 95 96 func TestTrie_SetGet(t *testing.T) { 97 trie := NewTrie() 98 99 data := []testData{ 100 {"Pepan", "Pepan Zdepan", success}, 101 {"Pepin", "Pepin Omacka", success}, 102 {"Honza", "Honza Novak", success}, 103 {"Jenik", "Jenik Poustevnicek", success}, 104 {"Pepan", "Pepan Dupan", failure}, 105 {"Karel", "Karel Pekar", success}, 106 {"Jenik", "Jenik Poustevnicek", failure}, 107 {"Pepanek", "Pepanek Zemlicka", success}, 108 } 109 110 for _, v := range data { 111 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 112 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 113 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 114 } 115 } 116 117 for _, v := range data { 118 t.Logf("SET %q to 10", v.key) 119 trie.Set(Prefix(v.key), 10) 120 } 121 122 for _, v := range data { 123 value := trie.Get(Prefix(v.key)) 124 t.Logf("GET %q => %v", v.key, value) 125 if value.(int) != 10 { 126 t.Errorf("Unexpected return value, %v != 10", value) 127 } 128 } 129 130 if value := trie.Get(Prefix("random crap")); value != nil { 131 t.Errorf("Unexpected return value, %v != <nil>", value) 132 } 133 } 134 135 func TestTrie_Match(t *testing.T) { 136 trie := NewTrie() 137 138 data := []testData{ 139 {"Pepan", "Pepan Zdepan", success}, 140 {"Pepin", "Pepin Omacka", success}, 141 {"Honza", "Honza Novak", success}, 142 {"Jenik", "Jenik Poustevnicek", success}, 143 {"Pepan", "Pepan Dupan", failure}, 144 {"Karel", "Karel Pekar", success}, 145 {"Jenik", "Jenik Poustevnicek", failure}, 146 {"Pepanek", "Pepanek Zemlicka", success}, 147 } 148 149 for _, v := range data { 150 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 151 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 152 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 153 } 154 } 155 156 for _, v := range data { 157 matched := trie.Match(Prefix(v.key)) 158 t.Logf("MATCH %q => %v", v.key, matched) 159 if !matched { 160 t.Errorf("Inserted key %q was not matched", v.key) 161 } 162 } 163 164 if trie.Match(Prefix("random crap")) { 165 t.Errorf("Key that was not inserted matched: %q", "random crap") 166 } 167 } 168 169 func TestTrie_MatchFalsePositive(t *testing.T) { 170 trie := NewTrie() 171 172 if ok := trie.Insert(Prefix("A"), 1); !ok { 173 t.Fatal("INSERT prefix=A, item=1 not ok") 174 } 175 176 resultMatchSubtree := trie.MatchSubtree(Prefix("A extra")) 177 resultMatch := trie.Match(Prefix("A extra")) 178 179 if resultMatchSubtree != false { 180 t.Error("MatchSubtree returned false positive") 181 } 182 183 if resultMatch != false { 184 t.Error("Match returned false positive") 185 } 186 } 187 188 func TestTrie_MatchSubtree(t *testing.T) { 189 trie := NewTrie() 190 191 data := []testData{ 192 {"Pepan", "Pepan Zdepan", success}, 193 {"Pepin", "Pepin Omacka", success}, 194 {"Honza", "Honza Novak", success}, 195 {"Jenik", "Jenik Poustevnicek", success}, 196 {"Pepan", "Pepan Dupan", failure}, 197 {"Karel", "Karel Pekar", success}, 198 {"Jenik", "Jenik Poustevnicek", failure}, 199 {"Pepanek", "Pepanek Zemlicka", success}, 200 } 201 202 for _, v := range data { 203 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 204 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 205 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 206 } 207 } 208 209 for _, v := range data { 210 key := Prefix(v.key[:3]) 211 matched := trie.MatchSubtree(key) 212 t.Logf("MATCH_SUBTREE %q => %v", key, matched) 213 if !matched { 214 t.Errorf("Subtree %q was not matched", v.key) 215 } 216 } 217 } 218 219 func TestTrie_Visit(t *testing.T) { 220 trie := NewTrie() 221 222 data := []testData{ 223 {"Pepa", 0, success}, 224 {"Pepa Zdepa", 1, success}, 225 {"Pepa Kuchar", 2, success}, 226 {"Honza", 3, success}, 227 {"Jenik", 4, success}, 228 } 229 230 for _, v := range data { 231 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 232 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 233 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 234 } 235 } 236 237 if err := trie.Visit(func(prefix Prefix, item Item) error { 238 name := data[item.(int)].key 239 t.Logf("VISITING prefix=%q, item=%v", prefix, item) 240 if !strings.HasPrefix(string(prefix), name) { 241 t.Errorf("Unexpected prefix encountered, %q not a prefix of %q", prefix, name) 242 } 243 return nil 244 }); err != nil { 245 t.Fatal(err) 246 } 247 } 248 249 func TestTrie_VisitSkipSubtree(t *testing.T) { 250 trie := NewTrie() 251 252 data := []testData{ 253 {"Pepa", 0, success}, 254 {"Pepa Zdepa", 1, success}, 255 {"Pepa Kuchar", 2, success}, 256 {"Honza", 3, success}, 257 {"Jenik", 4, success}, 258 } 259 260 for _, v := range data { 261 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 262 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 263 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 264 } 265 } 266 267 if err := trie.Visit(func(prefix Prefix, item Item) error { 268 t.Logf("VISITING prefix=%q, item=%v", prefix, item) 269 if item.(int) == 0 { 270 t.Logf("SKIP %q", prefix) 271 return SkipSubtree 272 } 273 if strings.HasPrefix(string(prefix), "Pepa") { 274 t.Errorf("Unexpected prefix encountered, %q", prefix) 275 } 276 return nil 277 }); err != nil { 278 t.Fatal(err) 279 } 280 } 281 282 func TestTrie_VisitReturnError(t *testing.T) { 283 trie := NewTrie() 284 285 data := []testData{ 286 {"Pepa", 0, success}, 287 {"Pepa Zdepa", 1, success}, 288 {"Pepa Kuchar", 2, success}, 289 {"Honza", 3, success}, 290 {"Jenik", 4, success}, 291 } 292 293 for _, v := range data { 294 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 295 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 296 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 297 } 298 } 299 300 someErr := errors.New("Something exploded") 301 if err := trie.Visit(func(prefix Prefix, item Item) error { 302 t.Logf("VISITING prefix=%q, item=%v", prefix, item) 303 if item.(int) == 3 { 304 return someErr 305 } 306 if item.(int) != 3 { 307 t.Errorf("Unexpected prefix encountered, %q", prefix) 308 } 309 return nil 310 }); err != nil && err != someErr { 311 t.Fatal(err) 312 } 313 } 314 315 func TestTrie_VisitSubtree(t *testing.T) { 316 trie := NewTrie() 317 318 data := []testData{ 319 {"Pepa", 0, success}, 320 {"Pepa Zdepa", 1, success}, 321 {"Pepa Kuchar", 2, success}, 322 {"Honza", 3, success}, 323 {"Jenik", 4, success}, 324 } 325 326 for _, v := range data { 327 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 328 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 329 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 330 } 331 } 332 333 var counter int 334 subtreePrefix := []byte("Pep") 335 t.Log("VISIT Pep") 336 if err := trie.VisitSubtree(subtreePrefix, func(prefix Prefix, item Item) error { 337 t.Logf("VISITING prefix=%q, item=%v", prefix, item) 338 if !bytes.HasPrefix(prefix, subtreePrefix) { 339 t.Errorf("Unexpected prefix encountered, %q does not extend %q", 340 prefix, subtreePrefix) 341 } 342 if len(prefix) > len(data[item.(int)].key) { 343 t.Fatalf("Something is rather fishy here, prefix=%q", prefix) 344 } 345 counter++ 346 return nil 347 }); err != nil { 348 t.Fatal(err) 349 } 350 351 if counter != 3 { 352 t.Error("Unexpected number of nodes visited") 353 } 354 } 355 356 func TestTrie_VisitPrefixes(t *testing.T) { 357 trie := NewTrie() 358 359 data := []testData{ 360 {"P", 0, success}, 361 {"Pe", 1, success}, 362 {"Pep", 2, success}, 363 {"Pepa", 3, success}, 364 {"Pepa Zdepa", 4, success}, 365 {"Pepa Kuchar", 5, success}, 366 {"Honza", 6, success}, 367 {"Jenik", 7, success}, 368 } 369 370 for _, v := range data { 371 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 372 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 373 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 374 } 375 } 376 377 var counter int 378 word := []byte("Pepa") 379 if err := trie.VisitPrefixes(word, func(prefix Prefix, item Item) error { 380 t.Logf("VISITING prefix=%q, item=%v", prefix, item) 381 if !bytes.HasPrefix(word, prefix) { 382 t.Errorf("Unexpected prefix encountered, %q is not a prefix of %q", 383 prefix, word) 384 } 385 counter++ 386 return nil 387 }); err != nil { 388 t.Fatal(err) 389 } 390 391 if counter != 4 { 392 t.Error("Unexpected number of nodes visited") 393 } 394 } 395 396 func TestPatriciaTrie_CloneSparse(t *testing.T) { 397 trie := NewTrie() 398 399 data := []testData{ 400 {"Pepaneeeeeeeeeeeeee", "Pepan Zdepan", success}, 401 {"Honzooooooooooooooo", "Honza Novak", success}, 402 {"Jenikuuuuuuuuuuuuuu", "Jenik Poustevnicek", success}, 403 } 404 405 for _, v := range data { 406 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 407 if ok := trie.Insert(Prefix(v.key), v.value); ok != v.retVal { 408 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 409 } 410 } 411 412 t.Log("CLONE") 413 clone := trie.Clone() 414 415 for _, v := range data { 416 t.Logf("GET prefix=%v, item=%v", v.key, v.value) 417 if item := clone.Get(Prefix(v.key)); item != v.value { 418 t.Errorf("Unexpected return value, expected=%v, got=%v", v.value, item) 419 } 420 } 421 422 prefix := "xxx" 423 item := 666 424 t.Logf("INSERT prefix=%v, item=%v", prefix, item) 425 if ok := trie.Insert(Prefix(prefix), item); !ok { 426 t.Errorf("Unexpected return value, expected=true, got=%v", ok) 427 } 428 t.Logf("GET cloned prefix=%v", prefix) 429 if item := clone.Get(Prefix(prefix)); item != nil { 430 t.Errorf("Unexpected return value, expected=nil, got=%v", item) 431 } 432 } 433 434 func TestParticiaTrie_Delete(t *testing.T) { 435 trie := NewTrie() 436 437 data := []testData{ 438 {"Pepan", "Pepan Zdepan", success}, 439 {"Honza", "Honza Novak", success}, 440 {"Jenik", "Jenik Poustevnicek", success}, 441 } 442 443 for _, v := range data { 444 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 445 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 446 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 447 } 448 } 449 450 for _, v := range data { 451 t.Logf("DELETE word=%v, success=%v", v.key, v.retVal) 452 if ok := trie.Delete([]byte(v.key)); ok != v.retVal { 453 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 454 } 455 } 456 } 457 458 func TestParticiaTrie_DeleteLeakageSparse(t *testing.T) { 459 trie := NewTrie() 460 461 data := []testData{ 462 {"Pepan", "Pepan Zdepan", success}, 463 {"Honza", "Honza Novak", success}, 464 {"Jenik", "Jenik Poustevnicek", success}, 465 } 466 467 oldBytes := heapAllocatedBytes() 468 469 for i := 0; i < 10000; i++ { 470 for _, v := range data { 471 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 472 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 473 } 474 } 475 476 for _, v := range data { 477 if ok := trie.Delete([]byte(v.key)); ok != v.retVal { 478 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 479 } 480 } 481 } 482 483 if newBytes := heapAllocatedBytes(); newBytes > oldBytes+overhead { 484 t.Logf("Size=%d, Total=%d, Trie state:\n%s\n", trie.size(), trie.total(), trie.dump()) 485 t.Errorf("Heap space leak, grew %d bytes (from %d to %d)\n", newBytes-oldBytes, oldBytes, newBytes) 486 } 487 } 488 489 func TestParticiaTrie_DeleteNonExistent(t *testing.T) { 490 trie := NewTrie() 491 492 insertData := []testData{ 493 {"Pepan", "Pepan Zdepan", success}, 494 {"Honza", "Honza Novak", success}, 495 {"Jenik", "Jenik Poustevnicek", success}, 496 } 497 deleteData := []testData{ 498 {"Pepan", "Pepan Zdepan", success}, 499 {"Honza", "Honza Novak", success}, 500 {"Pepan", "Pepan Zdepan", failure}, 501 {"Jenik", "Jenik Poustevnicek", success}, 502 {"Honza", "Honza Novak", failure}, 503 } 504 505 for _, v := range insertData { 506 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 507 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 508 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 509 } 510 } 511 512 for _, v := range deleteData { 513 t.Logf("DELETE word=%v, success=%v", v.key, v.retVal) 514 if ok := trie.Delete([]byte(v.key)); ok != v.retVal { 515 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 516 } 517 } 518 } 519 520 func TestParticiaTrie_DeleteSubtree(t *testing.T) { 521 trie := NewTrie() 522 523 insertData := []testData{ 524 {"P", 0, success}, 525 {"Pe", 1, success}, 526 {"Pep", 2, success}, 527 {"Pepa", 3, success}, 528 {"Pepa Zdepa", 4, success}, 529 {"Pepa Kuchar", 5, success}, 530 {"Honza", 6, success}, 531 {"Jenik", 7, success}, 532 } 533 deleteData := []testData{ 534 {"Pe", -1, success}, 535 {"Pe", -1, failure}, 536 {"Honzik", -1, failure}, 537 {"Honza", -1, success}, 538 {"Honza", -1, failure}, 539 {"Pep", -1, failure}, 540 {"P", -1, success}, 541 {"Nobody", -1, failure}, 542 {"", -1, success}, 543 } 544 545 for _, v := range insertData { 546 t.Logf("INSERT prefix=%v, item=%v, success=%v", v.key, v.value, v.retVal) 547 if ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 548 t.Fatalf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 549 } 550 } 551 552 for _, v := range deleteData { 553 t.Logf("DELETE_SUBTREE prefix=%v, success=%v", v.key, v.retVal) 554 if ok := trie.DeleteSubtree([]byte(v.key)); ok != v.retVal { 555 t.Errorf("Unexpected return value, expected=%v, got=%v", v.retVal, ok) 556 } 557 } 558 } 559 560 /* 561 func TestTrie_Dump(t *testing.T) { 562 trie := NewTrie() 563 564 data := []testData{ 565 {"Honda", nil, success}, 566 {"Honza", nil, success}, 567 {"Jenik", nil, success}, 568 {"Pepan", nil, success}, 569 {"Pepin", nil, success}, 570 } 571 572 for i, v := range data { 573 if _, ok := trie.Insert([]byte(v.key), v.value); ok != v.retVal { 574 t.Logf("INSERT %v %v", v.key, v.value) 575 t.Fatalf("Unexpected return value, expected=%v, got=%v", i, ok) 576 } 577 } 578 579 dump := ` 580 +--+--+ Hon +--+--+ da 581 | | 582 | +--+ za 583 | 584 +--+ Jenik 585 | 586 +--+ Pep +--+--+ an 587 | 588 +--+ in 589 ` 590 591 var buf bytes.Buffer 592 trie.Dump(buf) 593 594 if !bytes.Equal(buf.Bytes(), dump) { 595 t.Logf("DUMP") 596 t.Fatalf("Unexpected dump generated, expected\n\n%v\ngot\n\n%v", dump, buf.String()) 597 } 598 } 599 */ 600 601 func TestTrie_compact(t *testing.T) { 602 trie := NewTrie() 603 604 trie.Insert(Prefix("a"), 0) 605 trie.Insert(Prefix("ab"), 0) 606 trie.Insert(Prefix("abc"), 0) 607 trie.Insert(Prefix("abcd"), 0) 608 trie.Insert(Prefix("abcde"), 0) 609 trie.Insert(Prefix("abcdef"), 0) 610 trie.Insert(Prefix("abcdefg"), 0) 611 trie.Insert(Prefix("abcdefgi"), 0) 612 trie.Insert(Prefix("abcdefgij"), 0) 613 trie.Insert(Prefix("abcdefgijk"), 0) 614 615 trie.Delete(Prefix("abcdef")) 616 trie.Delete(Prefix("abcde")) 617 trie.Delete(Prefix("abcdefg")) 618 619 trie.Delete(Prefix("a")) 620 trie.Delete(Prefix("abc")) 621 trie.Delete(Prefix("ab")) 622 623 trie.Visit(func(prefix Prefix, item Item) error { 624 // 97 ~~ 'a', 625 for ch := byte(97); ch <= 107; ch++ { 626 if c := bytes.Count(prefix, []byte{ch}); c > 1 { 627 t.Errorf("%q appeared in %q %v times", ch, prefix, c) 628 } 629 } 630 return nil 631 }) 632 } 633 634 func TestTrie_longestCommonPrefixLenght(t *testing.T) { 635 trie := NewTrie() 636 trie.prefix = []byte("1234567890") 637 638 switch { 639 case trie.longestCommonPrefixLength([]byte("")) != 0: 640 t.Fail() 641 case trie.longestCommonPrefixLength([]byte("12345")) != 5: 642 t.Fail() 643 case trie.longestCommonPrefixLength([]byte("123789")) != 3: 644 t.Fail() 645 case trie.longestCommonPrefixLength([]byte("12345678901")) != 10: 646 t.Fail() 647 } 648 } 649 650 // Examples -------------------------------------------------------------------- 651 652 func ExampleTrie() { 653 // Create a new tree. 654 trie := NewTrie() 655 656 // Insert some items. 657 trie.Insert(Prefix("Pepa Novak"), 1) 658 trie.Insert(Prefix("Pepa Sindelar"), 2) 659 trie.Insert(Prefix("Karel Macha"), 3) 660 trie.Insert(Prefix("Karel Hynek Macha"), 4) 661 662 // Just check if some things are present in the tree. 663 key := Prefix("Pepa Novak") 664 fmt.Printf("%q present? %v\n", key, trie.Match(key)) 665 key = Prefix("Karel") 666 fmt.Printf("Anybody called %q here? %v\n", key, trie.MatchSubtree(key)) 667 668 // Walk the tree. 669 trie.Visit(printItem) 670 // "Karel Hynek Macha": 4 671 // "Karel Macha": 3 672 // "Pepa Novak": 1 673 // "Pepa Sindelar": 2 674 675 // Walk a subtree. 676 trie.VisitSubtree(Prefix("Pepa"), printItem) 677 // "Pepa Novak": 1 678 // "Pepa Sindelar": 2 679 680 // Modify an item, then fetch it from the tree. 681 trie.Set(Prefix("Karel Hynek Macha"), 10) 682 key = Prefix("Karel Hynek Macha") 683 fmt.Printf("%q: %v\n", key, trie.Get(key)) 684 // "Karel Hynek Macha": 10 685 686 // Walk prefixes. 687 prefix := Prefix("Karel Hynek Macha je kouzelnik") 688 trie.VisitPrefixes(prefix, printItem) 689 // "Karel Hynek Macha": 10 690 691 // Delete some items. 692 trie.Delete(Prefix("Pepa Novak")) 693 trie.Delete(Prefix("Karel Macha")) 694 695 // Walk again. 696 trie.Visit(printItem) 697 // "Karel Hynek Macha": 10 698 // "Pepa Sindelar": 2 699 700 // Delete a subtree. 701 trie.DeleteSubtree(Prefix("Pepa")) 702 703 // Print what is left. 704 trie.Visit(printItem) 705 // "Karel Hynek Macha": 10 706 707 // Output: 708 // "Pepa Novak" present? true 709 // Anybody called "Karel" here? true 710 // "Karel Hynek Macha": 4 711 // "Karel Macha": 3 712 // "Pepa Novak": 1 713 // "Pepa Sindelar": 2 714 // "Pepa Novak": 1 715 // "Pepa Sindelar": 2 716 // "Karel Hynek Macha": 10 717 // "Karel Hynek Macha": 10 718 // "Karel Hynek Macha": 10 719 // "Pepa Sindelar": 2 720 // "Karel Hynek Macha": 10 721 } 722 723 // Helpers --------------------------------------------------------------------- 724 725 func printItem(prefix Prefix, item Item) error { 726 fmt.Printf("%q: %v\n", prefix, item) 727 return nil 728 }