1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.codec.prefixtree;
20
21 import java.nio.ByteBuffer;
22
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.Cell;
25 import org.apache.hadoop.hbase.CellUtil;
26 import org.apache.hadoop.hbase.KeyValue;
27 import org.apache.hadoop.hbase.KeyValueUtil;
28 import org.apache.hadoop.hbase.KeyValue.KVComparator;
29 import org.apache.hadoop.hbase.codec.prefixtree.decode.DecoderFactory;
30 import org.apache.hadoop.hbase.codec.prefixtree.decode.PrefixTreeArraySearcher;
31 import org.apache.hadoop.hbase.codec.prefixtree.scanner.CellScannerPosition;
32 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoder.EncodedSeeker;
33
34
35
36
37
38
39
40
41
42 @InterfaceAudience.Private
43 public class PrefixTreeSeeker implements EncodedSeeker {
44
45 protected ByteBuffer block;
46 protected boolean includeMvccVersion;
47 protected PrefixTreeArraySearcher ptSearcher;
48 protected boolean movedToPrevious = false;
49
50 public PrefixTreeSeeker(boolean includeMvccVersion) {
51 this.includeMvccVersion = includeMvccVersion;
52 }
53
54 @Override
55 public void setCurrentBuffer(ByteBuffer fullBlockBuffer) {
56 block = fullBlockBuffer;
57 ptSearcher = DecoderFactory.checkOut(block, includeMvccVersion);
58 rewind();
59 }
60
61
62
63
64
65
66
67 public void releaseCurrentSearcher(){
68 DecoderFactory.checkIn(ptSearcher);
69 }
70
71
72 @Override
73 public ByteBuffer getKeyDeepCopy() {
74 return KeyValueUtil.copyKeyToNewByteBuffer(ptSearcher.current());
75 }
76
77
78 @Override
79 public ByteBuffer getValueShallowCopy() {
80 return CellUtil.getValueBufferShallowCopy(ptSearcher.current());
81 }
82
83
84
85
86 @Override
87 public ByteBuffer getKeyValueBuffer() {
88 return KeyValueUtil.copyToNewByteBuffer(ptSearcher.current());
89 }
90
91
92
93
94 @Override
95 public KeyValue getKeyValue() {
96 if (ptSearcher.current() == null) {
97 return null;
98 }
99 return KeyValueUtil.copyToNewKeyValue(ptSearcher.current());
100 }
101
102
103
104
105
106
107
108
109
110
111
112 public Cell get() {
113 return ptSearcher.current();
114 }
115
116 @Override
117 public void rewind() {
118 ptSearcher.positionAtFirstCell();
119 }
120
121 @Override
122 public boolean next() {
123 boolean advance = ptSearcher.advance();
124 if (ptSearcher.hasMovedToPreviousAsPartOfSeek()) {
125 ptSearcher.setMovedToPreviousAsPartOfSeek(false);
126 }
127 return advance;
128 }
129
130
131 public boolean advance() {
132 return ptSearcher.advance();
133 }
134
135
136 private static final boolean USE_POSITION_BEFORE = false;
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 @Override
156 public int seekToKeyInBlock(byte[] keyOnlyBytes, int offset, int length,
157 boolean forceBeforeOnExactMatch) {
158 if (USE_POSITION_BEFORE) {
159 return seekToOrBeforeUsingPositionAtOrBefore(keyOnlyBytes, offset, length,
160 forceBeforeOnExactMatch);
161 }else{
162 return seekToOrBeforeUsingPositionAtOrAfter(keyOnlyBytes, offset, length,
163 forceBeforeOnExactMatch);
164 }
165 }
166
167
168
169
170
171
172
173
174 protected int seekToOrBeforeUsingPositionAtOrBefore(byte[] keyOnlyBytes, int offset, int length,
175 boolean seekBefore){
176
177 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
178
179 CellScannerPosition position = ptSearcher.seekForwardToOrBefore(kv);
180
181 if(CellScannerPosition.AT == position){
182 if (seekBefore) {
183 ptSearcher.previous();
184 return 1;
185 }
186 return 0;
187 }
188
189 return 1;
190 }
191
192
193 protected int seekToOrBeforeUsingPositionAtOrAfter(byte[] keyOnlyBytes, int offset, int length,
194 boolean seekBefore){
195
196 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
197
198
199 CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv);
200
201 if(CellScannerPosition.AT == position){
202 if (seekBefore) {
203 ptSearcher.previous();
204 return 1;
205 }
206 return 0;
207
208 }
209
210 if(CellScannerPosition.AFTER == position){
211 if(!ptSearcher.isBeforeFirst()){
212 ptSearcher.previous();
213 ptSearcher.setMovedToPreviousAsPartOfSeek(true);
214 }
215 return 1;
216 }
217
218 if(position == CellScannerPosition.AFTER_LAST){
219 if (seekBefore) {
220
221 ptSearcher.previous();
222 }
223 return 1;
224 }
225
226 throw new RuntimeException("unexpected CellScannerPosition:"+position);
227 }
228
229 @Override
230 public int compareKey(KVComparator comparator, byte[] key, int offset, int length) {
231
232 ByteBuffer bb = getKeyDeepCopy();
233 return comparator.compareFlatKey(key, offset, length, bb.array(), bb.arrayOffset(), bb.limit());
234 }
235 }