@@ -550,6 +550,21 @@ func (i *Iterator) findNextEntry(limit []byte) {
550
550
return
551
551
}
552
552
553
+ // If the user has configured a SkipPoint function, invoke it to see
554
+ // whether we should skip over the current user key.
555
+ if i .opts .SkipPoint != nil && key .Kind () != InternalKeyKindRangeKeySet && i .opts .SkipPoint (i .iterKey .UserKey ) {
556
+ // NB: We could call nextUserKey, but in some cases the SkipPoint
557
+ // predicate function might be cheaper than nextUserKey's key copy
558
+ // and key comparison. This should be the case for MVCC suffix
559
+ // comparisons, for example. In the future, we could expand the
560
+ // SkipPoint interface to give the implementor more control over
561
+ // whether we skip over just the internal key, the user key, or even
562
+ // the key prefix.
563
+ i .stats .ForwardStepCount [InternalIterCall ]++
564
+ i .iterKey , i .iterValue = i .iter .Next ()
565
+ continue
566
+ }
567
+
553
568
switch key .Kind () {
554
569
case InternalKeyKindRangeKeySet :
555
570
// Save the current key.
@@ -619,6 +634,13 @@ func (i *Iterator) findNextEntry(limit []byte) {
619
634
}
620
635
621
636
func (i * Iterator ) nextPointCurrentUserKey () bool {
637
+ // If the user has configured a SkipPoint function and the current user key
638
+ // would be skipped by it, there's no need to step forward looking for a
639
+ // point key. If we were to find one, it should be skipped anyways.
640
+ if i .opts .SkipPoint != nil && i .opts .SkipPoint (i .key ) {
641
+ return false
642
+ }
643
+
622
644
i .pos = iterPosCurForward
623
645
624
646
i .iterKey , i .iterValue = i .iter .Next ()
@@ -911,6 +933,26 @@ func (i *Iterator) findPrevEntry(limit []byte) {
911
933
}
912
934
}
913
935
936
+ // If the user has configured a SkipPoint function, invoke it to see
937
+ // whether we should skip over the current user key.
938
+ if i .opts .SkipPoint != nil && key .Kind () != InternalKeyKindRangeKeySet && i .opts .SkipPoint (key .UserKey ) {
939
+ // NB: We could call prevUserKey, but in some cases the SkipPoint
940
+ // predicate function might be cheaper than prevUserKey's key copy
941
+ // and key comparison. This should be the case for MVCC suffix
942
+ // comparisons, for example. In the future, we could expand the
943
+ // SkipPoint interface to give the implementor more control over
944
+ // whether we skip over just the internal key, the user key, or even
945
+ // the key prefix.
946
+ i .stats .ReverseStepCount [InternalIterCall ]++
947
+ i .iterKey , i .iterValue = i .iter .Prev ()
948
+ if limit != nil && i .iterKey != nil && i .cmp (limit , i .iterKey .UserKey ) > 0 && ! i .rangeKeyWithinLimit (limit ) {
949
+ i .iterValidityState = IterAtLimit
950
+ i .pos = iterPosCurReversePaused
951
+ return
952
+ }
953
+ continue
954
+ }
955
+
914
956
switch key .Kind () {
915
957
case InternalKeyKindRangeKeySet :
916
958
// Range key start boundary markers are interleaved with the maximum
@@ -948,12 +990,12 @@ func (i *Iterator) findPrevEntry(limit []byte) {
948
990
// Compare with the limit. We could optimize by only checking when
949
991
// we step to the previous user key, but detecting that requires a
950
992
// comparison too. Note that this position may already passed a
951
- // number of versions of this user key, but they are all deleted,
952
- // so the fact that a subsequent Prev*() call will not see them is
993
+ // number of versions of this user key, but they are all deleted, so
994
+ // the fact that a subsequent Prev*() call will not see them is
953
995
// harmless. Also note that this is the only place in the loop,
954
- // other than the firstLoopIter case above, where we could step
955
- // to a different user key and start processing it for returning
956
- // to the caller.
996
+ // other than the firstLoopIter and SkipPoint cases above, where we
997
+ // could step to a different user key and start processing it for
998
+ // returning to the caller.
957
999
if limit != nil && i .iterKey != nil && i .cmp (limit , i .iterKey .UserKey ) > 0 && ! i .rangeKeyWithinLimit (limit ) {
958
1000
i .iterValidityState = IterAtLimit
959
1001
i .pos = iterPosCurReversePaused
@@ -2428,7 +2470,8 @@ func (i *Iterator) SetOptions(o *IterOptions) {
2428
2470
// If either options specify block property filters for an iterator stack,
2429
2471
// reconstruct it.
2430
2472
if i .pointIter != nil && (closeBoth || len (o .PointKeyFilters ) > 0 || len (i .opts .PointKeyFilters ) > 0 ||
2431
- o .RangeKeyMasking .Filter != nil || i .opts .RangeKeyMasking .Filter != nil ) {
2473
+ o .RangeKeyMasking .Filter != nil || i .opts .RangeKeyMasking .Filter != nil || o .SkipPoint != nil ||
2474
+ i .opts .SkipPoint != nil ) {
2432
2475
i .err = firstError (i .err , i .pointIter .Close ())
2433
2476
i .pointIter = nil
2434
2477
}
0 commit comments