Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: implement RangeKeyChanged() for MVCCIncrementalIterator #86259

Merged

Conversation

erikgrinaker
Copy link
Contributor

@erikgrinaker erikgrinaker commented Aug 16, 2022

storage: use RangeKeyChanged() in MVCCIncrementalIterator

This patch uses RangeKeyChanged() to detect changes to range keys in
MVCCIncrementalIterator. There are no functional changes.

Some quick benchmarks, using catchup scans:

name                                                                 old time/op  new time/op  delta
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=0-24      538ms ± 1%   535ms ± 1%     ~     (p=0.211 n=10+9)
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=1-24      690ms ± 0%   590ms ± 1%  -14.56%  (p=0.000 n=9+10)
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=100-24    743ms ± 1%   646ms ± 1%  -13.13%  (p=0.000 n=9+9)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=0-24     794ms ± 1%   794ms ± 0%     ~     (p=0.579 n=10+10)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=1-24     966ms ± 0%   911ms ± 1%   -5.72%  (p=0.000 n=10+10)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=100-24   974ms ± 0%   920ms ± 0%   -5.51%  (p=0.000 n=10+10)

Release justification: bug fixes and low-risk updates to new functionality.

Release note: None

storage: implement RangeKeyChanged() for MVCCIncrementalIterator

This patch implements RangeKeyChanged() for MVCCIncrementalIterator.
It only fires if the time bound range keys change, not if a
Next(Key)IgnoringTime() operation reveals additional range keys.

Resolves #86105.

Release justification: bug fixes and low-risk updates to new functionality

Release note: None

storage: add MVCCIncrementalIterator.RangeKeysIgnoringTime()

This patch changes MVCCIncrementalIterator range key behavior
following a Next(Key)IgnoringTime() call. Previously, range key
methods would then expose unfiltered range keys. Now, the standard range
key methods only apply to filtered range keys, and an additional
RangeKeysIgnoringTime() method provides access to unfiltered range
keys.

This implies that if such a call steps onto a range key that's entirely
outside of the time bounds then:

  • HasPointAndRange() will return false,false if on a bare range
    key.

  • RangeKeyChanged() will not fire, unless stepping off of a range key
    within the time bounds.

  • RangeBounds() and RangeKeys() will return empty results.

This is done to avoid conditional range key handling following these
calls, except for the exact sites where the caller is interested in
the unfiltered range keys.

Release justification: bug fixes and low-risk updates to new functionality

Release note: None

@erikgrinaker erikgrinaker requested review from jbowens, tbg and a team August 16, 2022 20:30
@erikgrinaker erikgrinaker self-assigned this Aug 16, 2022
@erikgrinaker erikgrinaker requested a review from a team as a code owner August 16, 2022 20:30
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@erikgrinaker erikgrinaker changed the title Mvcc incremental iter rangekeychanged storage: implement RangeKeyChanged() for MVCCIncrementalIterator Aug 16, 2022
@erikgrinaker erikgrinaker force-pushed the mvcc-incremental-iter-rangekeychanged branch 5 times, most recently from 0c84cca to f56dcfb Compare August 17, 2022 10:23
Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass, still need to get a little more confident with the code, if you put a silly bug in there on purpose I probably would've missed it. Haven't looked at the test output yet. I will work a bit on #86122 to get more comfortable with the harness.

Reviewed 2 of 2 files at r2, 2 of 2 files at r3, 3 of 3 files at r4, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @erikgrinaker and @jbowens)


-- commits line 51 at r4:
This


