Skip to content

Commit

Permalink
Merge #97668
Browse files Browse the repository at this point in the history
97668: storage: reduce intent interleaving allocations r=sumeerbhola a=jbowens

When seeking to a specific version, the intent interleaving iterator may need to construct the immediate successor next key to serve as a seek key within the lock table. The roachpb.NextKey method avoids allocations when its receiver's underlying slice already contains a trailing zero byte after the key. In all other cases, it must allocate and copy the receiver slice. In the context of the intent interleaving iterator, this is unnecessary. The intent interleaving iterator only temporarily needs to compute the next key for the purpose of constructing a lock-table seek key. Also, the intent interleaving iterator has a buffer available for constructing intent seek keys.

This commit adds a new keys.LockTableSingleNextKey function that behaves identically to `keys.LockTableSingleKey(key.Next(), buf)` but avoids the intermediary step of materializing the next key.

MVCC garbage collection may seek to a specific version, so the removal of this allocation and key copy is visible on the MVCCGarbageCollect microbenchmark.

```
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=true-24          1.070 ±   ∞ ¹    1.070 ±   1%          ~ (p=0.768 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=false-24       1.097 ±  3%      1.120 ±    ∞ ¹        ~ (p=0.286 n=6+1)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=false-24               4.974µ ±   ∞ ¹   4.790µ ±   1%     -3.70% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=true-24                5.377µ ±   ∞ ¹   4.882µ ±   2%     -9.22% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=false-24               7.648µ ±   ∞ ¹   7.399µ ±   1%     -3.26% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=true-24        1.090 ±  6%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=true-24                8.615µ ±   ∞ ¹   8.271µ ±   2%     -4.00% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=false-24               8.249µ ±   ∞ ¹   7.925µ ±   2%     -3.93% (p=0.008 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=false-24        1.021 ± 48%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=true-24                9.208µ ±   ∞ ¹   8.860µ ±   1%     -3.78% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=true-24         1.023 ± 50%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=false-24            8.699µ ±   ∞ ¹   8.389µ ±   3%     -3.57% (p=0.028 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=true-24             9.266µ ±   ∞ ¹   8.528µ ±   5%     -7.96% (p=0.013 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=false-24        1.112 ±  3%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=false-24            13.02µ ±   ∞ ¹   12.15µ ±   2%     -6.70% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=true-24         1.096 ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=true-24             13.49µ ±   ∞ ¹   12.76µ ±   3%     -5.38% (p=0.019 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=false-24          48.72µ ±   ∞ ¹   47.08µ ±   2%     -3.37% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=false-24      1.125 ±  7%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=true-24           57.19µ ±   ∞ ¹   54.01µ ±   2%     -5.56% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=false-24           13.97µ ±   ∞ ¹   13.21µ ±   2%          ~ (p=0.099 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=true-24       1.124 ±  4%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=true-24            15.22µ ±   ∞ ¹   14.67µ ±   1%     -3.58% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=false-24           18.44µ ±   ∞ ¹   17.91µ ±   2%          ~ (p=0.165 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=false-24       1.077 ±  9%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=true-24            21.51µ ±   ∞ ¹   20.70µ ±   1%     -3.76% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=true-24        1.058 ±  4%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=false-24         56.21µ ±   ∞ ¹   53.02µ ±   2%     -5.67% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=false-24       1.161 ±  7%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=true-24          66.05µ ±   ∞ ¹   62.73µ ±   2%     -5.04% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=true-24        1.155 ±  4%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=false-24           19.37µ ±   ∞ ¹   18.38µ ±   2%     -5.12% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=true-24            21.58µ ±   ∞ ¹   21.12µ ±   1%     -2.14% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=false-24           24.83µ ±   ∞ ¹   23.84µ ±   2%     -3.96% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=false-24     1.143 ±  8%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=true-24            29.28µ ±   ∞ ¹   28.70µ ±   1%     -2.00% (p=0.003 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=false-24         62.35µ ±   ∞ ¹   58.89µ ±   1%     -5.54% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=true-24      1.188 ±  8%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=false-24       1.057 ±  5%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=true-24          76.47µ ±   ∞ ¹   72.01µ ±   1%     -5.84% (p=0.019 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=true-24        1.075 ±  4%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=false-24          172.4µ ±   ∞ ¹   169.8µ ±   1%     -1.51% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=false-24       1.172 ±  7%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=true-24           215.9µ ±   ∞ ¹   211.7µ ±   1%     -1.94% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=false-24          208.5µ ±   ∞ ¹   202.8µ ±   1%     -2.69% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=true-24        1.148 ±  7%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=true-24           271.8µ ±   ∞ ¹   266.5µ ±   1%     -1.94% (p=0.008 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=false-24        249.6µ ±   ∞ ¹   243.7µ ±   1%          ~ (p=0.165 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=false-24     1.137 ± 11%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=true-24         331.4µ ±   ∞ ¹   329.1µ ±   0%     -0.69% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=false-24         332.7µ ±   ∞ ¹   329.6µ ±   2%          ~ (p=0.055 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=true-24          417.0µ ±   ∞ ¹   411.7µ ±   1%     -1.26% (p=0.003 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=true-24      1.098 ± 12%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=false-24         396.5µ ±   ∞ ¹   393.7µ ±   0%          ~ (p=0.055 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=true-24          526.4µ ±   ∞ ¹   523.8µ ±   1%          ~ (p=0.099 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=false-24       439.7µ ±   ∞ ¹   434.0µ ±   2%     -1.29% (p=0.019 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=true-24        597.9µ ±   ∞ ¹   592.1µ ±   1%     -0.98% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=false-24         331.7µ ±   ∞ ¹   327.5µ ±   1%     -1.25% (p=0.019 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=true-24          415.3µ ±   ∞ ¹   413.1µ ±   1%          ~ (p=0.099 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=false-24         397.1µ ±   ∞ ¹   392.4µ ±   1%     -1.17% (p=0.003 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=true-24          528.8µ ±   ∞ ¹   520.0µ ±   1%     -1.66% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=false-24       440.6µ ±   ∞ ¹   433.9µ ±   0%     -1.52% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=true-24        596.3µ ±   ∞ ¹   593.4µ ±   0%     -0.48% (p=0.008 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=false-24            1.754m ±   ∞ ¹   1.762m ±   1%          ~ (p=0.254 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=true-24             1.858m ±   ∞ ¹   1.826m ±   1%          ~ (p=0.099 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=false-24            2.510m ±   ∞ ¹   2.516m ±   2%          ~ (p=0.513 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=true-24             2.714m ±   ∞ ¹   2.723m ±   1%          ~ (p=0.371 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=false-24            2.563m ±   ∞ ¹   2.545m ±   2%          ~ (p=0.679 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=true-24             2.713m ±   ∞ ¹   2.758m ±   1%     +1.67% (p=0.040 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=false-24         87.58m ±   ∞ ¹   89.34m ± 181%          ~ (p=0.513 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=true-24          503.6m ±   ∞ ¹   333.8m ± 204%          ~ (p=1.000 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=false-24          1.040 ±   ∞ ¹    1.065 ±   2%          ~ (p=0.055 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=true-24           1.049 ±   ∞ ¹    1.064 ±   1%          ~ (p=0.075 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=false-24        1.062 ±   ∞ ¹    1.065 ±   2%          ~ (p=0.371 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=true-24         1.064 ±   ∞ ¹    1.068 ±   4%          ~ (p=1.000 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=false-24        341.7m ±   ∞ ¹   420.4m ±  40%          ~ (p=0.953 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=true-24        1003.3m ±   ∞ ¹   257.5m ±  96%    -74.33% (p=0.028 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=false-24         1.053 ±   ∞ ¹    1.071 ±   3%          ~ (p=0.165 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=true-24          1.054 ±   ∞ ¹    1.059 ±   1%          ~ (p=0.859 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=false-24       1.074 ±   ∞ ¹    1.074 ±   1%          ~ (p=0.953 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=true-24        1.096 ±   ∞ ¹    1.086 ±   4%          ~ (p=0.206 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=false-24       1011.4m ±   ∞ ¹   506.2m ±  59%    -49.95% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=true-24         510.0m ±   ∞ ¹   505.9m ±  34%          ~ (p=0.254 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=false-24         1.082 ±   ∞ ¹    1.066 ±   2%          ~ (p=0.129 n=5+10)

                                                                                                                                        │   allocs/op    │    allocs/op     vs base                    │
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=true-24        4.662k ±   ∞ ¹   3.618k ±   1%    -22.39% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=false-24     12.95k ±  7%     11.40k ±    ∞ ¹        ~ (p=0.286 n=6+1)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=false-24               8.000 ±   ∞ ¹    8.000 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=true-24                8.000 ±   ∞ ¹    8.000 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=false-24               10.00 ±   ∞ ¹    10.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=true-24      13.12k ±  5%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=true-24                14.00 ±   ∞ ¹    14.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=false-24               10.00 ±   ∞ ¹    10.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=false-24      4.421k ± 37%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=true-24                14.00 ±   ∞ ¹    14.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=true-24       4.427k ± 37%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=false-24            12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=true-24             12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=false-24      4.663k ±  1%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=false-24            14.00 ±   ∞ ¹    13.00 ±   0%     -7.14% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=true-24       4.663k ±  1%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=true-24             18.00 ±   ∞ ¹    17.00 ±   0%     -5.56% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=false-24          23.00 ±   ∞ ¹    22.00 ±   0%     -4.35% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=false-24    12.97k ±  3%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=true-24           27.00 ±   ∞ ¹    26.00 ±   0%     -3.70% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=false-24           12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=true-24     12.70k ±  6%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=true-24            12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=false-24           14.00 ±   ∞ ¹    13.00 ±   0%     -7.14% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=false-24     4.519k ±  8%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=true-24            18.00 ±   ∞ ¹    17.00 ±   0%     -5.56% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=true-24      4.510k ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=false-24         23.00 ±   ∞ ¹    22.00 ±   0%     -4.35% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=false-24     4.738k ±  1%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=true-24          27.00 ±   ∞ ¹    26.00 ±   0%     -3.70% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=true-24      4.729k ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=false-24           12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=true-24            12.00 ±   ∞ ¹    11.00 ±   0%     -8.33% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=false-24           14.00 ±   ∞ ¹    13.00 ±   0%     -7.14% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=false-24   13.00k ±  6%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=true-24            18.00 ±   ∞ ¹    17.00 ±   0%     -5.56% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=false-24         23.00 ±   ∞ ¹    22.00 ±   0%     -4.35% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=true-24    12.92k ±  6%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=false-24     3.466k ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=32/numRangeTs=100/updateStats=true-24          27.00 ±   ∞ ¹    26.00 ±   0%     -3.70% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=true-24      3.514k ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=false-24          13.00 ±   ∞ ¹    12.00 ±   0%     -7.69% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=false-24     3.700k ±  1%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=0/updateStats=true-24           13.00 ±   ∞ ¹    12.00 ±   0%     -7.69% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=false-24          15.00 ±   ∞ ¹    14.00 ±   0%     -6.67% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=true-24      3.704k ±  2%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=1/updateStats=true-24           19.00 ±   ∞ ¹    18.00 ±   0%     -5.26% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=false-24        24.00 ±   ∞ ¹    23.00 ±   0%     -4.17% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=false-24   11.69k ±  6%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=512/numRangeTs=100/updateStats=true-24         28.00 ±   ∞ ¹    27.00 ±   0%     -3.57% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=false-24         13.00 ±   ∞ ¹    12.00 ±   0%     -7.69% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=0/updateStats=true-24          13.00 ±   ∞ ¹    12.00 ±   0%     -7.69% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=true-24    11.78k ±  7%
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=false-24         15.00 ±   ∞ ¹    14.00 ±   0%     -6.67% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=1/updateStats=true-24          19.00 ±   ∞ ¹    18.00 ±   0%     -5.26% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=false-24       23.00 ±   ∞ ¹    22.00 ±   0%     -4.35% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1015/numRangeTs=100/updateStats=true-24        28.00 ±   ∞ ¹    27.00 ±   0%     -3.57% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=false-24         9.000 ±   ∞ ¹    9.000 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=0/updateStats=true-24          9.000 ±   ∞ ¹    9.000 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=false-24         11.00 ±   ∞ ¹    11.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=1/updateStats=true-24          15.00 ±   ∞ ¹    15.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=false-24       19.00 ±   ∞ ¹    19.00 ±   0%          ~ (p=0.527 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1/numVersions=1024/deleteVersions=1023/numRangeTs=100/updateStats=true-24        24.00 ±   ∞ ¹    24.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=false-24            12.00 ±   ∞ ¹    12.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=0/updateStats=true-24             12.00 ±   ∞ ¹    12.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=false-24            15.00 ±   ∞ ¹    15.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=1/updateStats=true-24             19.00 ±   ∞ ¹    19.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=false-24            16.00 ±   ∞ ¹    16.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=2/deleteVersions=1/numRangeTs=2/updateStats=true-24             23.00 ±   ∞ ¹    23.00 ±   0%          ~ (p=1.000 n=5+10) ²
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=false-24        1328.0 ±   ∞ ¹    317.0 ± 174%    -76.13% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=0/updateStats=true-24         2.742k ±   ∞ ¹   1.137k ± 203%          ~ (p=0.055 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=false-24        4.652k ±   ∞ ¹   3.616k ±   1%    -22.27% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=1/updateStats=true-24         4.650k ±   ∞ ¹   3.618k ±   1%    -22.19% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=false-24      13.09k ±   ∞ ¹   11.97k ±   6%     -8.62% (p=0.005 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=1/numRangeTs=100/updateStats=true-24       13.22k ±   ∞ ¹   12.09k ±   3%     -8.56% (p=0.003 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=false-24       2.182k ±   ∞ ¹   1.447k ±  39%    -33.68% (p=0.028 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=0/updateStats=true-24        4422.0 ±   ∞ ¹    872.0 ±  98%    -80.28% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=false-24       4.630k ±   ∞ ¹   3.611k ±   1%    -22.02% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=1/updateStats=true-24        4.638k ±   ∞ ¹   3.634k ±   1%    -21.66% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=false-24     12.80k ±   ∞ ¹   11.94k ±   4%     -6.67% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=16/numRangeTs=100/updateStats=true-24      12.75k ±   ∞ ¹   11.97k ±   3%     -6.08% (p=0.013 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=false-24       4.441k ±   ∞ ¹   1.722k ±  59%    -61.21% (p=0.001 n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=0/updateStats=true-24        2.755k ±   ∞ ¹   1.720k ±  33%    -37.57% (n=5+10)
MVCCGarbageCollect/pebble/keySize=128/valSize=128/numKeys=1024/numVersions=1024/deleteVersions=32/numRangeTs=1/updateStats=false-24       4.663k ±   ∞ ¹   3.616k ±   1%    -22.44% (p=0.001 n=5+10)
```

