Skip to content

Commit 8c784ec

Browse files
committed
db: consolidate Get code
Consolidate the code related to the implementation Reader.Get into get.go, alongside the getIter implementation.
1 parent 652f61a commit 8c784ec

File tree

3 files changed

+108
-104
lines changed

3 files changed

+108
-104
lines changed

db.go

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -538,110 +538,6 @@ func (d *DB) TestOnlyWaitForCleaning() {
538538
d.cleanupManager.Wait()
539539
}
540540

541-
// Get gets the value for the given key. It returns ErrNotFound if the DB does
542-
// not contain the key.
543-
//
544-
// The caller should not modify the contents of the returned slice, but it is
545-
// safe to modify the contents of the argument after Get returns. The returned
546-
// slice will remain valid until the returned Closer is closed. On success, the
547-
// caller MUST call closer.Close() or a memory leak will occur.
548-
func (d *DB) Get(key []byte) ([]byte, io.Closer, error) {
549-
return d.getInternal(key, nil /* batch */, nil /* snapshot */)
550-
}
551-
552-
type getIterAlloc struct {
553-
dbi Iterator
554-
keyBuf []byte
555-
get getIter
556-
}
557-
558-
var getIterAllocPool = sync.Pool{
559-
New: func() interface{} {
560-
return &getIterAlloc{}
561-
},
562-
}
563-
564-
func (d *DB) getInternal(key []byte, b *Batch, s *Snapshot) ([]byte, io.Closer, error) {
565-
if err := d.closed.Load(); err != nil {
566-
panic(err)
567-
}
568-
569-
// Grab and reference the current readState. This prevents the underlying
570-
// files in the associated version from being deleted if there is a current
571-
// compaction. The readState is unref'd by Iterator.Close().
572-
readState := d.loadReadState()
573-
574-
// Determine the seqnum to read at after grabbing the read state (current and
575-
// memtables) above.
576-
var seqNum base.SeqNum
577-
if s != nil {
578-
seqNum = s.seqNum
579-
} else {
580-
seqNum = d.mu.versions.visibleSeqNum.Load()
581-
}
582-
583-
buf := getIterAllocPool.Get().(*getIterAlloc)
584-
585-
get := &buf.get
586-
*get = getIter{
587-
comparer: d.opts.Comparer,
588-
newIters: d.newIters,
589-
snapshot: seqNum,
590-
iterOpts: IterOptions{
591-
// TODO(sumeer): replace with a parameter provided by the caller.
592-
Category: categoryGet,
593-
logger: d.opts.Logger,
594-
snapshotForHideObsoletePoints: seqNum,
595-
},
596-
key: key,
597-
// Compute the key prefix for bloom filtering.
598-
prefix: key[:d.opts.Comparer.Split(key)],
599-
batch: b,
600-
mem: readState.memtables,
601-
l0: readState.current.L0SublevelFiles,
602-
version: readState.current,
603-
}
604-
605-
// Strip off memtables which cannot possibly contain the seqNum being read
606-
// at.
607-
for len(get.mem) > 0 {
608-
n := len(get.mem)
609-
if logSeqNum := get.mem[n-1].logSeqNum; logSeqNum < seqNum {
610-
break
611-
}
612-
get.mem = get.mem[:n-1]
613-
}
614-
615-
i := &buf.dbi
616-
pointIter := get
617-
*i = Iterator{
618-
ctx: context.Background(),
619-
getIterAlloc: buf,
620-
iter: pointIter,
621-
pointIter: pointIter,
622-
merge: d.merge,
623-
comparer: *d.opts.Comparer,
624-
readState: readState,
625-
keyBuf: buf.keyBuf,
626-
}
627-
// Set up a blob value fetcher to use for retrieving values from blob files.
628-
i.blobValueFetcher.Init(&readState.current.BlobFiles, d.fileCache, block.NoReadEnv)
629-
get.iiopts.blobValueFetcher = &i.blobValueFetcher
630-
631-
if !i.First() {
632-
err := i.Close()
633-
if err != nil {
634-
return nil, nil, err
635-
}
636-
return nil, nil, ErrNotFound
637-
}
638-
val, err := i.ValueAndErr()
639-
if err != nil {
640-
return nil, nil, errors.CombineErrors(err, i.Close())
641-
}
642-
return val, i, nil
643-
}
644-
645541
// Set sets the value for the given key. It overwrites any previous value
646542
// for that key; a DB is not a multi-map.
647543
//

