@@ -34,6 +34,14 @@ class Block(val data: Array[Byte], val offsets: Array[Int]) {
34
34
buffer.appendAll(intLow2Bytes(offsets.length))
35
35
buffer.toArray
36
36
}
37
+
38
+ def getFirstKey (): MemTableKey = {
39
+ val buffer = ByteArrayReader (data)
40
+ val overlapLen = buffer.readUint16()
41
+ assert(overlapLen == 0 )
42
+ val keyLen = buffer.readUint16()
43
+ buffer.readBytes(keyLen)
44
+ }
37
45
}
38
46
39
47
object Block {
@@ -80,10 +88,16 @@ class BlockBuilder(val blockSize: Int) {
80
88
// 显然,新数据的offset就是当前data长度
81
89
offsets += data.length
82
90
83
- // key的长度
84
- data.appendAll(intLow2Bytes(key.length))
91
+ // overlap 格式
92
+ // key_overlap_len (u16) | rest_key_len (u16) | key (rest_key_len)
93
+ // 当前key与firstKey的共同前缀byte数量
94
+ val overlap = commonPrefix(key)
95
+ // key_overlap_len
96
+ data.appendAll(intLow2Bytes(overlap))
97
+ // rest_key_len (u16)
98
+ data.appendAll(intLow2Bytes(key.length - overlap))
85
99
// key内容
86
- data.appendAll(key)
100
+ data.appendAll(key.slice(overlap, key.length) )
87
101
// value的长度
88
102
data.appendAll(intLow2Bytes(value.length))
89
103
// value内容
@@ -95,6 +109,20 @@ class BlockBuilder(val blockSize: Int) {
95
109
true
96
110
}
97
111
112
+ /**
113
+ * @param key 指定key
114
+ * @return 指定key与 firstKey 有多少个相同的前缀byte
115
+ */
116
+ private def commonPrefix (key : MemTableKey ): Int = {
117
+ if (firstKey.isEmpty) {
118
+ return 0
119
+ }
120
+ var index = 0
121
+ while (index < firstKey.get.length && index < key.length && firstKey.get(index) == key(index)) {
122
+ index += 1
123
+ }
124
+ index
125
+ }
98
126
99
127
/**
100
128
* @return 按data和offsets估算的体积
@@ -138,6 +166,7 @@ class BlockIterator(block: Block) extends MemTableStorageIterator {
138
166
* 当前value在Block中data的下标
139
167
*/
140
168
private var curValuePos : (Int , Int ) = (0 , 0 )
169
+ private val firstKey = block.getFirstKey()
141
170
142
171
def seekToFirst (): Unit = {
143
172
seekToIndex(0 )
@@ -211,10 +240,12 @@ class BlockIterator(block: Block) extends MemTableStorageIterator {
211
240
212
241
// 根据 offset 段获取entry位置
213
242
val entryOffset = block.offsets(index)
214
- // 先后读取key长度、key、value长度
215
- val keyLength = low2BytesToInt(block.data(entryOffset), block.data(entryOffset + 1 ))
216
- curKey = Some (block.data.slice(entryOffset + 2 , entryOffset + 2 + keyLength))
217
- val valueOffset = entryOffset + 2 + keyLength
243
+ // 先后读取overlap长度、剩余key长度、剩余key、value长度
244
+ val overlapLength = low2BytesToInt(block.data(entryOffset), block.data(entryOffset + 1 ))
245
+ val restKeyLength = low2BytesToInt(block.data(entryOffset + 2 ), block.data(entryOffset + 3 ))
246
+ curKey = Some (firstKey.slice(0 , overlapLength) ++
247
+ block.data.slice(entryOffset + 4 , entryOffset + 4 + restKeyLength))
248
+ val valueOffset = entryOffset + 4 + restKeyLength
218
249
val valueLength = low2BytesToInt(block.data(valueOffset), block.data(valueOffset + 1 ))
219
250
curValuePos = (valueOffset + 2 , valueOffset + 2 + valueLength)
220
251
this .index = index
0 commit comments