Informs #97570.
Epic: None
Release note: None

Co-authored-by: Jackson Owens <[email protected]>
  • Loading branch information
craig[bot] and jbowens committed Feb 27, 2023
2 parents 7730070 + 0b2c235 commit c5068fc
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
18 changes: 18 additions & 0 deletions pkg/keys/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,24 @@ func LockTableSingleKey(key roachpb.Key, buf []byte) (roachpb.Key, []byte) {
return buf, buf
}

// LockTableSingleNextKey is equivalent to LockTableSingleKey(key.Next(), buf)
// but avoids an extra allocation in cases where key.Next() must allocate.
func LockTableSingleNextKey(key roachpb.Key, buf []byte) (roachpb.Key, []byte) {
keyLen := len(LocalRangeLockTablePrefix) + len(LockTableSingleKeyInfix) + encoding.EncodeNextBytesSize(key)
if cap(buf) < keyLen {
buf = make([]byte, 0, keyLen)
} else {
buf = buf[:0]
}
// Don't unwrap any local prefix on key using Addr(key). This allow for
// doubly-local lock table keys. For example, local range descriptor keys can
// be locked during split and merge transactions.
buf = append(buf, LocalRangeLockTablePrefix...)
buf = append(buf, LockTableSingleKeyInfix...)
buf = encoding.EncodeNextBytesAscending(buf, key)
return buf, buf
}

