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