Skip to content

Commit 17b8cef

Browse files
committed
db: store pointer to *Comparer on Iterator
Previously the base.Comparer struct was copied into the Iterator. As the Comparer and its fields have grown, the cost of this copy and the eventual zeroing of this structure have grown too. This commit switches to storing just a pointer to the DB's Comparer. ``` goos: darwin goarch: arm64 pkg: github.com/cockroachdb/pebble cpu: Apple M1 Pro │ prev.txt │ head.txt │ │ sec/op │ sec/op vs base │ NewIterClose/1-10 1.251µ ± 2% 1.213µ ± 0% -3.04% (p=0.000 n=10) NewIterClose/10-10 6.591µ ± 2% 6.466µ ± 1% -1.90% (p=0.004 n=10) NewIterClose/100-10 95.87µ ± 0% 93.27µ ± 2% -2.71% (p=0.001 n=10) geomean 9.246µ 9.010µ -2.55% ```
1 parent fb50dd2 commit 17b8cef

File tree

7 files changed

+22
-22
lines changed

7 files changed

+22
-22
lines changed

db.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ func (d *DB) newIter(
10121012
ctx: ctx,
10131013
alloc: buf,
10141014
merge: d.merge,
1015-
comparer: *d.opts.Comparer,
1015+
comparer: d.opts.Comparer,
10161016
readState: readState,
10171017
version: newIterOpts.snapshot.vers,
10181018
keyBuf: buf.keyBuf,
@@ -1076,7 +1076,7 @@ func finishInitializingIter(ctx context.Context, buf *iterAlloc) *Iterator {
10761076
}
10771077

10781078
if dbi.opts.rangeKeys() {
1079-
dbi.rangeKeyMasking.init(dbi, &dbi.comparer)
1079+
dbi.rangeKeyMasking.init(dbi, dbi.comparer)
10801080

10811081
// When iterating over both point and range keys, don't create the
10821082
// range-key iterator stack immediately if we can avoid it. This
@@ -1131,7 +1131,7 @@ func finishInitializingIter(ctx context.Context, buf *iterAlloc) *Iterator {
11311131
// NB: The interleaving iterator is always reinitialized, even if
11321132
// dbi already had an initialized range key iterator, in case the point
11331133
// iterator changed or the range key masking suffix changed.
1134-
dbi.rangeKey.iiter.Init(&dbi.comparer, dbi.iter, dbi.rangeKey.rangeKeyIter,
1134+
dbi.rangeKey.iiter.Init(dbi.comparer, dbi.iter, dbi.rangeKey.rangeKeyIter,
11351135
keyspan.InterleavingIterOpts{
11361136
Mask: &dbi.rangeKeyMasking,
11371137
LowerBound: dbi.opts.LowerBound,
@@ -1262,7 +1262,7 @@ func (i *Iterator) constructPointIter(
12621262
addLevelIterForFiles := func(files manifest.LevelIterator, level manifest.Layer) {
12631263
li := &levels[levelsIndex]
12641264

1265-
li.init(ctx, i.opts, &i.comparer, i.newIters, files, level, internalOpts)
1265+
li.init(ctx, i.opts, i.comparer, i.newIters, files, level, internalOpts)
12661266
li.initRangeDel(&mlevels[mlevelsIndex])
12671267
li.initCombinedIterState(&i.lazyCombinedIter.combinedIterState)
12681268
mlevels[mlevelsIndex].levelIter = li

external_iterator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func NewExternalIterWithContext(
7171
ctx: ctx,
7272
alloc: buf,
7373
merge: o.Merger.Merge,
74-
comparer: *o.Comparer,
74+
comparer: o.Comparer,
7575
readState: nil,
7676
keyBuf: buf.keyBuf,
7777
prefixOrFullSeekKey: buf.prefixOrFullSeekKey,
@@ -236,7 +236,7 @@ func finishInitializingExternal(ctx context.Context, it *Iterator) error {
236236
it.iter = it.pointIter
237237

238238
if it.opts.rangeKeys() {
239-
it.rangeKeyMasking.init(it, &it.comparer)
239+
it.rangeKeyMasking.init(it, it.comparer)
240240
var rangeKeyIters []keyspan.FragmentIterator
241241
if it.rangeKey == nil {
242242
// We could take advantage of the lack of overlaps in range keys within
@@ -272,7 +272,7 @@ func finishInitializingExternal(ctx context.Context, it *Iterator) error {
272272
if len(rangeKeyIters) > 0 {
273273
it.rangeKey = iterRangeKeyStateAllocPool.Get().(*iteratorRangeKeyState)
274274
it.rangeKey.rangeKeyIter = it.rangeKey.iterConfig.Init(
275-
&it.comparer,
275+
it.comparer,
276276
base.SeqNumMax,
277277
it.opts.LowerBound, it.opts.UpperBound,
278278
&it.hasPrefix, &it.prefixOrFullSeekKey,
@@ -284,7 +284,7 @@ func finishInitializingExternal(ctx context.Context, it *Iterator) error {
284284
}
285285
}
286286
if it.rangeKey != nil {
287-
it.rangeKey.iiter.Init(&it.comparer, it.iter, it.rangeKey.rangeKeyIter,
287+
it.rangeKey.iiter.Init(it.comparer, it.iter, it.rangeKey.rangeKeyIter,
288288
keyspan.InterleavingIterOpts{
289289
Mask: &it.rangeKeyMasking,
290290
LowerBound: it.opts.LowerBound,

get.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (d *DB) getInternal(key []byte, b *Batch, s *Snapshot) ([]byte, io.Closer,
115115
iter: pointIter,
116116
pointIter: pointIter,
117117
merge: d.merge,
118-
comparer: *d.opts.Comparer,
118+
comparer: d.opts.Comparer,
119119
readState: readState,
120120
keyBuf: buf.keyBuf,
121121
}

get_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ func TestGetIter(t *testing.T) {
462462
}
463463

464464
i := &buf.dbi
465-
i.comparer = *testkeys.Comparer
465+
i.comparer = testkeys.Comparer
466466
i.merge = DefaultMerger.Merge
467467
i.iter = get
468468

iterator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ type Iterator struct {
201201
ctx context.Context
202202
opts IterOptions
203203
merge Merge
204-
comparer base.Comparer
204+
comparer *base.Comparer
205205
iter internalIterator
206206
pointIter topLevelIterator
207207
// Either readState or version is set, but not both.

iterator_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ func TestIterator(t *testing.T) {
182182
}
183183
it := &Iterator{
184184
opts: opts,
185-
comparer: *testkeys.Comparer,
185+
comparer: testkeys.Comparer,
186186
merge: wrappedMerge,
187187
}
188188
// NB: Use a mergingIter to filter entries newer than seqNum.
@@ -854,7 +854,7 @@ func TestIteratorSeekOptErrors(t *testing.T) {
854854
// with a readState. It suffices for this test.
855855
return &Iterator{
856856
opts: opts,
857-
comparer: *testkeys.Comparer,
857+
comparer: testkeys.Comparer,
858858
merge: DefaultMerger.Merge,
859859
iter: &errorIter,
860860
}
@@ -1644,7 +1644,7 @@ func newPointTestkeysDatabase(t *testing.T, ks testkeys.Keyspace) *DB {
16441644
func BenchmarkIteratorSeekGE(b *testing.B) {
16451645
m, keys := buildMemTable(b)
16461646
iter := &Iterator{
1647-
comparer: *DefaultComparer,
1647+
comparer: DefaultComparer,
16481648
iter: m.newIter(nil),
16491649
}
16501650
rng := rand.New(rand.NewPCG(0, uint64(time.Now().UnixNano())))
@@ -1659,7 +1659,7 @@ func BenchmarkIteratorSeekGE(b *testing.B) {
16591659
func BenchmarkIteratorNext(b *testing.B) {
16601660
m, _ := buildMemTable(b)
16611661
iter := &Iterator{
1662-
comparer: *DefaultComparer,
1662+
comparer: DefaultComparer,
16631663
iter: m.newIter(nil),
16641664
}
16651665

@@ -1675,7 +1675,7 @@ func BenchmarkIteratorNext(b *testing.B) {
16751675
func BenchmarkIteratorPrev(b *testing.B) {
16761676
m, _ := buildMemTable(b)
16771677
iter := &Iterator{
1678-
comparer: *DefaultComparer,
1678+
comparer: DefaultComparer,
16791679
iter: m.newIter(nil),
16801680
}
16811681

@@ -1793,7 +1793,7 @@ func BenchmarkIteratorSeqSeekPrefixGENotFound(b *testing.B) {
17931793
levelSlices := levelSlices[index]
17941794
m := buildMergingIter(readers, levelSlices)
17951795
iter := Iterator{
1796-
comparer: *testkeys.Comparer,
1796+
comparer: testkeys.Comparer,
17971797
merge: DefaultMerger.Merge,
17981798
iter: m,
17991799
}
@@ -1858,7 +1858,7 @@ func BenchmarkIteratorSeqSeekPrefixGEFound(b *testing.B) {
18581858
levelSlices := levelSlices[index]
18591859
m := buildMergingIter(readers, levelSlices)
18601860
iter := Iterator{
1861-
comparer: *testkeys.Comparer,
1861+
comparer: testkeys.Comparer,
18621862
merge: DefaultMerger.Merge,
18631863
iter: m,
18641864
}
@@ -1911,7 +1911,7 @@ func BenchmarkIteratorSeqSeekGEWithBounds(b *testing.B) {
19111911
false, false, twoLevelIndex)
19121912
m := buildMergingIter(readers, levelSlices)
19131913
iter := Iterator{
1914-
comparer: *testkeys.Comparer,
1914+
comparer: testkeys.Comparer,
19151915
merge: DefaultMerger.Merge,
19161916
iter: m,
19171917
}
@@ -1959,7 +1959,7 @@ func BenchmarkIteratorSeekGENoop(b *testing.B) {
19591959
b.Run(fmt.Sprintf("withLimit=%t", withLimit), func(b *testing.B) {
19601960
m := buildMergingIter(readers, levelSlices)
19611961
iter := Iterator{
1962-
comparer: *testkeys.Comparer,
1962+
comparer: testkeys.Comparer,
19631963
merge: DefaultMerger.Merge,
19641964
iter: m,
19651965
}

range_keys.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
// i.rangeKey.rangeKeyIter with the resulting iterator.
2121
func (i *Iterator) constructRangeKeyIter() {
2222
i.rangeKey.rangeKeyIter = i.rangeKey.iterConfig.Init(
23-
&i.comparer, i.seqNum, i.opts.LowerBound, i.opts.UpperBound,
23+
i.comparer, i.seqNum, i.opts.LowerBound, i.opts.UpperBound,
2424
&i.hasPrefix, &i.prefixOrFullSeekKey, false /* internalKeys */, &i.rangeKey.rangeKeyBuffers.internal)
2525

2626
if i.opts.DebugRangeKeyStack {
@@ -562,7 +562,7 @@ func (i *lazyCombinedIter) initCombinedIteration(
562562

563563
// Initialize the Iterator's interleaving iterator.
564564
i.parent.rangeKey.iiter.Init(
565-
&i.parent.comparer, i.parent.pointIter, i.parent.rangeKey.rangeKeyIter,
565+
i.parent.comparer, i.parent.pointIter, i.parent.rangeKey.rangeKeyIter,
566566
keyspan.InterleavingIterOpts{
567567
Mask: &i.parent.rangeKeyMasking,
568568
LowerBound: i.parent.opts.LowerBound,

0 commit comments

Comments
 (0)