@@ -43,7 +43,10 @@ func (n *node) NextNode() (Node, bool) {
43
43
44
44
// Value returns node's value, it returns nil if there is no
45
45
func (n * node ) Value () (interface {}, bool ) {
46
- return n .Leaf .Val , n .Leaf != nil
46
+ if n .Leaf != nil {
47
+ return n .Leaf .Val , true
48
+ }
49
+ return nil , false
47
50
}
48
51
49
52
// Extra returns node's Extra Info
@@ -73,7 +76,7 @@ type RTree struct {
73
76
}
74
77
75
78
// return common prefix's offset of s1 and s2, in byte
76
- // s1[:offset] == s2[:offset]
79
+ // s1[:offset+1 ] == s2[:offset+1 ]
77
80
func commonPrefixOffset (s1 , s2 string ) int {
78
81
i := 0
79
82
runes1 , runes2 := []rune (s1 ), []rune (s2 )
@@ -454,7 +457,96 @@ func (T *RTree) GetAllPrefixMatches(key string) map[string]interface{} {
454
457
return resultMap
455
458
}
456
459
457
- // GetBestMatch returns the longest match in the tree according to the key
460
+ type traverseLog struct {
461
+ n * node
462
+ base string
463
+ }
464
+
465
+ // GetLongerMatches returns at most `limmit` matches which are longer than the key
466
+ // if no match is found, it returns an empty map
467
+ func (T * RTree ) GetLongerMatches (key string , limit int ) map [string ]interface {} {
468
+ T .m .RLock ()
469
+ defer T .m .RUnlock ()
470
+
471
+ resultMap := map [string ]interface {}{}
472
+ if T .root == nil {
473
+ return resultMap
474
+ } else if len (key ) == 0 {
475
+ return resultMap
476
+ }
477
+
478
+ var ok bool
479
+ var rune1 rune
480
+ var matchedNode * node
481
+ node1 := T .root
482
+ pathSuffix := key
483
+ baseOffset := 0 // key[:baseOffset] is matched
484
+ for {
485
+ if node1 == nil {
486
+ return resultMap
487
+ }
488
+
489
+ rune1 = getRune1 (pathSuffix )
490
+ matchedNode , ok = node1 .Idx [rune1 ]
491
+ if ! ok {
492
+ return resultMap
493
+ }
494
+
495
+ offset := commonPrefixOffset (matchedNode .Prefix , pathSuffix )
496
+ if offset == - 1 {
497
+ // this is impossible
498
+ panic (errImpossible (matchedNode .Prefix , key ))
499
+ } else if offset == len (matchedNode .Prefix )- 1 && offset < len (pathSuffix )- 1 {
500
+ pathSuffix = pathSuffix [offset + 1 :]
501
+ node1 = matchedNode .Children
502
+ baseOffset += offset + 1
503
+ continue
504
+ } else if offset == len (pathSuffix )- 1 {
505
+ break
506
+ }
507
+ return resultMap
508
+ }
509
+
510
+ if matchedNode .Leaf != nil {
511
+ resultMap [key [:baseOffset ]+ matchedNode .Prefix ] = matchedNode .Leaf .Val
512
+ }
513
+ // start from next level becasue matchedNode's siblings are not results
514
+ // traverse from the matchedNode and return values
515
+ queue := []* traverseLog {& traverseLog {
516
+ n : matchedNode .Children ,
517
+ base : key [:baseOffset ] + matchedNode .Prefix ,
518
+ }}
519
+ for len (queue ) > 0 {
520
+ tlog := queue [0 ]
521
+ queue = queue [1 :]
522
+ if tlog .n == nil {
523
+ continue
524
+ }
525
+
526
+ if tlog .n .Leaf != nil {
527
+ resultMap [tlog .base + tlog .n .Prefix ] = tlog .n .Leaf .Val
528
+ if len (resultMap ) > limit {
529
+ break
530
+ }
531
+ }
532
+ if tlog .n .Next != nil {
533
+ queue = append (queue , & traverseLog {
534
+ n : tlog .n .Next ,
535
+ base : tlog .base ,
536
+ })
537
+ }
538
+ if tlog .n .Children != nil {
539
+ queue = append (queue , & traverseLog {
540
+ n : tlog .n .Children ,
541
+ base : tlog .base + tlog .n .Prefix ,
542
+ })
543
+ }
544
+ }
545
+
546
+ return resultMap
547
+ }
548
+
549
+ // GetBestMatch returns the longest match from all existings values which key is short than the input key
458
550
// if there is no match, it returns empty string, nil and false
459
551
func (T * RTree ) GetBestMatch (key string ) (string , interface {}, bool ) {
460
552
T .m .RLock ()
0 commit comments