Skip to content

Commit 182f936

Browse files
committed
internal/keyspan: add special SPANSTART, SPANEND key kinds
1 parent c4b8017 commit 182f936

File tree

8 files changed

+89
-10
lines changed

8 files changed

+89
-10
lines changed

batch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,7 @@ func (i *flushableBatchIter) extractValue() base.LazyValue {
22842284
return base.LazyValue{}
22852285
}
22862286
kind := InternalKeyKind(p[0])
2287-
if kind > InternalKeyKindMax {
2287+
if kind > base.InternalKeyKindDurableMax {
22882288
i.err = base.CorruptionErrorf("corrupted batch")
22892289
return base.LazyValue{}
22902290
}

batchrepr/reader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (r *Reader) Next() (kind base.InternalKeyKind, ukey []byte, value []byte, o
8787
return 0, nil, nil, false, nil
8888
}
8989
kind = base.InternalKeyKind((*r)[0])
90-
if kind > base.InternalKeyKindMax {
90+
if kind > base.InternalKeyKindDurableMax {
9191
return 0, nil, nil, false, errors.Wrapf(ErrInvalidBatch, "invalid key kind 0x%x", (*r)[0])
9292
}
9393
*r, ukey, ok = DecodeStr((*r)[1:])

ingest.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func ingestSynthesizeShared(
139139
// a.RANGEDEL.100, with a.RANGEDEL.100 being the smallest key. To create a
140140
// correct bound, we just use the maximum key kind (which sorts first).
141141
// Similarly, we use the smallest key kind for the largest key.
142-
smallestPointKey := base.MakeInternalKey(sm.SmallestPointKey.UserKey, 0, base.InternalKeyKindMax)
142+
smallestPointKey := base.MakeInternalKey(sm.SmallestPointKey.UserKey, 0, base.InternalKeyKindDurableMax)
143143
largestPointKey := base.MakeInternalKey(sm.LargestPointKey.UserKey, 0, 0)
144144
if sm.LargestPointKey.IsExclusiveSentinel() {
145145
largestPointKey = base.MakeRangeDeleteSentinelKey(sm.LargestPointKey.UserKey)
@@ -220,12 +220,12 @@ func ingestLoad1External(
220220
if e.EndKeyIsInclusive {
221221
meta.ExtendPointKeyBounds(
222222
opts.Comparer.Compare,
223-
base.MakeInternalKey(smallestCopy, 0, InternalKeyKindMax),
223+
base.MakeInternalKey(smallestCopy, 0, base.InternalKeyKindDurableMax),
224224
base.MakeInternalKey(largestCopy, 0, 0))
225225
} else {
226226
meta.ExtendPointKeyBounds(
227227
opts.Comparer.Compare,
228-
base.MakeInternalKey(smallestCopy, 0, InternalKeyKindMax),
228+
base.MakeInternalKey(smallestCopy, 0, base.InternalKeyKindDurableMax),
229229
base.MakeRangeDeleteSentinelKey(largestCopy))
230230
}
231231
}

internal/base/internal.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ const (
9696
// heuristics, but is not required to be accurate for correctness.
9797
InternalKeyKindDeleteSized InternalKeyKind = 23
9898

99+
InternalKeyKindSpanStart InternalKeyKind = 24
100+
InternalKeyKindSpanEnd InternalKeyKind = 25
101+
99102
// This maximum value isn't part of the file format. Future extensions may
100103
// increase this value.
101104
//
@@ -105,7 +108,12 @@ const (
105108
// which sorts 'less than or equal to' any other valid internalKeyKind, when
106109
// searching for any kind of internal key formed by a certain user key and
107110
// seqNum.
108-
InternalKeyKindMax InternalKeyKind = 23
111+
InternalKeyKindMax InternalKeyKind = 25
112+
113+
// NB: This is less than InternalKeyKindSpanStart and InternalKeyKindSpanEnd
114+
// because those key kinds are never used in durable formats; only as
115+
// special in-memory indicators.
116+
InternalKeyKindDurableMax InternalKeyKind = 23
109117

110118
// Internal to the sstable format. Not exposed by any sstable iterator.
111119
// Declared here to prevent definition of valid key kinds that set this bit.
@@ -157,6 +165,8 @@ var internalKeyKindNames = []string{
157165
InternalKeyKindRangeKeyDelete: "RANGEKEYDEL",
158166
InternalKeyKindIngestSST: "INGESTSST",
159167
InternalKeyKindDeleteSized: "DELSIZED",
168+
InternalKeyKindSpanStart: "SPANSTART",
169+
InternalKeyKindSpanEnd: "SPANEND",
160170
InternalKeyKindInvalid: "INVALID",
161171
}
162172

@@ -249,6 +259,8 @@ var kindsMap = map[string]InternalKeyKind{
249259
"RANGEKEYDEL": InternalKeyKindRangeKeyDelete,
250260
"INGESTSST": InternalKeyKindIngestSST,
251261
"DELSIZED": InternalKeyKindDeleteSized,
262+
"SPANSTART": InternalKeyKindSpanStart,
263+
"SPANEND": InternalKeyKindSpanEnd,
252264
}
253265

254266
// ParseInternalKey parses the string representation of an internal key. The
@@ -476,7 +488,8 @@ func (k InternalKey) IsExclusiveSentinel() bool {
476488
}
477489
switch kind := k.Kind(); kind {
478490
case InternalKeyKindRangeDelete, InternalKeyKindRangeKeyDelete,
479-
InternalKeyKindRangeKeyUnset, InternalKeyKindRangeKeySet:
491+
InternalKeyKindRangeKeyUnset, InternalKeyKindRangeKeySet,
492+
InternalKeyKindSpanStart, InternalKeyKindSpanEnd:
480493
return true
481494
default:
482495
return false

internal/base/internal_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func TestInvalidInternalKey(t *testing.T) {
4141
"\x01\x02\x03\x04\x05\x06\x07",
4242
"foo",
4343
"foo\x08\x07\x06\x05\x04\x03\x02",
44-
"foo\x18\x07\x06\x05\x04\x03\x02\x01",
44+
"foo\x1a\x07\x06\x05\x04\x03\x02\x01",
4545
}
4646
for _, tc := range testCases {
4747
k := DecodeInternalKey([]byte(tc))

internal/keyspan/interleaving_iter.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ type InterleavingIterOpts struct {
199199
// end keys of spans (in addition to the start keys, which are always
200200
// interleaved).
201201
InterleaveEndKeys bool
202+
// UseBoundaryKeyKinds configures the interleaving iterator to interleave
203+
// keys using SPANSTART and SPANEND key kinds for start and end boundaries
204+
// respectively, rather than the key kind of the first key in the Span.
205+
UseBoundaryKeyKinds bool
202206
}
203207

204208
// Init initializes the InterleavingIter to interleave point keys from pointIter
@@ -979,7 +983,12 @@ func (i *InterleavingIter) yieldPointKey() *base.InternalKV {
979983

980984
func (i *InterleavingIter) yieldSyntheticSpanStartMarker(lowerBound []byte) *base.InternalKV {
981985
i.spanMarker.K.UserKey = i.startKey()
982-
i.spanMarker.K.Trailer = base.MakeTrailer(base.InternalKeySeqNumMax, i.span.Keys[0].Kind())
986+
987+
kind := base.InternalKeyKindSpanStart
988+
if !i.opts.UseBoundaryKeyKinds {
989+
kind = i.span.Keys[0].Kind()
990+
}
991+
i.spanMarker.K.Trailer = base.MakeTrailer(base.InternalKeySeqNumMax, kind)
983992

984993
// Truncate the key we return to our lower bound if we have one. Note that
985994
// we use the lowerBound function parameter, not i.lower. The lowerBound
@@ -1015,8 +1024,12 @@ func (i *InterleavingIter) yieldSyntheticSpanStartMarker(lowerBound []byte) *bas
10151024
}
10161025

10171026
func (i *InterleavingIter) yieldSyntheticSpanEndMarker() *base.InternalKV {
1027+
kind := base.InternalKeyKindSpanEnd
1028+
if !i.opts.UseBoundaryKeyKinds {
1029+
kind = i.span.Keys[0].Kind()
1030+
}
10181031
i.spanMarker.K.UserKey = i.endKey()
1019-
i.spanMarker.K.Trailer = base.MakeTrailer(base.InternalKeySeqNumMax, i.span.Keys[0].Kind())
1032+
i.spanMarker.K.Trailer = base.MakeTrailer(base.InternalKeySeqNumMax, kind)
10201033
return i.verify(&i.spanMarker)
10211034
}
10221035

internal/keyspan/interleaving_iter_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func runInterleavingIterTest(t *testing.T, filename string) {
123123
hooks.threshold = []byte(strings.Join(cmdArg.Vals, ""))
124124
}
125125
opts.InterleaveEndKeys = td.HasArg("interleave-end-keys")
126+
opts.UseBoundaryKeyKinds = td.HasArg("use-boundary-key-kinds")
126127
iter.Init(testkeys.Comparer, &pointIter, keyspanIter, opts)
127128
// Clear any previous bounds.
128129
pointIter.SetBounds(nil, nil)

internal/keyspan/testdata/interleaving_iter

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,58 @@ Span: f-g:{(#6,RANGEDEL)}
11521152
-- SpanChanged(nil)
11531153
.
11541154

1155+
iter interleave-end-keys use-boundary-key-kinds
1156+
first
1157+
next
1158+
next
1159+
next
1160+
next
1161+
next
1162+
next
1163+
next
1164+
next
1165+
next
1166+
next
1167+
----
1168+
-- SpanChanged(nil)
1169+
-- SpanChanged(nil)
1170+
PointKey: a@4#8,SET
1171+
Span: <invalid>
1172+
-
1173+
-- SpanChanged(b-e:{(#5,RANGEDEL)})
1174+
PointKey: b#72057594037927935,SPANSTART
1175+
Span: b-e:{(#5,RANGEDEL)}
1176+
-
1177+
PointKey: c@11#8,SET
1178+
Span: b-e:{(#5,RANGEDEL)}
1179+
-
1180+
PointKey: c@3#8,SET
1181+
Span: b-e:{(#5,RANGEDEL)}
1182+
-
1183+
PointKey: c@1#4,SET
1184+
Span: b-e:{(#5,RANGEDEL)}
1185+
-
1186+
PointKey: d@5#3,SET
1187+
Span: b-e:{(#5,RANGEDEL)}
1188+
-
1189+
PointKey: e#72057594037927935,SPANEND
1190+
Span: b-e:{(#5,RANGEDEL)}
1191+
-
1192+
-- SpanChanged(nil)
1193+
PointKey: e@9#2,SET
1194+
Span: <invalid>
1195+
-
1196+
-- SpanChanged(f-g:{(#6,RANGEDEL)})
1197+
PointKey: f#72057594037927935,SPANSTART
1198+
Span: f-g:{(#6,RANGEDEL)}
1199+
-
1200+
PointKey: g#72057594037927935,SPANEND
1201+
Span: f-g:{(#6,RANGEDEL)}
1202+
-
1203+
-- SpanChanged(nil)
1204+
.
1205+
1206+
11551207
iter interleave-end-keys
11561208
last
11571209
prev

0 commit comments

Comments
 (0)