1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.apache.hadoop.hbase.client.ConnectionUtils.filterCells;
21
22 import java.io.IOException;
23 import java.util.ArrayDeque;
24 import java.util.Deque;
25 import java.util.List;
26
27 import org.apache.hadoop.hbase.Cell;
28 import org.apache.hadoop.hbase.CellUtil;
29 import org.apache.hadoop.hbase.classification.InterfaceAudience;
30 import org.apache.hadoop.hbase.util.Bytes;
31
32
33
34
35
36
37
38
39 @InterfaceAudience.Private
40 public class BatchScanResultCache extends ScanResultCache {
41
42 private final int batch;
43
44
45
46 private Cell lastCell;
47
48 private boolean lastResultPartial;
49
50 private final Deque<Result> partialResults = new ArrayDeque<>();
51
52 private int numCellsOfPartialResults;
53
54 public BatchScanResultCache(List<Result> cache, int batch) {
55 super(cache);
56 this.batch = batch;
57 }
58
59 private void recordLastResult(Result result) {
60 lastCell = result.rawCells()[result.rawCells().length - 1];
61 lastResultPartial = result.mayHaveMoreCellsInRow();
62 }
63
64 private Result createCompletedResult() throws IOException {
65 numberOfCompleteRows++;
66 Result result = Result.createCompleteResult(partialResults);
67 partialResults.clear();
68 numCellsOfPartialResults = 0;
69 return result;
70 }
71
72
73
74
75 private Result regroupResults(Result result) {
76 partialResults.addLast(result);
77 numCellsOfPartialResults += result.size();
78 if (numCellsOfPartialResults < batch) {
79 return null;
80 }
81 Cell[] cells = new Cell[batch];
82 int cellCount = 0;
83 boolean stale = false;
84 for (;;) {
85 Result r = partialResults.pollFirst();
86 stale = stale || r.isStale();
87 int newCellCount = cellCount + r.size();
88 if (newCellCount > batch) {
89
90 int len = batch - cellCount;
91 System.arraycopy(r.rawCells(), 0, cells, cellCount, len);
92 Cell[] remainingCells = new Cell[r.size() - len];
93 System.arraycopy(r.rawCells(), len, remainingCells, 0, r.size() - len);
94 partialResults.addFirst(
95 Result.create(remainingCells, r.getExists(), r.isStale(), r.mayHaveMoreCellsInRow()));
96 break;
97 }
98 System.arraycopy(r.rawCells(), 0, cells, cellCount, r.size());
99 if (newCellCount == batch) {
100 break;
101 }
102 cellCount = newCellCount;
103 }
104 numCellsOfPartialResults -= batch;
105 return Result.create(cells, null, stale,
106 result.mayHaveMoreCellsInRow() || !partialResults.isEmpty());
107 }
108
109 @Override
110 public void loadResultsToCache(Result[] results, boolean isHeartbeatMessage) throws IOException {
111 if (results.length == 0) {
112 if (!isHeartbeatMessage) {
113 if (!partialResults.isEmpty()) {
114 checkUpdateNumberOfCompleteRowsAndCache(createCompletedResult());
115 return;
116 }
117 if (lastResultPartial) {
118
119
120 numberOfCompleteRows++;
121 }
122 }
123 return;
124 }
125 for (Result result : results) {
126 result = filterCells(result, lastCell);
127 if (result == null) {
128 continue;
129 }
130 if (!partialResults.isEmpty()) {
131 if (!Bytes.equals(partialResults.peek().getRow(), result.getRow())) {
132
133 checkUpdateNumberOfCompleteRowsAndCache(createCompletedResult());
134 }
135 } else if (lastResultPartial && !CellUtil.matchingRow(lastCell, result.getRow())) {
136
137
138
139 numberOfCompleteRows++;
140 }
141
142 if (!partialResults.isEmpty() &&
143 !Bytes.equals(partialResults.peek().getRow(), result.getRow())) {
144 checkUpdateNumberOfCompleteRowsAndCache(createCompletedResult());
145 }
146 Result regroupedResult = regroupResults(result);
147 if (regroupedResult != null) {
148 if (!regroupedResult.mayHaveMoreCellsInRow()) {
149 numberOfCompleteRows++;
150 }
151 checkUpdateNumberOfCompleteRowsAndCache(regroupedResult);
152
153 recordLastResult(regroupedResult);
154 }
155 if (!result.mayHaveMoreCellsInRow() && !partialResults.isEmpty()) {
156
157 checkUpdateNumberOfCompleteRowsAndCache(createCompletedResult());
158 }
159 }
160 }
161
162 @Override
163 protected void checkUpdateNumberOfCompleteRowsAndCache(Result rs) {
164
165 addResultToCache(rs);
166 }
167
168 @Override
169 public void clear() {
170 partialResults.clear();
171 numCellsOfPartialResults = 0;
172 super.clear();
173 }
174 }