@@ -460,84 +460,223 @@ def _update_kv_node(self, node, key, value):
460
460
return new_node
461
461
462
462
def _getany (self , node , reverse = False , path = []):
463
+ # print 'getany', node, 'reverse=', reverse, path
463
464
node_type = self ._get_node_type (node )
464
465
if node_type == NODE_TYPE_BLANK :
465
466
return None
466
467
if node_type == NODE_TYPE_BRANCH :
467
- if node [16 ]:
468
+ if node [16 ] and not reverse :
469
+ # print 'found!', [16], path
468
470
return [16 ]
469
471
scan_range = list (range (16 ))
470
472
if reverse :
471
473
scan_range .reverse ()
472
474
for i in scan_range :
473
- o = self ._getany (self ._decode_to_node (node [i ]), path = path + [i ])
474
- if o :
475
+ o = self ._getany (self ._decode_to_node (node [i ]), reverse = reverse , path = path + [i ])
476
+ if o is not None :
477
+ # print 'found@', [i] + o, path
475
478
return [i ] + o
479
+ if node [16 ] and reverse :
480
+ # print 'found!', [16], path
481
+ return [16 ]
476
482
return None
477
483
curr_key = without_terminator (unpack_to_nibbles (node [0 ]))
478
484
if node_type == NODE_TYPE_LEAF :
485
+ # print 'found#', curr_key, path
479
486
return curr_key
480
487
481
488
if node_type == NODE_TYPE_EXTENSION :
482
489
curr_key = without_terminator (unpack_to_nibbles (node [0 ]))
483
490
sub_node = self ._decode_to_node (node [1 ])
484
- return self ._getany (sub_node , path = path + curr_key )
491
+ return curr_key + self ._getany (sub_node , reverse = reverse , path = path + curr_key )
492
+
493
+ def _split (self , node , key ):
494
+ node_type = self ._get_node_type (node )
495
+ if node_type == NODE_TYPE_BLANK :
496
+ return BLANK_NODE , BLANK_NODE
497
+ elif not key :
498
+ return BLANK_NODE , node
499
+ elif node_type == NODE_TYPE_BRANCH :
500
+ b1 = node [:key [0 ]]
501
+ b1 += ['' ] * (17 - len (b1 ))
502
+ b2 = node [key [0 ]+ 1 :]
503
+ b2 = ['' ] * (17 - len (b2 )) + b2
504
+ b1 [16 ], b2 [16 ] = b2 [16 ], b1 [16 ]
505
+ sub = self ._decode_to_node (node [key [0 ]])
506
+ sub1 , sub2 = self ._split (sub , key [1 :])
507
+ b1 [key [0 ]] = self ._encode_node (sub1 ) if sub1 else ''
508
+ b2 [key [0 ]] = self ._encode_node (sub2 ) if sub2 else ''
509
+ return self ._normalize_branch_node (b1 ) if len ([x for x in b1 if x ]) else BLANK_NODE , \
510
+ self ._normalize_branch_node (b2 ) if len ([x for x in b2 if x ]) else BLANK_NODE
511
+
512
+ descend_key = without_terminator (unpack_to_nibbles (node [0 ]))
513
+ if node_type == NODE_TYPE_LEAF :
514
+ if descend_key < key :
515
+ return node , BLANK_NODE
516
+ else :
517
+ return BLANK_NODE , node
518
+ elif node_type == NODE_TYPE_EXTENSION :
519
+ sub_node = self ._decode_to_node (node [1 ])
520
+ sub_key = key [len (descend_key ):]
521
+ if starts_with (key , descend_key ):
522
+ sub1 , sub2 = self ._split (sub_node , sub_key )
523
+ subtype1 = self ._get_node_type (sub1 )
524
+ subtype2 = self ._get_node_type (sub2 )
525
+ if not sub1 :
526
+ o1 = BLANK_NODE
527
+ elif subtype1 in (NODE_TYPE_LEAF , NODE_TYPE_EXTENSION ):
528
+ new_key = key [:len (descend_key )] + unpack_to_nibbles (sub1 [0 ])
529
+ o1 = [pack_nibbles (new_key ), sub1 [1 ]]
530
+ else :
531
+ o1 = [pack_nibbles (key [:len (descend_key )]), self ._encode_node (sub1 )]
532
+ if not sub2 :
533
+ o2 = BLANK_NODE
534
+ elif subtype2 in (NODE_TYPE_LEAF , NODE_TYPE_EXTENSION ):
535
+ new_key = key [:len (descend_key )] + unpack_to_nibbles (sub2 [0 ])
536
+ o2 = [pack_nibbles (new_key ), sub2 [1 ]]
537
+ else :
538
+ o2 = [pack_nibbles (key [:len (descend_key )]), self ._encode_node (sub2 )]
539
+ return o1 , o2
540
+ elif descend_key < key [:len (descend_key )]:
541
+ return node , BLANK_NODE
542
+ elif descend_key > key [:len (descend_key )]:
543
+ return BLANK_NODE , node
544
+ else :
545
+ return BLANK_NODE , BLANK_NODE
546
+
547
+ def split (self , key ):
548
+ key = bin_to_nibbles (key )
549
+ r1 , r2 = self ._split (self .root_node , key )
550
+ t1 , t2 = Trie (self .db ), Trie (self .db )
551
+ t1 .root_node , t2 .root_node = r1 , r2
552
+ return t1 , t2
553
+
554
+ def _merge (self , node1 , node2 ):
555
+ assert isinstance (node1 , list ) or not node1
556
+ assert isinstance (node2 , list ) or not node2
557
+ node_type1 = self ._get_node_type (node1 )
558
+ node_type2 = self ._get_node_type (node2 )
559
+ if not node1 :
560
+ return node2
561
+ if not node2 :
562
+ return node1
563
+ if node_type1 != NODE_TYPE_BRANCH and node_type2 != NODE_TYPE_BRANCH :
564
+ descend_key1 = unpack_to_nibbles (node1 [0 ])
565
+ descend_key2 = unpack_to_nibbles (node2 [0 ])
566
+ # find longest common prefix
567
+ prefix_length = 0
568
+ for i in range (min (len (descend_key1 ), len (descend_key2 ))):
569
+ if descend_key1 [i ] != descend_key2 [i ]:
570
+ break
571
+ prefix_length = i + 1
572
+ if prefix_length :
573
+ sub1 = self ._decode_to_node (node1 [1 ]) if node_type1 == NODE_TYPE_EXTENSION else node1 [1 ]
574
+ new_sub1 = [
575
+ pack_nibbles (descend_key1 [prefix_length :]),
576
+ sub1
577
+ ] if descend_key1 [prefix_length :] else sub1
578
+ sub2 = self ._decode_to_node (node2 [1 ]) if node_type2 == NODE_TYPE_EXTENSION else node2 [1 ]
579
+ new_sub2 = [
580
+ pack_nibbles (descend_key2 [prefix_length :]),
581
+ sub2
582
+ ] if descend_key2 [prefix_length :] else sub2
583
+ return [pack_nibbles (descend_key1 [:prefix_length ]),
584
+ self ._encode_node (self ._merge (new_sub1 , new_sub2 ))]
585
+
586
+ nodes = [[node1 ], [node2 ]]
587
+ for (node , node_type ) in zip (nodes , [node_type1 , node_type2 ]):
588
+ if node_type != NODE_TYPE_BRANCH :
589
+ new_node = [BLANK_NODE ] * 17
590
+ curr_key = unpack_to_nibbles (node [0 ][0 ])
591
+ new_node [curr_key [0 ]] = self ._encode_node ([
592
+ pack_nibbles (curr_key [1 :]),
593
+ node [0 ][1 ]
594
+ ]) if curr_key [0 ] < 16 and curr_key [1 :] else node [0 ][1 ]
595
+ node [0 ] = new_node
596
+ node1 , node2 = nodes [0 ][0 ], nodes [1 ][0 ]
597
+ assert len ([i for i in range (17 ) if node1 [i ] and node2 [i ]]) <= 1
598
+ new_node = [self ._encode_node (self ._merge (self ._decode_to_node (node1 [i ]), self ._decode_to_node (node2 [i ]))) if node1 [i ] and node2 [i ] else node1 [i ] or node2 [i ] for i in range (17 )]
599
+ return new_node
600
+
601
+ @classmethod
602
+ def unsafe_merge (cls , trie1 , trie2 ):
603
+ t = Trie (trie1 .db )
604
+ t .root_node = t ._merge (trie1 .root_node , trie2 .root_node )
605
+ return t
485
606
486
607
def _iter (self , node , key , reverse = False , path = []):
608
+ # print 'iter', node, key, 'reverse =', reverse, 'path =', path
487
609
node_type = self ._get_node_type (node )
488
610
489
611
if node_type == NODE_TYPE_BLANK :
490
612
return None
491
613
492
614
elif node_type == NODE_TYPE_BRANCH :
615
+ # print 'b'
493
616
if len (key ):
494
617
sub_node = self ._decode_to_node (node [key [0 ]])
495
618
o = self ._iter (sub_node , key [1 :], reverse , path + [key [0 ]])
496
- if o :
619
+ if o is not None :
620
+ # print 'returning', [key[0]] + o, path
497
621
return [key [0 ]] + o
498
622
if reverse :
499
- scan_range = list (range (key [0 ] if len (key ) else 0 ))
623
+ scan_range = reversed ( list (range (key [0 ] if len (key ) else 0 ) ))
500
624
else :
501
625
scan_range = list (range (key [0 ] + 1 if len (key ) else 0 , 16 ))
502
626
for i in scan_range :
503
627
sub_node = self ._decode_to_node (node [i ])
628
+ # print 'prelim getany', path+[i]
504
629
o = self ._getany (sub_node , reverse , path + [i ])
505
- if o :
630
+ if o is not None :
631
+ # print 'returning', [i] + o, path
506
632
return [i ] + o
507
- if reverse and node [16 ]:
633
+ if reverse and key and node [16 ]:
634
+ # print 'o'
508
635
return [16 ]
509
636
return None
510
637
511
638
descend_key = without_terminator (unpack_to_nibbles (node [0 ]))
512
639
if node_type == NODE_TYPE_LEAF :
513
640
if reverse :
641
+ # print 'L', descend_key, key, descend_key if descend_key < key else None, path
514
642
return descend_key if descend_key < key else None
515
643
else :
644
+ # print 'L', descend_key, key, descend_key if descend_key > key else None, path
516
645
return descend_key if descend_key > key else None
517
646
518
647
if node_type == NODE_TYPE_EXTENSION :
519
648
# traverse child nodes
520
649
sub_node = self ._decode_to_node (node [1 ])
521
650
sub_key = key [len (descend_key ):]
651
+ # print 'amhere', key, descend_key, descend_key > key[:len(descend_key)]
522
652
if starts_with (key , descend_key ):
523
653
o = self ._iter (sub_node , sub_key , reverse , path + descend_key )
524
654
elif descend_key > key [:len (descend_key )] and not reverse :
525
- o = self ._getany (sub_node , sub_key , False , path + descend_key )
655
+ # print 1
656
+ # print 'prelim getany', path+descend_key
657
+ o = self ._getany (sub_node , False , path + descend_key )
526
658
elif descend_key < key [:len (descend_key )] and reverse :
527
- o = self ._getany (sub_node , sub_key , True , path + descend_key )
659
+ # print 2
660
+ # print 'prelim getany', path+descend_key
661
+ o = self ._getany (sub_node , True , path + descend_key )
528
662
else :
529
663
o = None
664
+ # print 'returning@', descend_key + o if o else None, path
530
665
return descend_key + o if o else None
531
666
532
667
def next (self , key ):
668
+ # print 'nextting'
533
669
key = bin_to_nibbles (key )
534
670
o = self ._iter (self .root_node , key )
535
- return nibbles_to_bin (o ) if o else None
671
+ # print 'answer', o
672
+ return nibbles_to_bin (without_terminator (o )) if o else None
536
673
537
674
def prev (self , key ):
675
+ # print 'prevving'
538
676
key = bin_to_nibbles (key )
539
677
o = self ._iter (self .root_node , key , reverse = True )
540
- return nibbles_to_bin (o ) if o else None
678
+ # print 'answer', o
679
+ return nibbles_to_bin (without_terminator (o )) if o else None
541
680
542
681
def _delete_node_storage (self , node ):
543
682
'''delete storage
0 commit comments