Skip to content

Commit f098d82

Browse files
committed
db: fix L0 blob reference depth calculation
Fix the calculation of a compaction's output tables' blob reference depths to take into account that L0 input sstables in different sublevels overlap one another. This commit sums the maximum blob reference depth in each sublevel.
1 parent 06c3d70 commit f098d82

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

testdata/compaction/value_separation

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,65 @@ L0.0:
188188
Blob files:
189189
000006: 51 physical bytes, 5 value bytes
190190

191+
# Construct an initial state with two overlapping files in L0, both with blob
192+
# references. Because these files overlap and are in separate sublevels, a
193+
# compaction that preserves blob references should sum their depths.
194+
195+
define value-separation=(true,1,5) l0-compaction-threshold=2
196+
L0 blob-depth=1
197+
a.SET.9:a
198+
d.SET.9:blob{fileNum=100001 value=d}
199+
L0 blob-depth=3
200+
a.SET.1:a
201+
b.SET.1:blob{fileNum=100002 value=bar}
202+
f.SET.1:blob{fileNum=100003 value=foo}
203+
k.SET.1:k
204+
z.SET.1:blob{fileNum=100004 value=zoo}
205+
----
206+
L0.1:
207+
000004:[a#9,SET-d#9,SET] seqnums:[9-9] points:[a#9,SET-d#9,SET] size:775 blobrefs:[(100001: 1); depth:1]
208+
L0.0:
209+
000005:[a#1,SET-z#1,SET] seqnums:[1-1] points:[a#1,SET-z#1,SET] size:795 blobrefs:[(100002: 3), (100003: 3), (100004: 3); depth:3]
210+
211+
compact a-z
212+
----
213+
L1:
214+
000006:[a#0,SET-z#0,SET] seqnums:[0-0] points:[a#0,SET-z#0,SET] size:819 blobrefs:[(100002: 3), (100001: 1), (100003: 3), (100004: 3); depth:4]
215+
Blob files:
216+
100001: 47 physical bytes, 1 value bytes
217+
100002: 49 physical bytes, 3 value bytes
218+
100003: 49 physical bytes, 3 value bytes
219+
100004: 49 physical bytes, 3 value bytes
220+
221+
# Construct an initial state with two non-overlapping files in L0, both with
222+
# blob references. Because these files do NOT overlap and are in the same
223+
# sublevel, a compaction that preserves blob references should take the MAX of
224+
# their depths.
225+
226+
define value-separation=(true,1,5) l0-compaction-threshold=2
227+
L0 blob-depth=1
228+
a.SET.9:a
229+
d.SET.9:blob{fileNum=100001 value=d}
230+
L0 blob-depth=3
231+
e.SET.1:a
232+
f.SET.1:blob{fileNum=100002 value=bar}
233+
g.SET.1:blob{fileNum=100003 value=foo}
234+
k.SET.1:k
235+
z.SET.1:blob{fileNum=100004 value=zoo}
236+
----
237+
L0.0:
238+
000004:[a#9,SET-d#9,SET] seqnums:[9-9] points:[a#9,SET-d#9,SET] size:775 blobrefs:[(100001: 1); depth:1]
239+
000005:[e#1,SET-z#1,SET] seqnums:[1-1] points:[e#1,SET-z#1,SET] size:795 blobrefs:[(100002: 3), (100003: 3), (100004: 3); depth:3]
240+
241+
compact a-z
242+
----
243+
L1:
244+
000006:[a#0,SET-z#0,SET] seqnums:[0-0] points:[a#0,SET-z#0,SET] size:813 blobrefs:[(100001: 1), (100002: 3), (100003: 3), (100004: 3); depth:3]
245+
Blob files:
246+
100001: 47 physical bytes, 1 value bytes
247+
100002: 49 physical bytes, 3 value bytes
248+
100003: 49 physical bytes, 3 value bytes
249+
100004: 49 physical bytes, 3 value bytes
191250

192251
define value-separation=(true,5,5) l0-compaction-threshold=1
193252
----

value_separation.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,27 @@ func shouldWriteBlobFiles(
105105
// files. In the worst case, these references are evenly distributed across the
106106
// keyspace and there is very little locality.
107107
func compactionBlobReferenceDepth(levels []compactionLevel) manifest.BlobReferenceDepth {
108+
// TODO(jackson): Consider using a range tree to precisely compute the
109+
// depth. This would require maintaining minimum and maximum keys.
108110
var depth manifest.BlobReferenceDepth
109111
for _, level := range levels {
112+
// L0 allows files to overlap one another, so it's not sufficient to
113+
// just take the maximum within the level. Instead, we need to sum the
114+
// max of each sublevel.
115+
//
116+
// TODO(jackson): This and other compaction logic would likely be
117+
// cleaner if we modeled each sublevel as its own `compactionLevel`.
118+
if level.level == 0 {
119+
for _, sublevel := range level.l0SublevelInfo {
120+
var sublevelDepth int
121+
for t := range sublevel.LevelSlice.All() {
122+
sublevelDepth = max(sublevelDepth, int(t.BlobReferenceDepth))
123+
}
124+
depth += manifest.BlobReferenceDepth(sublevelDepth)
125+
}
126+
continue
127+
}
128+
110129
var levelDepth manifest.BlobReferenceDepth
111130
for t := range level.files.All() {
112131
levelDepth = max(levelDepth, t.BlobReferenceDepth)

0 commit comments

Comments
 (0)