get_iter.go renamed to get.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,121 @@ package pebble
77
import (
88
"context"
99
"fmt"
10+
"io"
11+
"sync"
1012

13+
"github.com/cockroachdb/errors"
1114
"github.com/cockroachdb/pebble/internal/base"
1215
"github.com/cockroachdb/pebble/internal/keyspan"
1316
"github.com/cockroachdb/pebble/internal/manifest"
1417
"github.com/cockroachdb/pebble/internal/treeprinter"
18+
"github.com/cockroachdb/pebble/sstable/block"
1519
)
1620

21+
// Get gets the value for the given key. It returns ErrNotFound if the DB does
22+
// not contain the key.
23+
//
24+
// The caller should not modify the contents of the returned slice, but it is
25+
// safe to modify the contents of the argument after Get returns. The returned
26+
// slice will remain valid until the returned Closer is closed. On success, the
27+
// caller MUST call closer.Close() or a memory leak will occur.
28+
func (d *DB) Get(key []byte) ([]byte, io.Closer, error) {
29+
return d.getInternal(key, nil /* batch */, nil /* snapshot */)
30+
}
31+
32+
type getIterAlloc struct {
33+
dbi Iterator
34+
keyBuf []byte
35+
get getIter
36+
}
37+
38+
var getIterAllocPool = sync.Pool{
39+
New: func() interface{} {
40+
return &getIterAlloc{}
41+
},
42+
}
43+
44+
func (d *DB) getInternal(key []byte, b *Batch, s *Snapshot) ([]byte, io.Closer, error) {
45+
if err := d.closed.Load(); err != nil {
46+
panic(err)
47+
}
48+
49+
// Grab and reference the current readState. This prevents the underlying
50+
// files in the associated version from being deleted if there is a current
51+
// compaction. The readState is unref'd by Iterator.Close().
52+
readState := d.loadReadState()
53+
54+
// Determine the seqnum to read at after grabbing the read state (current and
55+
// memtables) above.
56+
var seqNum base.SeqNum
57+
if s != nil {
58+
seqNum = s.seqNum
59+
} else {
60+
seqNum = d.mu.versions.visibleSeqNum.Load()
61+
}
62+
63+
buf := getIterAllocPool.Get().(*getIterAlloc)
64+
65+
get := &buf.get
66+
*get = getIter{
67+
comparer: d.opts.Comparer,
68+
newIters: d.newIters,
69+
snapshot: seqNum,
70+
iterOpts: IterOptions{
71+
// TODO(sumeer): replace with a parameter provided by the caller.
72+
Category: categoryGet,
73+
logger: d.opts.Logger,
74+
snapshotForHideObsoletePoints: seqNum,
75+
},
76+
key: key,
77+
// Compute the key prefix for bloom filtering.
78+
prefix: key[:d.opts.Comparer.Split(key)],
79+
batch: b,
80+
mem: readState.memtables,
81+
l0: readState.current.L0SublevelFiles,
82+
version: readState.current,
83+
}
84+
85+
// Strip off memtables which cannot possibly contain the seqNum being read
86+
// at.
87+
for len(get.mem) > 0 {
88+
n := len(get.mem)
89+
if logSeqNum := get.mem[n-1].logSeqNum; logSeqNum < seqNum {
90+
break
91+
}
92+
get.mem = get.mem[:n-1]
93+
}
94+
95+
i := &buf.dbi
96+
pointIter := get
97+
*i = Iterator{
98+
ctx: context.Background(),
99+
getIterAlloc: buf,
100+
iter: pointIter,
101+
pointIter: pointIter,
102+
merge: d.merge,
103+
comparer: *d.opts.Comparer,
104+
readState: readState,
105+
keyBuf: buf.keyBuf,
106+
}
107+
// Set up a blob value fetcher to use for retrieving values from blob files.
108+
i.blobValueFetcher.Init(&readState.current.BlobFiles, d.fileCache, block.NoReadEnv)
109+
get.iiopts.blobValueFetcher = &i.blobValueFetcher
110+
111+
if !i.First() {
112+
err := i.Close()
113+
if err != nil {
114+
return nil, nil, err
115+
}
116+
return nil, nil, ErrNotFound
117+
}
118+
val, err := i.ValueAndErr()
119+
if err != nil {
120+
return nil, nil, errors.CombineErrors(err, i.Close())
121+
}
122+
return val, i, nil
123+
}
124+
17125
// getIter is an internal iterator used to perform gets. It iterates through
18126
// the values for a particular key, level by level. It is not a general purpose
19127
// internalIterator, but specialized for Get operations so that it loads data
File renamed without changes.

0 commit comments

Comments
 (0)