Skip to content

Commit 4a5d7e3

Browse files
committed
objstorage: fix preallocated handle initialization
We were not initializing the readahead state when using a preallocated handle. We add an assertion that would have failed and improve an existing test to use the preallocated handle sometimes. We also use a preallocated handle for the single level iterator (using it only for the two level was an omission).
1 parent 6b251de commit 4a5d7e3

File tree

5 files changed

+41
-8
lines changed

5 files changed

+41
-8
lines changed

objstorage/objstorageprovider/provider_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,14 @@ func TestProvider(t *testing.T) {
181181
if err != nil {
182182
return err.Error()
183183
}
184-
rh := r.NewReadHandle(ctx)
184+
var rh objstorage.ReadHandle
185+
// Test both ways of getting a handle.
186+
if rand.Intn(2) == 0 {
187+
rh = r.NewReadHandle(ctx)
188+
} else {
189+
var prealloc PreallocatedReadHandle
190+
rh = UsePreallocatedReadHandle(ctx, r, &prealloc)
191+
}
185192
if forCompaction {
186193
rh.SetupForCompaction()
187194
}

objstorage/objstorageprovider/readahead.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
package objstorageprovider
66

7+
import "github.com/cockroachdb/pebble/internal/invariants"
8+
79
const (
810
// Constants for dynamic readahead of data blocks. Note that the size values
911
// make sense as some multiple of the default block size; and they should
@@ -81,6 +83,9 @@ func (rs *readaheadState) recordCacheHit(offset, blockLength int64) {
8183
// Returns a size value (greater than 0) that should be prefetched if readahead
8284
// would be beneficial.
8385
func (rs *readaheadState) maybeReadahead(offset, blockLength int64) int64 {
86+
if invariants.Enabled && rs.maxReadaheadSize == 0 {
87+
panic("readaheadState not initialized")
88+
}
8489
currentReadEnd := offset + blockLength
8590
if rs.numReads >= minFileReadsForReadahead {
8691
// The minimum threshold of sequential reads to justify reading ahead

objstorage/objstorageprovider/testdata/provider/local_readahead

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ create 1 local 1 2000000
1717
<local fs> sync-data: p1/000001.sst
1818
<local fs> close: p1/000001.sst
1919

20-
# We should see prefetch calls, and eventually a reopen
21-
# (with sequential reads option).
20+
# We should see prefetch calls, and eventually a reopen with sequential reads
21+
# option.
2222
read 1
2323
0 1000
2424
1000 15000
@@ -49,3 +49,18 @@ size: 2000000
4949
140000 80000: ok (salt 1)
5050
<local fs> close: p1/000001.sst
5151
<local fs> close: p1/000001.sst
52+
53+
# We should directly see a reopen with sequential reads option.
54+
read 1 for-compaction
55+
0 1000
56+
1000 15000
57+
----
58+
<local fs> open: p1/000001.sst (options: *vfs.randomReadsOption)
59+
<local fs> open: p1/000001.sst (options: *vfs.sequentialReadsOption)
60+
size: 2000000
61+
<local fs> read-at(0, 1000): p1/000001.sst
62+
0 1000: ok (salt 1)
63+
<local fs> read-at(1000, 15000): p1/000001.sst
64+
1000 15000: ok (salt 1)
65+
<local fs> close: p1/000001.sst
66+
<local fs> close: p1/000001.sst

objstorage/objstorageprovider/vfs_readable.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ func (r *fileReadable) Size() int64 {
7676
// NewReadHandle is part of the objstorage.Readable interface.
7777
func (r *fileReadable) NewReadHandle(_ context.Context) objstorage.ReadHandle {
7878
rh := readHandlePool.Get().(*vfsReadHandle)
79-
rh.r = r
80-
rh.rs = makeReadaheadState(fileMaxReadaheadSize)
79+
rh.init(r)
8180
return rh
8281
}
8382

@@ -108,6 +107,13 @@ var readHandlePool = sync.Pool{
108107
},
109108
}
110109

110+
func (rh *vfsReadHandle) init(r *fileReadable) {
111+
*rh = vfsReadHandle{
112+
r: r,
113+
rs: makeReadaheadState(fileMaxReadaheadSize),
114+
}
115+
}
116+
111117
// Close is part of the objstorage.ReadHandle interface.
112118
func (rh *vfsReadHandle) Close() error {
113119
var err error
@@ -208,8 +214,7 @@ func UsePreallocatedReadHandle(
208214
ctx context.Context, readable objstorage.Readable, rh *PreallocatedReadHandle,
209215
) objstorage.ReadHandle {
210216
if r, ok := readable.(*fileReadable); ok {
211-
// See fileReadable.NewReadHandle.
212-
rh.vfsReadHandle = vfsReadHandle{r: r}
217+
rh.init(r)
213218
return rh
214219
}
215220
return readable.NewReadHandle(ctx)

sstable/reader_iter_two_lvl.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010

1111
"github.com/cockroachdb/pebble/internal/base"
12+
"github.com/cockroachdb/pebble/objstorage/objstorageprovider"
1213
"github.com/cockroachdb/pebble/objstorage/objstorageprovider/objiotracing"
1314
)
1415

@@ -177,7 +178,7 @@ func (i *twoLevelIterator) init(
177178
_ = i.topLevelIndex.Close()
178179
return err
179180
}
180-
i.dataRH = r.readable.NewReadHandle(ctx)
181+
i.dataRH = objstorageprovider.UsePreallocatedReadHandle(ctx, r.readable, &i.dataRHPrealloc)
181182
if r.tableFormat >= TableFormatPebblev3 {
182183
if r.Properties.NumValueBlocks > 0 {
183184
i.vbReader = &valueBlockReader{

0 commit comments

Comments
 (0)