1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21 import java.io.Closeable;
22 import java.io.IOException;
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.HBaseConfiguration;
30 import org.apache.hadoop.hbase.HTableDescriptor;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.client.coprocessor.Batch;
33 import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback;
34 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
35 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.PoolMap;
38 import org.apache.hadoop.hbase.util.PoolMap.PoolType;
39
40 import com.google.protobuf.Descriptors;
41 import com.google.protobuf.Message;
42 import com.google.protobuf.Service;
43 import com.google.protobuf.ServiceException;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 @InterfaceAudience.Private
69 @Deprecated
70 public class HTablePool implements Closeable {
71 private final PoolMap<String, HTableInterface> tables;
72 private final int maxSize;
73 private final PoolType poolType;
74 private final Configuration config;
75 private final HTableInterfaceFactory tableFactory;
76
77
78
79
80 public HTablePool() {
81 this(HBaseConfiguration.create(), Integer.MAX_VALUE);
82 }
83
84
85
86
87
88
89
90
91
92 public HTablePool(final Configuration config, final int maxSize) {
93 this(config, maxSize, null, null);
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107 public HTablePool(final Configuration config, final int maxSize,
108 final HTableInterfaceFactory tableFactory) {
109 this(config, maxSize, tableFactory, PoolType.Reusable);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public HTablePool(final Configuration config, final int maxSize,
125 final PoolType poolType) {
126 this(config, maxSize, null, poolType);
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public HTablePool(final Configuration config, final int maxSize,
147 final HTableInterfaceFactory tableFactory, PoolType poolType) {
148
149
150 this.config = config == null ? HBaseConfiguration.create() : config;
151 this.maxSize = maxSize;
152 this.tableFactory = tableFactory == null ? new HTableFactory()
153 : tableFactory;
154 if (poolType == null) {
155 this.poolType = PoolType.Reusable;
156 } else {
157 switch (poolType) {
158 case Reusable:
159 case ThreadLocal:
160 this.poolType = poolType;
161 break;
162 default:
163 this.poolType = PoolType.Reusable;
164 break;
165 }
166 }
167 this.tables = new PoolMap<String, HTableInterface>(this.poolType,
168 this.maxSize);
169 }
170
171
172
173
174
175
176
177
178
179
180 public HTableInterface getTable(String tableName) {
181
182 HTableInterface table = findOrCreateTable(tableName);
183
184
185 return new PooledHTable(table);
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199 private HTableInterface findOrCreateTable(String tableName) {
200 HTableInterface table = tables.get(tableName);
201 if (table == null) {
202 table = createHTable(tableName);
203 }
204 return table;
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218
219 public HTableInterface getTable(byte[] tableName) {
220 return getTable(Bytes.toString(tableName));
221 }
222
223
224
225
226
227
228
229
230
231 public void putTable(HTableInterface table) throws IOException {
232
233
234
235
236
237
238 if (table instanceof PooledHTable) {
239 returnTable(((PooledHTable) table).getWrappedTable());
240 } else {
241
242
243
244
245 throw new IllegalArgumentException("not a pooled table: " + table);
246 }
247 }
248
249
250
251
252
253
254
255
256
257
258
259 private void returnTable(HTableInterface table) throws IOException {
260
261 String tableName = Bytes.toString(table.getTableName());
262 if (tables.size(tableName) >= maxSize) {
263
264 this.tables.removeValue(tableName, table);
265 this.tableFactory.releaseHTableInterface(table);
266 return;
267 }
268 tables.put(tableName, table);
269 }
270
271 protected HTableInterface createHTable(String tableName) {
272 return this.tableFactory.createHTableInterface(config,
273 Bytes.toBytes(tableName));
274 }
275
276
277
278
279
280
281
282
283
284
285
286 public void closeTablePool(final String tableName) throws IOException {
287 Collection<HTableInterface> tables = this.tables.values(tableName);
288 if (tables != null) {
289 for (HTableInterface table : tables) {
290 this.tableFactory.releaseHTableInterface(table);
291 }
292 }
293 this.tables.remove(tableName);
294 }
295
296
297
298
299
300
301 public void closeTablePool(final byte[] tableName) throws IOException {
302 closeTablePool(Bytes.toString(tableName));
303 }
304
305
306
307
308
309
310
311 @Override
312 public void close() throws IOException {
313 for (String tableName : tables.keySet()) {
314 closeTablePool(tableName);
315 }
316 this.tables.clear();
317 }
318
319 public int getCurrentPoolSize(String tableName) {
320 return tables.size(tableName);
321 }
322
323
324
325
326
327
328 class PooledHTable implements HTableInterface {
329
330 private boolean open = false;
331
332 private HTableInterface table;
333
334 public PooledHTable(HTableInterface table) {
335 this.table = table;
336 this.open = true;
337 }
338
339 @Override
340 public byte[] getTableName() {
341 checkState();
342 return table.getTableName();
343 }
344
345 @Override
346 public TableName getName() {
347 return table.getName();
348 }
349
350 @Override
351 public Configuration getConfiguration() {
352 checkState();
353 return table.getConfiguration();
354 }
355
356 @Override
357 public HTableDescriptor getTableDescriptor() throws IOException {
358 checkState();
359 return table.getTableDescriptor();
360 }
361
362 @Override
363 public boolean exists(Get get) throws IOException {
364 checkState();
365 return table.exists(get);
366 }
367
368 @Override
369 public boolean[] existsAll(List<Get> gets) throws IOException {
370 checkState();
371 return table.existsAll(gets);
372 }
373
374 @Override
375 public Boolean[] exists(List<Get> gets) throws IOException {
376 checkState();
377 return table.exists(gets);
378 }
379
380 @Override
381 public void batch(List<? extends Row> actions, Object[] results) throws IOException,
382 InterruptedException {
383 checkState();
384 table.batch(actions, results);
385 }
386
387
388
389
390
391
392 @Override
393 public Object[] batch(List<? extends Row> actions) throws IOException,
394 InterruptedException {
395 checkState();
396 return table.batch(actions);
397 }
398
399 @Override
400 public Result get(Get get) throws IOException {
401 checkState();
402 return table.get(get);
403 }
404
405 @Override
406 public Result[] get(List<Get> gets) throws IOException {
407 checkState();
408 return table.get(gets);
409 }
410
411 @Override
412 @SuppressWarnings("deprecation")
413 @Deprecated
414 public Result getRowOrBefore(byte[] row, byte[] family) throws IOException {
415 checkState();
416 return table.getRowOrBefore(row, family);
417 }
418
419 @Override
420 public ResultScanner getScanner(Scan scan) throws IOException {
421 checkState();
422 return table.getScanner(scan);
423 }
424
425 @Override
426 public ResultScanner getScanner(byte[] family) throws IOException {
427 checkState();
428 return table.getScanner(family);
429 }
430
431 @Override
432 public ResultScanner getScanner(byte[] family, byte[] qualifier)
433 throws IOException {
434 checkState();
435 return table.getScanner(family, qualifier);
436 }
437
438 @Override
439 public void put(Put put) throws IOException {
440 checkState();
441 table.put(put);
442 }
443
444 @Override
445 public void put(List<Put> puts) throws IOException {
446 checkState();
447 table.put(puts);
448 }
449
450 @Override
451 public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
452 byte[] value, Put put) throws IOException {
453 checkState();
454 return table.checkAndPut(row, family, qualifier, value, put);
455 }
456
457 @Override
458 public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
459 CompareOp compareOp, byte[] value, Put put) throws IOException {
460 checkState();
461 return table.checkAndPut(row, family, qualifier, compareOp, value, put);
462 }
463
464 @Override
465 public void delete(Delete delete) throws IOException {
466 checkState();
467 table.delete(delete);
468 }
469
470 @Override
471 public void delete(List<Delete> deletes) throws IOException {
472 checkState();
473 table.delete(deletes);
474 }
475
476 @Override
477 public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
478 byte[] value, Delete delete) throws IOException {
479 checkState();
480 return table.checkAndDelete(row, family, qualifier, value, delete);
481 }
482
483 @Override
484 public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
485 CompareOp compareOp, byte[] value, Delete delete) throws IOException {
486 checkState();
487 return table.checkAndDelete(row, family, qualifier, compareOp, value, delete);
488 }
489
490 @Override
491 public Result increment(Increment increment) throws IOException {
492 checkState();
493 return table.increment(increment);
494 }
495
496 @Override
497 public long incrementColumnValue(byte[] row, byte[] family,
498 byte[] qualifier, long amount) throws IOException {
499 checkState();
500 return table.incrementColumnValue(row, family, qualifier, amount);
501 }
502
503 @Override
504 public long incrementColumnValue(byte[] row, byte[] family,
505 byte[] qualifier, long amount, Durability durability) throws IOException {
506 checkState();
507 return table.incrementColumnValue(row, family, qualifier, amount,
508 durability);
509 }
510
511 @Override
512 public boolean isAutoFlush() {
513 checkState();
514 return table.isAutoFlush();
515 }
516
517 @Override
518 public void flushCommits() throws IOException {
519 checkState();
520 table.flushCommits();
521 }
522
523
524
525
526
527
528 @Override
529 public void close() throws IOException {
530 checkState();
531 open = false;
532 returnTable(table);
533 }
534
535 @Override
536 public CoprocessorRpcChannel coprocessorService(byte[] row) {
537 checkState();
538 return table.coprocessorService(row);
539 }
540
541 @Override
542 public <T extends Service, R> Map<byte[], R> coprocessorService(Class<T> service,
543 byte[] startKey, byte[] endKey, Batch.Call<T, R> callable)
544 throws ServiceException, Throwable {
545 checkState();
546 return table.coprocessorService(service, startKey, endKey, callable);
547 }
548
549 @Override
550 public <T extends Service, R> void coprocessorService(Class<T> service,
551 byte[] startKey, byte[] endKey, Batch.Call<T, R> callable, Callback<R> callback)
552 throws ServiceException, Throwable {
553 checkState();
554 table.coprocessorService(service, startKey, endKey, callable, callback);
555 }
556
557 @Override
558 public String toString() {
559 return "PooledHTable{" + ", table=" + table + '}';
560 }
561
562
563
564
565
566
567 HTableInterface getWrappedTable() {
568 return table;
569 }
570
571 @Override
572 public <R> void batchCallback(List<? extends Row> actions,
573 Object[] results, Callback<R> callback) throws IOException,
574 InterruptedException {
575 checkState();
576 table.batchCallback(actions, results, callback);
577 }
578
579
580
581
582
583
584
585
586 @Override
587 public <R> Object[] batchCallback(List<? extends Row> actions,
588 Callback<R> callback) throws IOException, InterruptedException {
589 checkState();
590 return table.batchCallback(actions, callback);
591 }
592
593 @Override
594 public void mutateRow(RowMutations rm) throws IOException {
595 checkState();
596 table.mutateRow(rm);
597 }
598
599 @Override
600 public Result append(Append append) throws IOException {
601 checkState();
602 return table.append(append);
603 }
604
605 @Override
606 public void setAutoFlush(boolean autoFlush) {
607 checkState();
608 table.setAutoFlush(autoFlush, autoFlush);
609 }
610
611 @Override
612 public void setAutoFlush(boolean autoFlush, boolean clearBufferOnFail) {
613 checkState();
614 table.setAutoFlush(autoFlush, clearBufferOnFail);
615 }
616
617 @Override
618 public void setAutoFlushTo(boolean autoFlush) {
619 table.setAutoFlushTo(autoFlush);
620 }
621
622 @Override
623 public long getWriteBufferSize() {
624 checkState();
625 return table.getWriteBufferSize();
626 }
627
628 @Override
629 public void setWriteBufferSize(long writeBufferSize) throws IOException {
630 checkState();
631 table.setWriteBufferSize(writeBufferSize);
632 }
633
634 boolean isOpen() {
635 return open;
636 }
637
638 private void checkState() {
639 if (!isOpen()) {
640 throw new IllegalStateException("Table=" + table.getName().getNameAsString()
641 + " already closed");
642 }
643 }
644
645 @Override
646 public long incrementColumnValue(byte[] row, byte[] family,
647 byte[] qualifier, long amount, boolean writeToWAL) throws IOException {
648 return table.incrementColumnValue(row, family, qualifier, amount, writeToWAL);
649 }
650
651 @Override
652 public <R extends Message> Map<byte[], R> batchCoprocessorService(
653 Descriptors.MethodDescriptor method, Message request,
654 byte[] startKey, byte[] endKey, R responsePrototype) throws ServiceException, Throwable {
655 checkState();
656 return table.batchCoprocessorService(method, request, startKey, endKey,
657 responsePrototype);
658 }
659
660 @Override
661 public <R extends Message> void batchCoprocessorService(
662 Descriptors.MethodDescriptor method, Message request,
663 byte[] startKey, byte[] endKey, R responsePrototype, Callback<R> callback)
664 throws ServiceException, Throwable {
665 checkState();
666 table.batchCoprocessorService(method, request, startKey, endKey, responsePrototype, callback);
667 }
668
669 @Override
670 public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareOp compareOp,
671 byte[] value, RowMutations mutation) throws IOException {
672 checkState();
673 return table.checkAndMutate(row, family, qualifier, compareOp, value, mutation);
674 }
675
676 @Override public void setOperationTimeout(int operationTimeout) {
677 table.setOperationTimeout(operationTimeout);
678 }
679
680 @Override public int getOperationTimeout() {
681 return table.getOperationTimeout();
682 }
683
684 @Override
685 @Deprecated
686 public void setRpcTimeout(int rpcTimeout) {
687 table.setRpcTimeout(rpcTimeout);
688 }
689
690 @Override
691 @Deprecated
692 public int getRpcTimeout() {
693 return table.getRpcTimeout();
694 }
695
696 @Override
697 public int getReadRpcTimeout() {
698 return table.getReadRpcTimeout();
699 }
700
701 @Override
702 public void setReadRpcTimeout(int readRpcTimeout) {
703 table.setReadRpcTimeout(readRpcTimeout);
704 }
705
706 @Override
707 public int getWriteRpcTimeout() {
708 return table.getWriteRpcTimeout();
709 }
710
711 @Override
712 public void setWriteRpcTimeout(int writeRpcTimeout) {
713 table.setWriteRpcTimeout(writeRpcTimeout);
714 }
715 }
716 }