Skip to content

Commit

Permalink
storage: add IterOptions.RangeKeyMaskingBelow
Browse files Browse the repository at this point in the history
This patch adds an iterator option `RangeKeyMaskingBelow`, which will
cause range keys at or below the given timestamp to mask any point
keys below them.

Release note: None
  • Loading branch information
erikgrinaker committed Apr 3, 2022
1 parent 4f2e461 commit f8ce1fa
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 8 deletions.
11 changes: 11 additions & 0 deletions pkg/storage/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,17 @@ type IterOptions struct {
// MVCCIterators from them. Range key behavior for EngineIterators is
// undefined.
KeyTypes IterKeyType
// RangeKeyMaskingBelow enables masking (hiding) of point keys by range keys.
// Any range key with a timestamp at or below the RangeKeyMaskingBelow
// timestamp will mask point keys below it, preventing them from being
// surfaced. Consider the following example:
//
// 4 o---------------o RangeKeyMaskingBelow=4 emits b3
// 3 b3 d3 RangeKeyMaskingBelow=3 emits b3,d3,f2
// 2 o---------------o f2 RangeKeyMaskingBelow=2 emits b3,d3,f2
// 1 a1 b1 o-------o RangeKeyMaskingBelow=1 emits a1,b3,b1,d3,f2
// a b c d e f g
RangeKeyMaskingBelow hlc.Timestamp
}

// IterKeyType configures which types of keys an iterator should surface.
Expand Down
5 changes: 4 additions & 1 deletion pkg/storage/mvcc_history_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ import (
// put_rangekey k=<key> end=<key> ts=<int>[,<int>]
// scan [t=<name>] [ts=<int>[,<int>]] [resolve [status=<txnstatus>]] k=<key> [end=<key>] [inconsistent] [tombstones] [reverse] [failOnMoreRecent] [localUncertaintyLimit=<int>[,<int>]] [globalUncertaintyLimit=<int>[,<int>]] [max=<max>] [targetbytes=<target>] [avoidExcess] [allowEmpty]
//
// iter [k=<key>] [end=<key>] [kind=key|keyAndIntents] [types=pointsOnly|pointsWithRanges|pointsAndRanges|rangesOnly]
// iter [k=<key>] [end=<key>] [kind=key|keyAndIntents] [types=pointsOnly|pointsWithRanges|pointsAndRanges|rangesOnly] [maskBelow=<int>[,<int>]]
// iter_seek_ge k=<key> [ts=<int>[,<int>]]
// iter_seek_lt k=<key> [ts=<int>[,<int>]]
// iter_seek_intent_ge k=<key> txn=<name>
Expand Down Expand Up @@ -974,6 +974,9 @@ func cmdIterNew(e *evalCtx) error {
return errors.Errorf("unknown key type %s", arg)
}
}
if e.hasArg("maskBelow") {
opts.RangeKeyMaskingBelow = e.getTsWithName(nil, "maskBelow")
}

var r, closeReader Reader
rType := util.ConstantWithMetamorphicTestChoice(
Expand Down
8 changes: 6 additions & 2 deletions pkg/storage/pebble.go
Original file line number Diff line number Diff line change
Expand Up @@ -1946,7 +1946,8 @@ func (p *pebbleReadOnly) NewMVCCIterator(iterKind MVCCIterKind, opts IterOptions
}

// TODO(erikgrinaker): We should generalize and consolidate iterator reuse.
reusable := opts.MinTimestampHint.IsEmpty() && opts.KeyTypes == IterKeyTypePointsOnly
reusable := opts.MinTimestampHint.IsEmpty() && opts.KeyTypes == IterKeyTypePointsOnly &&
opts.RangeKeyMaskingBelow.IsEmpty()
if !reusable {
iter := MVCCIterator(newPebbleIterator(
p.parent.db, nil, opts, p.durability, p.parent.db.FormatMajorVersion()))
Expand Down Expand Up @@ -1991,7 +1992,7 @@ func (p *pebbleReadOnly) NewEngineIterator(opts IterOptions) EngineIterator {
panic("using a closed pebbleReadOnly")
}

reusable := opts.KeyTypes == IterKeyTypePointsOnly
reusable := opts.KeyTypes == IterKeyTypePointsOnly && opts.RangeKeyMaskingBelow.IsEmpty()
if !reusable {
return newPebbleIterator(
p.parent.db, nil, opts, StandardDurability, p.parent.db.FormatMajorVersion())
Expand Down Expand Up @@ -2033,6 +2034,9 @@ func checkOptionsForIterReuse(opts IterOptions) {
if opts.KeyTypes != IterKeyTypePointsOnly {
panic("iterators with range keys cannot be reused")
}
if opts.RangeKeyMaskingBelow.IsSet() {
panic("iterators with range key masking cannot be reused")
}
if !opts.Prefix && len(opts.UpperBound) == 0 && len(opts.LowerBound) == 0 {
panic("iterator must set prefix or upper bound or lower bound")
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/storage/pebble_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ func (p *pebbleBatch) NewMVCCIterator(iterKind MVCCIterKind, opts IterOptions) M
return iter
}

reusable := opts.MinTimestampHint.IsEmpty() && opts.KeyTypes == IterKeyTypePointsOnly
reusable := opts.MinTimestampHint.IsEmpty() && opts.KeyTypes == IterKeyTypePointsOnly &&
opts.RangeKeyMaskingBelow.IsEmpty()
if !reusable {
iter := MVCCIterator(newPebbleIterator(
p.batch, nil, opts, StandardDurability, p.db.FormatMajorVersion()))
Expand Down Expand Up @@ -259,7 +260,7 @@ func (p *pebbleBatch) NewEngineIterator(opts IterOptions) EngineIterator {
panic("write-only batch")
}

reusable := opts.KeyTypes == IterKeyTypePointsOnly
reusable := opts.KeyTypes == IterKeyTypePointsOnly && opts.RangeKeyMaskingBelow.IsEmpty()
if !reusable {
return newPebbleIterator(p.batch, nil, opts, StandardDurability, p.db.FormatMajorVersion())
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/storage/pebble_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ func (p *pebbleIterator) init(
}
}

if opts.RangeKeyMaskingBelow.IsSet() {
p.options.RangeKeyMasking = pebble.RangeKeyMasking{
Suffix: EncodeMVCCTimestampSuffix(opts.RangeKeyMaskingBelow),
}
}

if doClone {
var err error
if p.iter, err = iterToClone.Clone(); err != nil {
Expand Down
Loading

0 comments on commit f8ce1fa

Please sign in to comment.