pkg/storage/mvcc_history_test.go line 1611 at r4 (raw file):

		if e.iterRangeKeys.IsEmpty() {
			e.iterRangeKeys = MVCCRangeKeyStack{
				Bounds:   roachpb.Span{Key: keys.MinKey.Next().Clone(), EndKey: keys.MaxKey.Clone()},

Why the clone? Do we need to update keys.MinKey etc so that its cap equals its len?


pkg/storage/mvcc_incremental_iterator.go line 336 at r2 (raw file):

						return false
					}
					tbiKey = i.timeBoundIter.UnsafeKey().Key

Could i.timeBoundIter still be positioned with (hasRange && !hasPoint) at this point, i.e. can we access UnsafeKey() unconditionally here?


pkg/storage/mvcc_incremental_iterator.go line 434 at r2 (raw file):

		}
		if skipped {
			// The skip may landed in the middle of a bare range key, in which case we

may have landed


pkg/storage/mvcc_incremental_iterator.go line 435 at r2 (raw file):

		if skipped {
			// The skip may landed in the middle of a bare range key, in which case we
			// should move on to the next key.

Why is this done here and not in maybeSkipKeys?


pkg/storage/mvcc_incremental_iterator.go line 96 at r3 (raw file):

	// underlying iterator returns true as well. This can be used to hide point or
	// range keys where one key kind satisfies the time predicate but the other
	// one doesn't. Ignored following IgnoringTime() calls.

Ignored for how long? Consider expanding the comment by referencing i.ignoringTime and expanding its comment a bit to point out when the flag is reset (I guess that's when we're done with the IgnoringTime call). The code isn't so clear; we actually reset ignoringTime at the top of advance, I think someplace should explain how this works and on the field is as good a place as any. Maybe advance should also be renamed to reflect that it doesn't ignore time? advanceObservingTime? You could similarly rename hasPoint and hasRange with an ObservingTime suffix.


pkg/storage/mvcc_incremental_iterator.go line 247 at r3 (raw file):

	}
	i.iter.SeekGE(startKey)
	i.advance(true /* seek */)

Should the parameter be called seeked, since it reflects what the caller did before? As is, this sounds like imperative mood which doesn't seem right.

edit: with the comment on advance this seems clear enough, still going to submit this for your consideration.


pkg/storage/mvcc_incremental_iterator.go line 480 at r3 (raw file):

			// isn't visible either, then we keep going.
			if !i.hasPoint {
				if !i.hasRange {

Not new code, but I thought one of (hasPoint,hasRange) them has to be true for a valid iterator. This isn't true here because these values come from updateRangeKeys which filters them by time, so we could have both false. Mind pointing this out.


pkg/storage/mvcc_incremental_iterator.go line 486 at r4 (raw file):

			newRangeKey = i.hasRange
			if !hadRange && !i.hasRange {
				i.rangeKeyChanged = false

It's false already, so you don't need this?


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

// However, RangeKeyChanged() will only fire if this moves onto an entirely new
// MVCC range key, not if it reveals additional range keys at the current
// position.

Are you confident that these are the right semantics? Is it what CatchUpScan wants? It feels like this might require awkward code at each caller that also uses *IgnoringTime. Could it be better to trigger an event in this case?

If the current semantics are desirable, maybe a way to phrase them as less of a one-off is that RangeKeyChanged triggers whenever we traverse (i.e. cross or step onto) the start key of a range deletion. This is not the case if we call NextIgnoringTime while already positioned on a hidden range key, so there is no surprise that RangeKeyChanged won't fire.

I am still suspicious that current semantics are the right choice. Callers may use RangeKeyChanged to cache state that depends on the range key. Seems to invite bugs if the range key may change without the corresponding notification firing.


pkg/storage/testdata/mvcc_histories/range_key_iter_incremental line 129 at r4 (raw file):

iter_scan: "a"/4.000000000,0=/<empty> {a-b}/[1.000000000,0=/<empty>]
iter_scan: "a"/2.000000000,0=/BYTES/a2 {a-b}/[1.000000000,0=/<empty>]
iter_scan: {b-c}/[3.000000000,0=/<empty> 1.000000000,0=/<empty>] !

I don't see code in this diff that produces the exclamation mark.

Copy link
Contributor Author

@erikgrinaker erikgrinaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @erikgrinaker, @jbowens, and @tbg)


pkg/storage/mvcc_history_test.go line 1611 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Why the clone? Do we need to update keys.MinKey etc so that its cap equals its len?

Otherwise, when we call CloneInto() later which reuses the byte slices, we're trampling keys.MinKey and keys.MaxKey, which is really bad. I'll add a comment.


pkg/storage/mvcc_incremental_iterator.go line 435 at r2 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Why is this done here and not in maybeSkipKeys?

We need to record and propagate the RangeKeyChanged state during the steps. By doing this here, maybeSkipKeys only ever takes one step, so we can keep all of the RangeKeyChanged logic in one spot. Initially tried returning a value for it instead, but don't think it ended up being as clear -- either works though, no strong opinion.


pkg/storage/mvcc_incremental_iterator.go line 96 at r3 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Ignored for how long? Consider expanding the comment by referencing i.ignoringTime and expanding its comment a bit to point out when the flag is reset (I guess that's when we're done with the IgnoringTime call). The code isn't so clear; we actually reset ignoringTime at the top of advance, I think someplace should explain how this works and on the field is as good a place as any. Maybe advance should also be renamed to reflect that it doesn't ignore time? advanceObservingTime? You could similarly rename hasPoint and hasRange with an ObservingTime suffix.

Until the next positioning operation, which may or may not be another IgnoringTime operation. Will expand.


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Are you confident that these are the right semantics? Is it what CatchUpScan wants? It feels like this might require awkward code at each caller that also uses *IgnoringTime. Could it be better to trigger an event in this case?

If the current semantics are desirable, maybe a way to phrase them as less of a one-off is that RangeKeyChanged triggers whenever we traverse (i.e. cross or step onto) the start key of a range deletion. This is not the case if we call NextIgnoringTime while already positioned on a hidden range key, so there is no surprise that RangeKeyChanged won't fire.

I am still suspicious that current semantics are the right choice. Callers may use RangeKeyChanged to cache state that depends on the range key. Seems to invite bugs if the range key may change without the corresponding notification firing.

I've been going back and forth on this.

The main reason I landed on this is that if the caller is doing any caching, then triggering RangeKeyChanged´ when NextIgnoringTimereveals additional versions is going to ruin that caching anyway -- in the worst case, it's going to flip back and forth for everyNext()/NextIgnoringTime()` cycle, effectively making the caching worse than not caching at all.

Because MVCCIncrementalIterator already has to decode and process the range keys (for filtering), we can cheaply cache both of them in here, and so I think the recommended way to use this would be for the caller to not do any caching at all, but simply call RangeKeys() at the spot they need it and process as needed -- for example, this simplifies the WithDiff processing in catchupscan, which just needs to know if there's a range key between two points regardless of time filtering.

Another option I've been considering has been to always expose filtered range keys in RangeKeys(), and have a separate RangeKeysIgnoringTime() to expose unfiltered range keys. However, in that case it isn't clear what the semantics of RangeKeyChanged should be when RangeKeysIgnoringTime() changes but RangeKeys()doesn't.

Happy to talk through this on a call or something.

Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @erikgrinaker, @jbowens, and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, erikgrinaker (Erik Grinaker) wrote…

I've been going back and forth on this.

The main reason I landed on this is that if the caller is doing any caching, then triggering RangeKeyChanged´ when NextIgnoringTimereveals additional versions is going to ruin that caching anyway -- in the worst case, it's going to flip back and forth for everyNext()/NextIgnoringTime()` cycle, effectively making the caching worse than not caching at all.

Because MVCCIncrementalIterator already has to decode and process the range keys (for filtering), we can cheaply cache both of them in here, and so I think the recommended way to use this would be for the caller to not do any caching at all, but simply call RangeKeys() at the spot they need it and process as needed -- for example, this simplifies the WithDiff processing in catchupscan, which just needs to know if there's a range key between two points regardless of time filtering.

Another option I've been considering has been to always expose filtered range keys in RangeKeys(), and have a separate RangeKeysIgnoringTime() to expose unfiltered range keys. However, in that case it isn't clear what the semantics of RangeKeyChanged should be when RangeKeysIgnoringTime() changes but RangeKeys()doesn't.

Happy to talk through this on a call or something.

How about

  • RangeKeyChanged() only triggers on filtered range keys, even if XIgnoringTime exposes an unseen, out-of-bounds range key.
  • XIgnoringTime() (rangeKeyChanged bool) returns whether there's now an exclusively ignored rangekey, which can be retrieved via:
  • RangeKeyIgnoringTime() MVCCRangeKeyStack

This seems good because:

  • caching based on RangeKey when all you care about is filtered ones "just works"
  • don't randomly expose RangeKeys that are out of time bounds after a call to XIgnoringKey...
  • ... but if those are relevant, the event tracking and access to them is there, and
  • it's nicely contained in the three methods related to ignoring time bounds.

This is also operating under the assumption that access to out-of-bounds range keys will be somewhat rare. The uses I've seen revolve around discovering a version matching an intent, finding a previous version for withDiff, etc.
Would be interesting to litmus test this with MVCCPredicateDeleteRange and/or MVCCClearRange since both probably do want to see out-of-bound range dels.

This patch uses `RangeKeyChanged()` to detect changes to range keys in
`MVCCIncrementalIterator`. There are no functional changes.

Some quick benchmarks, using catchup scans:

```
name                                                                 old time/op  new time/op  delta
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=0-24      538ms ± 1%   535ms ± 1%     ~     (p=0.211 n=10+9)
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=1-24      690ms ± 0%   590ms ± 1%  -14.56%  (p=0.000 n=9+10)
CatchUpScan/mixed-case/withDiff=true/perc=0.00/numRangeKeys=100-24    743ms ± 1%   646ms ± 1%  -13.13%  (p=0.000 n=9+9)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=0-24     794ms ± 1%   794ms ± 0%     ~     (p=0.579 n=10+10)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=1-24     966ms ± 0%   911ms ± 1%   -5.72%  (p=0.000 n=10+10)
CatchUpScan/mixed-case/withDiff=false/perc=0.00/numRangeKeys=100-24   974ms ± 0%   920ms ± 0%   -5.51%  (p=0.000 n=10+10)
```

Release justification: bug fixes and low-risk updates to new functionality.

Release note: None
Copy link
Contributor Author

@erikgrinaker erikgrinaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 336 at r2 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Could i.timeBoundIter still be positioned with (hasRange && !hasPoint) at this point, i.e. can we access UnsafeKey() unconditionally here?

Yes, UnsafeKey() is also valid along a range key.


pkg/storage/mvcc_incremental_iterator.go line 435 at r2 (raw file):

Previously, erikgrinaker (Erik Grinaker) wrote…

We need to record and propagate the RangeKeyChanged state during the steps. By doing this here, maybeSkipKeys only ever takes one step, so we can keep all of the RangeKeyChanged logic in one spot. Initially tried returning a value for it instead, but don't think it ended up being as clear -- either works though, no strong opinion.

Ended up moving this back into maybeSkipKeys, it's cleaner.


pkg/storage/mvcc_incremental_iterator.go line 247 at r3 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Should the parameter be called seeked, since it reflects what the caller did before? As is, this sounds like imperative mood which doesn't seem right.

edit: with the comment on advance this seems clear enough, still going to submit this for your consideration.

Sure, done.


pkg/storage/mvcc_incremental_iterator.go line 486 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

It's false already, so you don't need this?

We need this in the case where we weren't on a range key, then stepped onto a new range key, but it got filtered out. This shouldn't trigger RangeKeyChanged() to the caller, since we're going from empty to empty.


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

How about

  • RangeKeyChanged() only triggers on filtered range keys, even if XIgnoringTime exposes an unseen, out-of-bounds range key.
  • XIgnoringTime() (rangeKeyChanged bool) returns whether there's now an exclusively ignored rangekey, which can be retrieved via:
  • RangeKeyIgnoringTime() MVCCRangeKeyStack

This seems good because:

  • caching based on RangeKey when all you care about is filtered ones "just works"
  • don't randomly expose RangeKeys that are out of time bounds after a call to XIgnoringKey...
  • ... but if those are relevant, the event tracking and access to them is there, and
  • it's nicely contained in the three methods related to ignoring time bounds.

This is also operating under the assumption that access to out-of-bounds range keys will be somewhat rare. The uses I've seen revolve around discovering a version matching an intent, finding a previous version for withDiff, etc.
Would be interesting to litmus test this with MVCCPredicateDeleteRange and/or MVCCClearRange since both probably do want to see out-of-bound range dels.

Yeah, let me do another pass over this. Seems reasonable to stick to filtered range keys by default. We may not even need XIgnoringTime() (rangeKeyChanged bool) at all -- since RangeKeyIgnoringTime() is ~free, the caller can just call it unconditionally when needed.


pkg/storage/testdata/mvcc_histories/range_key_iter_incremental line 129 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

I don't see code in this diff that produces the exclamation mark.

It was added back in #86056, but MVCCIncrementalIterator was explicitly omitted because it didn't implement RangeKeyChanged(). See changes in mvcc_history_test.go which remove those exclusions.

@erikgrinaker erikgrinaker force-pushed the mvcc-incremental-iter-rangekeychanged branch 3 times, most recently from ea57915 to 8a2f31a Compare August 20, 2022 13:08
@erikgrinaker erikgrinaker requested a review from a team as a code owner August 20, 2022 13:08
Copy link
Contributor Author

@erikgrinaker erikgrinaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, erikgrinaker (Erik Grinaker) wrote…

Yeah, let me do another pass over this. Seems reasonable to stick to filtered range keys by default. We may not even need XIgnoringTime() (rangeKeyChanged bool) at all -- since RangeKeyIgnoringTime() is ~free, the caller can just call it unconditionally when needed.

Done. All standard range key methods now only apply to filtered range keys. Unfiltered range keys are available via RangeKeysIgnoringTime().

The only wart here is that it's now possible for HasPointAndRange() to return false,false if NextIgnoringTime steps onto a bare range key that's outside the time bounds, in violation of the SimpleMVCCIterator contract. This isn't really an issue for the current callers, but it is a bit of a footgun so one has to be careful -- then again, one does have to be careful with the IgnoringTime methods in general.

@erikgrinaker erikgrinaker force-pushed the mvcc-incremental-iter-rangekeychanged branch 2 times, most recently from fc38a5b to 079066f Compare August 20, 2022 13:18
This patch implements `RangeKeyChanged()` for `MVCCIncrementalIterator`.
It only fires if the time bound range keys change, not if a
`Next(Key)IgnoringTime()` operation reveals additional range keys.

Release justification: bug fixes and low-risk updates to new functionality

Release note: None
This patch changes `MVCCIncrementalIterator` range key behavior
following a `Next(Key)IgnoringTime()` call. Previously, range key
methods would then expose unfiltered range keys. Now, the standard range
key methods only apply to filtered range keys. The additional
`RangeKeysIgnoringTime()` and `RangeKeyChangedIgnoringTime()` methods
provide access to unfiltered range keys.

This implies that if such a call steps onto a range key that's entirely
outside of the time bounds then:

* `HasPointAndRange()` will return `false`,`false` if on a bare range
  key.

* `RangeKeyChanged()` will not fire, unless stepping off of a range key
  within the time bounds.

* `RangeBounds()` and `RangeKeys()` will return empty results.

This is done to avoid conditional range key handling following these
calls, except for the exact sites where the caller is interested in
the unfiltered range keys.

Release justification: bug fixes and low-risk updates to new functionality

Release note: None
Copy link
Contributor Author

@erikgrinaker erikgrinaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, erikgrinaker (Erik Grinaker) wrote…

Done. All standard range key methods now only apply to filtered range keys. Unfiltered range keys are available via RangeKeysIgnoringTime().

The only wart here is that it's now possible for HasPointAndRange() to return false,false if NextIgnoringTime steps onto a bare range key that's outside the time bounds, in violation of the SimpleMVCCIterator contract. This isn't really an issue for the current callers, but it is a bit of a footgun so one has to be careful -- then again, one does have to be careful with the IgnoringTime methods in general.

Meh, had to add in RangeKeyChangedIgnoringTime() too, since it's otherwise possible to land on one of these bare, invisible range keys without detecting it.

See #86512 for the catchup scan "port".

Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r5, 3 of 3 files at r6.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, erikgrinaker (Erik Grinaker) wrote…

Meh, had to add in RangeKeyChangedIgnoringTime() too, since it's otherwise possible to land on one of these bare, invisible range keys without detecting it.

See #86512 for the catchup scan "port".

Think it's worth removing that last wart, too?

HasPointAndRange() (hasPoint, hasRange, hasRangeIgnoringTime bool)?

It seems valuable to have the contract that for a valid iter, HasPointAndRange() returns at least one true. Most callers could assign while ignoring the third param, if they're pretty sure they didn't call XIgnoringTime.

Copy link
Contributor Author

@erikgrinaker erikgrinaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens and @tbg)


pkg/storage/mvcc_incremental_iterator.go line 679 at r4 (raw file):

Previously, tbg (Tobias Grieger) wrote…

Think it's worth removing that last wart, too?

HasPointAndRange() (hasPoint, hasRange, hasRangeIgnoringTime bool)?

It seems valuable to have the contract that for a valid iter, HasPointAndRange() returns at least one true. Most callers could assign while ignoring the third param, if they're pretty sure they didn't call XIgnoringTime.

But that method is part of the SimpleMVCCIterator interface, so we can't add on a return value.

It seems ok to say that if Valid() returns true but HasPointAndRange() returns false,false then we must be on a hidden MVCC range tombstone.

Copy link
Member

@tbg tbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 5 of 5 files at r7, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @jbowens)

@erikgrinaker
Copy link
Contributor Author

TFTR!

bors r=tbg

@craig
Copy link
Contributor

craig bot commented Aug 22, 2022

Build succeeded:

@craig craig bot merged commit 9c7db33 into cockroachdb:master Aug 22, 2022
@erikgrinaker erikgrinaker deleted the mvcc-incremental-iter-rangekeychanged branch August 23, 2022 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

storage: implement RangeKeyChanged for MVCCIncrementalIterator
3 participants