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.HConstants.EMPTY_END_ROW;
21 import static org.apache.hadoop.hbase.HConstants.EMPTY_START_ROW;
22
23 import java.io.IOException;
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import java.util.List;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.ThreadLocalRandom;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.hadoop.conf.Configuration;
32 import org.apache.hadoop.hbase.Cell;
33 import org.apache.hadoop.hbase.CellComparator;
34 import org.apache.hadoop.hbase.CellUtil;
35 import org.apache.hadoop.hbase.HConstants;
36 import org.apache.hadoop.hbase.HRegionInfo;
37 import org.apache.hadoop.hbase.ServerName;
38 import org.apache.hadoop.hbase.TableName;
39 import org.apache.hadoop.hbase.classification.InterfaceAudience;
40 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService;
41 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ClientService;
42 import org.apache.hadoop.hbase.security.User;
43 import org.apache.hadoop.hbase.security.UserProvider;
44 import org.apache.hadoop.hbase.util.Bytes;
45
46
47
48
49 @InterfaceAudience.Private
50 public class ConnectionUtils {
51
52
53
54
55
56
57
58
59 public static long getPauseTime(final long pause, final int tries) {
60 int ntries = tries;
61 if (ntries >= HConstants.RETRY_BACKOFF.length) {
62 ntries = HConstants.RETRY_BACKOFF.length - 1;
63 }
64 if (ntries < 0) {
65 ntries = 0;
66 }
67
68 long normalPause = pause * HConstants.RETRY_BACKOFF[ntries];
69
70 long jitter = (long) (normalPause * ThreadLocalRandom.current().nextFloat() * 0.01f);
71 return normalPause + jitter;
72 }
73
74
75
76
77
78
79
80 public static NonceGenerator injectNonceGeneratorForTesting(
81 ClusterConnection conn, NonceGenerator cnm) {
82 return ConnectionManager.injectNonceGeneratorForTesting(conn, cnm);
83 }
84
85
86
87
88
89
90
91
92 public static void setServerSideHConnectionRetriesConfig(
93 final Configuration c, final String sn, final Log log) {
94
95 int hcRetries = c.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
96 HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
97
98
99 int serversideMultiplier = c.getInt("hbase.client.serverside.retries.multiplier", 10);
100 int retries = hcRetries * serversideMultiplier;
101 c.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, retries);
102 log.info(sn + " server-side HConnection retries=" + retries);
103 }
104
105
106
107
108
109
110
111
112
113
114 @Deprecated
115 public static ClusterConnection createShortCircuitHConnection(final Connection conn,
116 final ServerName serverName, final AdminService.BlockingInterface admin,
117 final ClientService.BlockingInterface client) {
118 return new ConnectionAdapter(conn) {
119 @Override
120 public AdminService.BlockingInterface getAdmin(
121 ServerName sn, boolean getMaster) throws IOException {
122 return serverName.equals(sn) ? admin : super.getAdmin(sn, getMaster);
123 }
124
125 @Override
126 public ClientService.BlockingInterface getClient(
127 ServerName sn) throws IOException {
128 return serverName.equals(sn) ? client : super.getClient(sn);
129 }
130 };
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public static ClusterConnection createShortCircuitConnection(final Configuration conf,
146 ExecutorService pool, User user, final ServerName serverName,
147 final AdminService.BlockingInterface admin, final ClientService.BlockingInterface client)
148 throws IOException {
149 if (user == null) {
150 user = UserProvider.instantiate(conf).getCurrent();
151 }
152 return new ConnectionManager.HConnectionImplementation(conf, false, pool, user) {
153 @Override
154 public AdminService.BlockingInterface getAdmin(ServerName sn, boolean getMaster)
155 throws IOException {
156 return serverName.equals(sn) ? admin : super.getAdmin(sn, getMaster);
157 }
158
159 @Override
160 public ClientService.BlockingInterface getClient(ServerName sn) throws IOException {
161 return serverName.equals(sn) ? client : super.getClient(sn);
162 }
163 };
164 }
165
166
167
168
169
170 public static void setupMasterlessConnection(Configuration conf) {
171 conf.set(HConnection.HBASE_CLIENT_CONNECTION_IMPL,
172 MasterlessConnection.class.getName());
173 }
174
175
176
177
178
179 static class MasterlessConnection extends ConnectionManager.HConnectionImplementation {
180 MasterlessConnection(Configuration conf, boolean managed,
181 ExecutorService pool, User user) throws IOException {
182 super(conf, managed, pool, user);
183 }
184
185 @Override
186 public boolean isTableDisabled(TableName tableName) throws IOException {
187
188 return false;
189 }
190 }
191
192
193
194
195 static String getStubKey(String serviceName, ServerName serverName) {
196 return String.format("%s@%s", serviceName, serverName);
197 }
198
199
200
201 static final byte[] MAX_BYTE_ARRAY = Bytes.createMaxByteArray(9);
202
203
204
205
206 static byte[] createClosestRowAfter(byte[] row) {
207 return Arrays.copyOf(row, row.length + 1);
208 }
209
210
211
212
213 static byte[] createCloseRowBefore(byte[] row) {
214 if (row.length == 0) {
215 return MAX_BYTE_ARRAY;
216 }
217 if (row[row.length - 1] == 0) {
218 return Arrays.copyOf(row, row.length - 1);
219 } else {
220 byte[] nextRow = new byte[row.length + MAX_BYTE_ARRAY.length];
221 System.arraycopy(row, 0, nextRow, 0, row.length - 1);
222 nextRow[row.length - 1] = (byte) ((row[row.length - 1] & 0xFF) - 1);
223 System.arraycopy(MAX_BYTE_ARRAY, 0, nextRow, row.length, MAX_BYTE_ARRAY.length);
224 return nextRow;
225 }
226 }
227
228 static boolean isEmptyStartRow(byte[] row) {
229 return Bytes.equals(row, EMPTY_START_ROW);
230 }
231
232 static boolean isEmptyStopRow(byte[] row) {
233 return Bytes.equals(row, EMPTY_END_ROW);
234 }
235
236 private static final Comparator<Cell> COMPARE_WITHOUT_ROW = new Comparator<Cell>() {
237
238 @Override
239 public int compare(Cell o1, Cell o2) {
240 return CellComparator.compareWithoutRow(o1, o2);
241 }
242 };
243
244 static Result filterCells(Result result, Cell keepCellsAfter) {
245 if (keepCellsAfter == null) {
246
247 return result;
248 }
249
250 if (!CellUtil.matchingRow(keepCellsAfter, result.getRow(), 0, result.getRow().length)) {
251 return result;
252 }
253 Cell[] rawCells = result.rawCells();
254 int index = Arrays.binarySearch(rawCells, keepCellsAfter, COMPARE_WITHOUT_ROW);
255 if (index < 0) {
256 index = -index - 1;
257 } else {
258 index++;
259 }
260 if (index == 0) {
261 return result;
262 }
263 if (index == rawCells.length) {
264 return null;
265 }
266 return Result.create(Arrays.copyOfRange(rawCells, index, rawCells.length), null,
267 result.isStale(), result.mayHaveMoreCellsInRow());
268 }
269
270 static boolean noMoreResultsForScan(Scan scan, HRegionInfo info) {
271 if (isEmptyStopRow(info.getEndKey())) {
272 return true;
273 }
274 if (isEmptyStopRow(scan.getStopRow())) {
275 return false;
276 }
277 int c = Bytes.compareTo(info.getEndKey(), scan.getStopRow());
278
279
280
281 return c > 0 || (c == 0 && !scan.includeStopRow());
282 }
283
284 static boolean noMoreResultsForReverseScan(Scan scan, HRegionInfo info) {
285 if (isEmptyStartRow(info.getStartKey())) {
286 return true;
287 }
288 if (isEmptyStopRow(scan.getStopRow())) {
289 return false;
290 }
291
292
293 return Bytes.compareTo(info.getStartKey(), scan.getStopRow()) <= 0;
294 }
295
296 public static ScanResultCache createScanResultCache(Scan scan, List<Result> cache) {
297 if (scan.getAllowPartialResults()) {
298 return new AllowPartialScanResultCache(cache);
299 } else if (scan.getBatch() > 0) {
300 return new BatchScanResultCache(cache, scan.getBatch());
301 } else {
302 return new CompleteScanResultCache(cache);
303 }
304 }
305 }