@@ -20,10 +20,12 @@ import (
20
20
21
21
"github.com/ava-labs/avalanchego/database"
22
22
"github.com/ava-labs/avalanchego/ids"
23
- "github.com/ava-labs/avalanchego/utils/set"
24
23
)
25
24
26
- const defaultPreallocationSize = 100
25
+ const (
26
+ initKeyValuesSize = 256
27
+ defaultPreallocationSize = 100
28
+ )
27
29
28
30
var (
29
31
_ TrieView = (* trieView )(nil )
@@ -418,25 +420,20 @@ func (t *trieView) GetRangeProof(
418
420
t .lock .RLock ()
419
421
}
420
422
421
- var (
422
- result RangeProof
423
- err error
424
- )
423
+ var result RangeProof
425
424
426
- result .KeyValues , err = t .getKeyValues (
427
- start ,
428
- end ,
429
- maxLength ,
430
- set.Set [string ]{},
431
- false , /*lock*/
432
- )
433
- if err != nil {
434
- return nil , err
425
+ result .KeyValues = make ([]KeyValue , 0 , initKeyValuesSize )
426
+ it := t .NewIteratorWithStart (start )
427
+ for it .Next () && len (result .KeyValues ) < maxLength && (len (end ) == 0 || bytes .Compare (it .Key (), end ) <= 0 ) {
428
+ // clone the value to prevent editing of the values stored within the trie
429
+ result .KeyValues = append (result .KeyValues , KeyValue {
430
+ Key : it .Key (),
431
+ Value : slices .Clone (it .Value ()),
432
+ })
435
433
}
436
-
437
- // copy values, so edits won't affect the underlying arrays
438
- for i , kv := range result .KeyValues {
439
- result .KeyValues [i ] = KeyValue {Key : kv .Key , Value : slices .Clone (kv .Value )}
434
+ it .Release ()
435
+ if err := it .Error (); err != nil {
436
+ return nil , err
440
437
}
441
438
442
439
// This proof may not contain all key-value pairs in [start, end] due to size limitations.
@@ -719,140 +716,6 @@ func (t *trieView) getMerkleRoot(ctx context.Context) (ids.ID, error) {
719
716
return t .root .id , nil
720
717
}
721
718
722
- // Returns up to [maxLength] key/values from keys in closed range [start, end].
723
- // Acts similarly to the merge step of a merge sort to combine state from the view
724
- // with state from the parent trie.
725
- // If [lock], grabs [t.lock]'s read lock.
726
- // Otherwise assumes [t.lock]'s read lock is held.
727
- func (t * trieView ) getKeyValues (
728
- start []byte ,
729
- end []byte ,
730
- maxLength int ,
731
- keysToIgnore set.Set [string ],
732
- lock bool ,
733
- ) ([]KeyValue , error ) {
734
- if lock {
735
- t .lock .RLock ()
736
- defer t .lock .RUnlock ()
737
- }
738
-
739
- if maxLength <= 0 {
740
- return nil , fmt .Errorf ("%w but was %d" , ErrInvalidMaxLength , maxLength )
741
- }
742
-
743
- if t .isInvalid () {
744
- return nil , ErrInvalid
745
- }
746
-
747
- // collect all values that have changed or been deleted
748
- changes := make ([]KeyValue , 0 , len (t .changes .values ))
749
- for key , change := range t .changes .values {
750
- if change .after .IsNothing () {
751
- // This was deleted
752
- keysToIgnore .Add (string (key .Serialize ().Value ))
753
- } else {
754
- changes = append (changes , KeyValue {
755
- Key : key .Serialize ().Value ,
756
- Value : change .after .value ,
757
- })
758
- }
759
- }
760
- // sort [changes] so they can be merged with the parent trie's state
761
- slices .SortFunc (changes , func (a , b KeyValue ) bool {
762
- return bytes .Compare (a .Key , b .Key ) == - 1
763
- })
764
-
765
- baseKeyValues , err := t .getParentTrie ().getKeyValues (
766
- start ,
767
- end ,
768
- maxLength ,
769
- keysToIgnore ,
770
- true , /*lock*/
771
- )
772
- if err != nil {
773
- return nil , err
774
- }
775
-
776
- var (
777
- // True if there are more key/value pairs from [baseKeyValues] to add to result
778
- baseKeyValuesFinished = false
779
- // True if there are more key/value pairs from [changes] to add to result
780
- changesFinished = false
781
- // The index of the next key/value pair to add from [baseKeyValues].
782
- baseKeyValuesIndex = 0
783
- // The index of the next key/value pair to add from [changes].
784
- changesIndex = 0
785
- remainingLength = maxLength
786
- hasUpperBound = len (end ) > 0
787
- result = make ([]KeyValue , 0 , len (baseKeyValues ))
788
- )
789
-
790
- // keep adding key/value pairs until one of the following:
791
- // * a key that is lexicographically larger than the end key is hit
792
- // * the maxLength is hit
793
- // * no more values are available to add
794
- for remainingLength > 0 {
795
- // the baseKeyValues iterator is finished when we have run out of keys or hit a key greater than the end key
796
- baseKeyValuesFinished = baseKeyValuesFinished ||
797
- (baseKeyValuesIndex >= len (baseKeyValues ) || (hasUpperBound && bytes .Compare (baseKeyValues [baseKeyValuesIndex ].Key , end ) == 1 ))
798
-
799
- // the changes iterator is finished when we have run out of keys or hit a key greater than the end key
800
- changesFinished = changesFinished ||
801
- (changesIndex >= len (changes ) || (hasUpperBound && bytes .Compare (changes [changesIndex ].Key , end ) == 1 ))
802
-
803
- // if both the base state and changes are finished, return the result of the merge
804
- if baseKeyValuesFinished && changesFinished {
805
- return result , nil
806
- }
807
-
808
- // one or both iterators still have values, so one will be added to the result
809
- remainingLength --
810
-
811
- // both still have key/values available, so add the smallest key
812
- if ! changesFinished && ! baseKeyValuesFinished {
813
- currentChangeState := changes [changesIndex ]
814
- currentKeyValues := baseKeyValues [baseKeyValuesIndex ]
815
-
816
- switch bytes .Compare (currentChangeState .Key , currentKeyValues .Key ) {
817
- case - 1 :
818
- result = append (result , currentChangeState )
819
- changesIndex ++
820
- case 0 :
821
- // the keys are the same, so override the base value with the changed value
822
- result = append (result , currentChangeState )
823
- changesIndex ++
824
- baseKeyValuesIndex ++
825
- case 1 :
826
- result = append (result , currentKeyValues )
827
- baseKeyValuesIndex ++
828
- }
829
- continue
830
- }
831
-
832
- // the base state is not finished, but the changes is finished.
833
- // add the next base state value.
834
- if ! baseKeyValuesFinished {
835
- currentBaseState := baseKeyValues [baseKeyValuesIndex ]
836
- result = append (result , currentBaseState )
837
- baseKeyValuesIndex ++
838
- continue
839
- }
840
-
841
- // the base state is finished, but the changes is not finished.
842
- // add the next changes value.
843
- currentChangeState := changes [changesIndex ]
844
- result = append (result , currentChangeState )
845
- changesIndex ++
846
- }
847
-
848
- // ensure no ancestor changes occurred during execution
849
- if t .isInvalid () {
850
- return nil , ErrInvalid
851
- }
852
-
853
- return result , nil
854
- }
855
-
856
719
func (t * trieView ) GetValues (_ context.Context , keys [][]byte ) ([][]byte , []error ) {
857
720
t .lock .RLock ()
858
721
defer t .lock .RUnlock ()
0 commit comments