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.hbase.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 KeyValue getKeyValue() {
88 if (ptSearcher.current() == null) {
89 return null;
90 }
91 return KeyValueUtil.copyToNewKeyValue(ptSearcher.current());
92 }
93
94
95
96
97
98
99
100
101
102
103
104 public Cell get() {
105 return ptSearcher.current();
106 }
107
108 @Override
109 public void rewind() {
110 ptSearcher.positionAtFirstCell();
111 }
112
113 @Override
114 public boolean next() {
115 return ptSearcher.advance();
116 }
117
118 public boolean advance() {
119 return ptSearcher.advance();
120 }
121
122
123 private static final boolean USE_POSITION_BEFORE = false;
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 @Override
143 public int seekToKeyInBlock(byte[] keyOnlyBytes, int offset, int length,
144 boolean forceBeforeOnExactMatch) {
145 if (USE_POSITION_BEFORE) {
146 return seekToOrBeforeUsingPositionAtOrBefore(keyOnlyBytes, offset, length,
147 forceBeforeOnExactMatch);
148 }else{
149 return seekToOrBeforeUsingPositionAtOrAfter(keyOnlyBytes, offset, length,
150 forceBeforeOnExactMatch);
151 }
152 }
153
154
155
156
157
158
159
160
161 protected int seekToOrBeforeUsingPositionAtOrBefore(byte[] keyOnlyBytes, int offset, int length,
162 boolean seekBefore){
163
164 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
165
166 CellScannerPosition position = ptSearcher.seekForwardToOrBefore(kv);
167
168 if(CellScannerPosition.AT == position){
169 if (seekBefore) {
170 ptSearcher.previous();
171 return 1;
172 }
173 return 0;
174 }
175
176 return 1;
177 }
178
179
180 protected int seekToOrBeforeUsingPositionAtOrAfter(byte[] keyOnlyBytes, int offset, int length,
181 boolean seekBefore){
182
183 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
184
185
186 CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv);
187
188 if(CellScannerPosition.AT == position){
189 if (seekBefore) {
190 ptSearcher.previous();
191 return 1;
192 }
193 return 0;
194
195 }
196
197 if(CellScannerPosition.AFTER == position){
198 if(!ptSearcher.isBeforeFirst()){
199 ptSearcher.previous();
200 }
201 return 1;
202 }
203
204 if(position == CellScannerPosition.AFTER_LAST){
205 if (seekBefore) {
206
207 ptSearcher.previous();
208 }
209 return 1;
210 }
211
212 throw new RuntimeException("unexpected CellScannerPosition:"+position);
213 }
214
215 @Override
216 public int compareKey(KVComparator comparator, byte[] key, int offset, int length) {
217
218 ByteBuffer bb = getKeyDeepCopy();
219 return comparator.compareFlatKey(key, offset, length, bb.array(), bb.arrayOffset(), bb.limit());
220 }
221 }