// DecodeLockTableSingleKey decodes the single-key lock table key to return the key
// that was locked.
func DecodeLockTableSingleKey(key roachpb.Key) (lockedKey roachpb.Key, err error) {
Expand Down
25 changes: 25 additions & 0 deletions pkg/keys/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,3 +772,28 @@ func TestLockTableKeyEncodeDecode(t *testing.T) {
})
}
}

func TestLockTableSingleKeyNext_Equivalent(t *testing.T) {
testCases := []struct {
key roachpb.Key
}{
{key: roachpb.Key("foo")},
{key: roachpb.Key("a")},
{key: roachpb.Key("")},
// Causes a doubly-local range local key.
{key: RangeDescriptorKey(roachpb.RKey("baz"))},
}
for _, test := range testCases {
t.Run("", func(t *testing.T) {
next := test.key.Next()
want, _ := LockTableSingleKey(next, nil)

got, _ := LockTableSingleNextKey(test.key, nil)
require.Equal(t, want, got)

k, err := DecodeLockTableSingleKey(got)
require.NoError(t, err)
require.Equal(t, next, k)
})
}
}
4 changes: 2 additions & 2 deletions pkg/storage/intent_interleaving_iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ func (i *intentInterleavingIter) SeekGE(key MVCCKey) {
intentSeekKey, i.intentKeyBuf = keys.LockTableSingleKey(key.Key, i.intentKeyBuf)
} else if !i.prefix {
// Seeking to a specific version, so go past the intent.
intentSeekKey, i.intentKeyBuf = keys.LockTableSingleKey(key.Key.Next(), i.intentKeyBuf)
intentSeekKey, i.intentKeyBuf = keys.LockTableSingleNextKey(key.Key, i.intentKeyBuf)
} else {
// Else seeking to a particular version and using prefix iteration,
// so don't expect to ever see the intent. NB: intentSeekKey is nil.
Expand Down Expand Up @@ -1103,7 +1103,7 @@ func (i *intentInterleavingIter) SeekLT(key MVCCKey) {
// Seeking to a specific version, so need to see the intent. Since we need
// to see the intent for key.Key, and we don't have SeekLE, call Next() on
// the key before doing SeekLT.
intentSeekKey, i.intentKeyBuf = keys.LockTableSingleKey(key.Key.Next(), i.intentKeyBuf)
intentSeekKey, i.intentKeyBuf = keys.LockTableSingleNextKey(key.Key, i.intentKeyBuf)
}
var limitKey roachpb.Key
if i.iterValid {
Expand Down
33 changes: 33 additions & 0 deletions pkg/util/encoding/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,23 @@ func EncodeBytesAscending(b []byte, data []byte) []byte {
return encodeBytesAscendingWithTerminatorAndPrefix(b, data, ascendingBytesEscapes.escapedTerm, bytesMarker)
}

// EncodeNextBytesAscending encodes the []byte value with an extra 0x00 byte
// appended before encoding. It's equivalent to
//
// EncodeBytesAscending(b, append(data, 0x00))
//
// but may avoid an allocation when the data slice does not have additional
// capacity.
func EncodeNextBytesAscending(b []byte, data []byte) []byte {
b = append(b, bytesMarker)
return encodeNextBytesAscendingWithTerminator(b, data, ascendingBytesEscapes.escapedTerm)
}

func encodeNextBytesAscendingWithTerminator(b []byte, data []byte, terminator byte) []byte {
bs := encodeBytesAscendingWithoutTerminatorOrPrefix(b, data)
return append(bs, escape, escaped00, escape, terminator)
}

// encodeBytesAscendingWithTerminatorAndPrefix encodes the []byte value using an escape-based
// encoding. The encoded value is terminated with the sequence
// "\x00\terminator". The encoded bytes are append to the supplied buffer
Expand Down Expand Up @@ -676,6 +693,22 @@ func EncodeBytesSize(data []byte) int {
return len(data) + 3 + bytes.Count(data, []byte{escape})
}

// EncodeNextBytesSize returns the size of the []byte value when suffixed with a
// zero byte and then encoded using EncodeNextBytes{Ascending,Descending}. The
// function accounts for the encoding marker, escaping, and the terminator.
func EncodeNextBytesSize(data []byte) int {
// Encoding overhead:
// +1 for [bytesMarker] prefix
// +2 for [escape, escapedTerm] suffix
// +1 for each byte that needs to be escaped
// +2 for the appended 0x00 byte, plus its escaping byte
//
// NOTE: bytes.Count is implemented by the go runtime in assembly and is
// much faster than looping over the bytes in the slice, especially when
// given a single-byte separator.
return len(data) + 5 + bytes.Count(data, []byte{escape})
}

// DecodeBytesAscending decodes a []byte value from the input buffer
// which was encoded using EncodeBytesAscending. The decoded bytes
// are appended to r. The remainder of the input buffer and the
Expand Down
50 changes: 50 additions & 0 deletions pkg/util/encoding/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,56 @@ func TestEncodeDecodeBytesAscending(t *testing.T) {
}
}

func TestEncodeNextBytesAscending_Equivalence(t *testing.T) {
for _, b := range [][]byte{
{0, 1, 'a'},
{0, 'a'},
{0, 0xff, 'a'},
{'a'},
{'b'},
{'b', 0},
{'b', 0, 0},
{'b', 0, 0, 'a'},
{'b', 0xff},
{'h', 'e', 'l', 'l', 'o'},
} {
next := append(b, 0x00)

gotSz := EncodeNextBytesSize(b)
wantSz := EncodeBytesSize(next)
if gotSz != wantSz {
t.Errorf("EncodeNextBytesSize(%q) = %d; want %d", b, gotSz, wantSz)
}
gotV := EncodeNextBytesAscending(nil, b)
wantV := EncodeBytesAscending(nil, next)
if !bytes.Equal(gotV, wantV) {
t.Errorf("EncodeNextBytesAscending(%q) = %q; want %q", b, gotV, wantV)
}
}
}

func TestEncodeNextBytesAscending_Equivalence_Randomized(t *testing.T) {
rnd, _ := randutil.NewTestRand()
var buf [10]byte
var nextBuf [10 + 1]byte
for i := 0; i < 1000; i++ {
b := buf[:randutil.RandIntInRange(rnd, 1, cap(buf))]
randutil.ReadTestdataBytes(rnd, b)
next := append(append(nextBuf[:0], b...), 0x00)

gotSz := EncodeNextBytesSize(b)
wantSz := EncodeBytesSize(next)
if gotSz != wantSz {
t.Errorf("EncodeNextBytesSize(%q) = %d; want %d", b, gotSz, wantSz)
}
gotV := EncodeNextBytesAscending(nil, b)
wantV := EncodeBytesAscending(nil, next)
if !bytes.Equal(gotV, wantV) {
t.Errorf("EncodeNextBytesAscending(%q) = %q; want %q", b, gotV, wantV)
}
}
}

func TestEncodeDecodeBytesDescending(t *testing.T) {
testCases := []struct {
value []byte
Expand Down

0 comments on commit c5068fc

Please sign in to comment.