1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.NavigableSet;
25
26 import org.apache.hadoop.hbase.util.Bytes;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class ExplicitColumnTracker implements ColumnTracker {
48
49 private final int maxVersions;
50 private final List<ColumnCount> columns;
51 private final List<ColumnCount> columnsToReuse;
52 private int index;
53 private ColumnCount column;
54
55
56
57
58
59
60 public ExplicitColumnTracker(NavigableSet<byte[]> columns, int maxVersions) {
61 this.maxVersions = maxVersions;
62 this.columns = new ArrayList<ColumnCount>(columns.size());
63 this.columnsToReuse = new ArrayList<ColumnCount>(columns.size());
64 for(byte [] column : columns) {
65 this.columnsToReuse.add(new ColumnCount(column,maxVersions));
66 }
67 reset();
68 }
69
70
71
72
73 public boolean done() {
74 return this.columns.size() == 0;
75 }
76
77 public ColumnCount getColumnHint() {
78 return this.column;
79 }
80
81
82
83
84
85
86
87
88
89 public ScanQueryMatcher.MatchCode checkColumn(byte [] bytes, int offset, int length) {
90 do {
91
92 if(this.columns.size() == 0) {
93 return ScanQueryMatcher.MatchCode.DONE;
94 }
95
96
97 if(this.column == null) {
98 return ScanQueryMatcher.MatchCode.NEXT;
99 }
100
101
102 int ret = Bytes.compareTo(column.getBuffer(), column.getOffset(),
103 column.getLength(), bytes, offset, length);
104
105
106 if(ret == 0) {
107 if(this.column.decrement() == 0) {
108
109 this.columns.remove(this.index);
110 if(this.columns.size() == this.index) {
111
112 this.column = null;
113 } else {
114 this.column = this.columns.get(this.index);
115 }
116 }
117 return ScanQueryMatcher.MatchCode.INCLUDE;
118 }
119
120
121 if (ret > 0) {
122
123 return ScanQueryMatcher.MatchCode.SKIP;
124 }
125
126
127
128 if(ret <= -1) {
129 if(++this.index == this.columns.size()) {
130
131 return ScanQueryMatcher.MatchCode.NEXT;
132 }
133
134 this.column = this.columns.get(this.index);
135 }
136 } while(true);
137 }
138
139
140
141
142 public void update() {
143 if(this.columns.size() != 0) {
144 this.index = 0;
145 this.column = this.columns.get(this.index);
146 } else {
147 this.index = -1;
148 this.column = null;
149 }
150 }
151
152
153 public void reset() {
154 buildColumnList();
155 this.index = 0;
156 this.column = this.columns.get(this.index);
157 }
158
159 private void buildColumnList() {
160 this.columns.clear();
161 this.columns.addAll(this.columnsToReuse);
162 for(ColumnCount col : this.columns) {
163 col.setCount(this.maxVersions);
164 }
165 }
166
167
168
169
170
171
172
173
174
175
176 public void doneWithColumn(byte [] bytes, int offset, int length) {
177 while (this.column != null) {
178 int compare = Bytes.compareTo(column.getBuffer(), column.getOffset(),
179 column.getLength(), bytes, offset, length);
180 if (compare == 0) {
181 this.columns.remove(this.index);
182 if (this.columns.size() == this.index) {
183
184 this.column = null;
185 } else {
186 this.column = this.columns.get(this.index);
187 }
188 return;
189 } else if ( compare <= -1) {
190 if(++this.index != this.columns.size()) {
191 this.column = this.columns.get(this.index);
192 } else {
193 this.column = null;
194 }
195 } else {
196 return;
197 }
198 }
199 }
200
201 }