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.codec.prefixtree.decode.DecoderFactory;
29 import org.apache.hadoop.hbase.codec.prefixtree.decode.PrefixTreeArraySearcher;
30 import org.apache.hadoop.hbase.codec.prefixtree.scanner.CellScannerPosition;
31 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoder.EncodedSeeker;
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 KeyValueUtil.copyKeyToNewByteBuffer(ptSearcher.current());
73 }
74
75
76 @Override
77 public ByteBuffer getValueShallowCopy() {
78 return CellUtil.getValueBufferShallowCopy(ptSearcher.current());
79 }
80
81
82
83
84 @Override
85 public ByteBuffer getKeyValueBuffer() {
86 return KeyValueUtil.copyToNewByteBuffer(ptSearcher.current());
87 }
88
89
90
91
92 @Override
93 public KeyValue getKeyValue() {
94 return KeyValueUtil.copyToNewKeyValue(ptSearcher.current());
95 }
96
97
98
99
100
101
102
103
104
105
106
107 public Cell get() {
108 return ptSearcher.current();
109 }
110
111 @Override
112 public void rewind() {
113 ptSearcher.positionAtFirstCell();
114 }
115
116 @Override
117 public boolean next() {
118 return ptSearcher.advance();
119 }
120
121
122 public boolean advance() {
123 return ptSearcher.advance();
124 }
125
126
127 private static final boolean USE_POSITION_BEFORE = false;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 @Override
147 public int seekToKeyInBlock(byte[] keyOnlyBytes, int offset, int length,
148 boolean forceBeforeOnExactMatch) {
149 if (USE_POSITION_BEFORE) {
150 return seekToOrBeforeUsingPositionAtOrBefore(keyOnlyBytes, offset, length,
151 forceBeforeOnExactMatch);
152 }else{
153 return seekToOrBeforeUsingPositionAtOrAfter(keyOnlyBytes, offset, length,
154 forceBeforeOnExactMatch);
155 }
156 }
157
158
159
160
161
162
163
164
165 protected int seekToOrBeforeUsingPositionAtOrBefore(byte[] keyOnlyBytes, int offset, int length,
166 boolean forceBeforeOnExactMatch){
167
168 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
169
170 CellScannerPosition position = ptSearcher.seekForwardToOrBefore(kv);
171
172 if(CellScannerPosition.AT == position){
173 if (forceBeforeOnExactMatch) {
174 ptSearcher.previous();
175 return 1;
176 }
177 return 0;
178 }
179
180 return 1;
181 }
182
183
184 protected int seekToOrBeforeUsingPositionAtOrAfter(byte[] keyOnlyBytes, int offset, int length,
185 boolean forceBeforeOnExactMatch){
186
187 KeyValue kv = KeyValue.createKeyValueFromKey(keyOnlyBytes, offset, length);
188
189
190 CellScannerPosition position = ptSearcher.seekForwardToOrAfter(kv);
191
192 if(CellScannerPosition.AT == position){
193 if (forceBeforeOnExactMatch) {
194 ptSearcher.previous();
195 return 1;
196 }
197 return 0;
198
199 }
200
201 if(CellScannerPosition.AFTER == position){
202 if(!ptSearcher.isBeforeFirst()){
203 ptSearcher.previous();
204 }
205 return 1;
206 }
207
208 if(position == CellScannerPosition.AFTER_LAST){
209 return 1;
210 }
211
212 throw new RuntimeException("unexpected CellScannerPosition:"+position);
213 }
214
215 }