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.client;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.conf.Configuration;
25 import org.apache.hadoop.hbase.DoNotRetryIOException;
26 import org.apache.hadoop.hbase.HBaseConfiguration;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.HRegionInfo;
29 import org.apache.hadoop.hbase.HRegionLocation;
30 import org.apache.hadoop.hbase.HServerAddress;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.KeyValue;
33 import org.apache.hadoop.hbase.NotServingRegionException;
34 import org.apache.hadoop.hbase.UnknownScannerException;
35 import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.Pair;
38 import org.apache.hadoop.hbase.util.Writables;
39
40 import java.io.IOException;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Iterator;
44 import java.util.LinkedList;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.TreeMap;
48 import java.util.concurrent.ExecutorService;
49 import java.util.concurrent.LinkedBlockingQueue;
50 import java.util.concurrent.ThreadFactory;
51 import java.util.concurrent.ThreadPoolExecutor;
52 import java.util.concurrent.TimeUnit;
53 import java.util.concurrent.atomic.AtomicInteger;
54
55 import java.io.DataInput;
56 import java.io.DataOutput;
57
58
59
60
61
62
63
64
65
66
67
68 public class HTable implements HTableInterface {
69 private final HConnection connection;
70 private final byte [] tableName;
71 protected final int scannerTimeout;
72 private volatile Configuration configuration;
73 private final ArrayList<Put> writeBuffer = new ArrayList<Put>();
74 private long writeBufferSize;
75 private boolean autoFlush;
76 private long currentWriteBufferSize;
77 protected int scannerCaching;
78 private int maxKeyValueSize;
79
80 private long maxScannerResultSize;
81
82
83
84
85
86
87
88 public HTable(final String tableName)
89 throws IOException {
90 this(HBaseConfiguration.create(), Bytes.toBytes(tableName));
91 }
92
93
94
95
96
97
98
99 public HTable(final byte [] tableName)
100 throws IOException {
101 this(HBaseConfiguration.create(), tableName);
102 }
103
104
105
106
107
108
109
110
111 public HTable(Configuration conf, final String tableName)
112 throws IOException {
113 this(conf, Bytes.toBytes(tableName));
114 }
115
116
117
118
119
120
121
122
123
124 public HTable(Configuration conf, final byte [] tableName)
125 throws IOException {
126 this.tableName = tableName;
127 if (conf == null) {
128 this.scannerTimeout = 0;
129 this.connection = null;
130 return;
131 }
132 this.connection = HConnectionManager.getConnection(conf);
133 this.scannerTimeout =
134 (int) conf.getLong(HConstants.HBASE_REGIONSERVER_LEASE_PERIOD_KEY, HConstants.DEFAULT_HBASE_REGIONSERVER_LEASE_PERIOD);
135 this.configuration = conf;
136 this.connection.locateRegion(tableName, HConstants.EMPTY_START_ROW);
137 this.writeBufferSize = conf.getLong("hbase.client.write.buffer", 2097152);
138 this.autoFlush = true;
139 this.currentWriteBufferSize = 0;
140 this.scannerCaching = conf.getInt("hbase.client.scanner.caching", 1);
141
142 this.maxScannerResultSize = conf.getLong(
143 HConstants.HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE_KEY,
144 HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
145 this.maxKeyValueSize = conf.getInt("hbase.client.keyvalue.maxsize", -1);
146
147 int nrHRS = getCurrentNrHRS();
148 if (nrHRS == 0) {
149
150 nrHRS = 10;
151 }
152 int nrThreads = conf.getInt("hbase.htable.threads.max", nrHRS);
153
154
155
156 this.pool = new ThreadPoolExecutor(0, nrThreads,
157 60, TimeUnit.SECONDS,
158 new LinkedBlockingQueue<Runnable>(),
159 new DaemonThreadFactory());
160 }
161
162 public Configuration getConfiguration() {
163 return configuration;
164 }
165
166
167
168
169
170
171
172 int getCurrentNrHRS() throws IOException {
173 return HConnectionManager
174 .getClientZooKeeperWatcher(this.configuration)
175 .getZooKeeperWrapper()
176 .getRSDirectoryCount();
177 }
178
179
180 private ExecutorService pool;
181
182
183
184
185
186
187
188 public static boolean isTableEnabled(String tableName) throws IOException {
189 return isTableEnabled(Bytes.toBytes(tableName));
190 }
191
192
193
194
195
196
197
198 public static boolean isTableEnabled(byte[] tableName) throws IOException {
199 return isTableEnabled(HBaseConfiguration.create(), tableName);
200 }
201
202
203
204
205
206
207
208
209 public static boolean isTableEnabled(Configuration conf, String tableName)
210 throws IOException {
211 return isTableEnabled(conf, Bytes.toBytes(tableName));
212 }
213
214
215
216
217
218
219
220
221 public static boolean isTableEnabled(Configuration conf, byte[] tableName)
222 throws IOException {
223 return HConnectionManager.getConnection(conf).isTableEnabled(tableName);
224 }
225
226
227
228
229
230
231
232 public HRegionLocation getRegionLocation(final String row)
233 throws IOException {
234 return connection.getRegionLocation(tableName, Bytes.toBytes(row), false);
235 }
236
237
238
239
240
241
242
243 public HRegionLocation getRegionLocation(final byte [] row)
244 throws IOException {
245 return connection.getRegionLocation(tableName, row, false);
246 }
247
248 public byte [] getTableName() {
249 return this.tableName;
250 }
251
252
253
254
255
256
257
258 public HConnection getConnection() {
259 return this.connection;
260 }
261
262
263
264
265
266
267 public int getScannerCaching() {
268 return scannerCaching;
269 }
270
271
272
273
274
275
276
277
278
279
280
281 public void setScannerCaching(int scannerCaching) {
282 this.scannerCaching = scannerCaching;
283 }
284
285 public HTableDescriptor getTableDescriptor() throws IOException {
286 return new UnmodifyableHTableDescriptor(
287 this.connection.getHTableDescriptor(this.tableName));
288 }
289
290
291
292
293
294
295
296
297 public byte [][] getStartKeys() throws IOException {
298 return getStartEndKeys().getFirst();
299 }
300
301
302
303
304
305
306
307
308 public byte[][] getEndKeys() throws IOException {
309 return getStartEndKeys().getSecond();
310 }
311
312
313
314
315
316
317
318
319
320 @SuppressWarnings("unchecked")
321 public Pair<byte[][],byte[][]> getStartEndKeys() throws IOException {
322 final List<byte[]> startKeyList = new ArrayList<byte[]>();
323 final List<byte[]> endKeyList = new ArrayList<byte[]>();
324 MetaScannerVisitor visitor = new MetaScannerVisitor() {
325 public boolean processRow(Result rowResult) throws IOException {
326 HRegionInfo info = Writables.getHRegionInfo(
327 rowResult.getValue(HConstants.CATALOG_FAMILY,
328 HConstants.REGIONINFO_QUALIFIER));
329 if (Bytes.equals(info.getTableDesc().getName(), getTableName())) {
330 if (!(info.isOffline() || info.isSplit())) {
331 startKeyList.add(info.getStartKey());
332 endKeyList.add(info.getEndKey());
333 }
334 }
335 return true;
336 }
337 };
338 MetaScanner.metaScan(configuration, visitor, this.tableName);
339 return new Pair(startKeyList.toArray(new byte[startKeyList.size()][]),
340 endKeyList.toArray(new byte[endKeyList.size()][]));
341 }
342
343
344
345
346
347
348
349
350 public Map<HRegionInfo, HServerAddress> getRegionsInfo() throws IOException {
351 final Map<HRegionInfo, HServerAddress> regionMap =
352 new TreeMap<HRegionInfo, HServerAddress>();
353
354 MetaScannerVisitor visitor = new MetaScannerVisitor() {
355 public boolean processRow(Result rowResult) throws IOException {
356 HRegionInfo info = Writables.getHRegionInfo(
357 rowResult.getValue(HConstants.CATALOG_FAMILY,
358 HConstants.REGIONINFO_QUALIFIER));
359
360 if (!(Bytes.equals(info.getTableDesc().getName(), getTableName()))) {
361 return false;
362 }
363
364 HServerAddress server = new HServerAddress();
365 byte [] value = rowResult.getValue(HConstants.CATALOG_FAMILY,
366 HConstants.SERVER_QUALIFIER);
367 if (value != null && value.length > 0) {
368 String address = Bytes.toString(value);
369 server = new HServerAddress(address);
370 }
371
372 if (!(info.isOffline() || info.isSplit())) {
373 regionMap.put(new UnmodifyableHRegionInfo(info), server);
374 }
375 return true;
376 }
377
378 };
379 MetaScanner.metaScan(configuration, visitor, tableName);
380 return regionMap;
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405 public void prewarmRegionCache(Map<HRegionInfo, HServerAddress> regionMap) {
406 this.connection.prewarmRegionCache(this.getTableName(), regionMap);
407 }
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429 public void serializeRegionInfo(DataOutput out) throws IOException {
430 Map<HRegionInfo, HServerAddress> allRegions = this.getRegionsInfo();
431
432 out.writeInt(allRegions.size());
433 for (Map.Entry<HRegionInfo, HServerAddress> es : allRegions.entrySet()) {
434 es.getKey().write(out);
435 es.getValue().write(out);
436 }
437 }
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 public Map<HRegionInfo, HServerAddress> deserializeRegionInfo(DataInput in)
456 throws IOException {
457 final Map<HRegionInfo, HServerAddress> allRegions =
458 new TreeMap<HRegionInfo, HServerAddress>();
459
460
461 int regionsCount = in.readInt();
462 for (int i = 0; i < regionsCount; ++i) {
463 HRegionInfo hri = new HRegionInfo();
464 hri.readFields(in);
465 HServerAddress hsa = new HServerAddress();
466 hsa.readFields(in);
467 allRegions.put(hri, hsa);
468 }
469 return allRegions;
470 }
471
472 public Result getRowOrBefore(final byte[] row, final byte[] family)
473 throws IOException {
474 return connection.getRegionServerWithRetries(
475 new ServerCallable<Result>(connection, tableName, row) {
476 public Result call() throws IOException {
477 return server.getClosestRowBefore(location.getRegionInfo().getRegionName(),
478 row, family);
479 }
480 });
481 }
482
483 public ResultScanner getScanner(final Scan scan) throws IOException {
484 ClientScanner s = new ClientScanner(scan);
485 s.initialize();
486 return s;
487 }
488
489 public ResultScanner getScanner(byte [] family) throws IOException {
490 Scan scan = new Scan();
491 scan.addFamily(family);
492 return getScanner(scan);
493 }
494
495 public ResultScanner getScanner(byte [] family, byte [] qualifier)
496 throws IOException {
497 Scan scan = new Scan();
498 scan.addColumn(family, qualifier);
499 return getScanner(scan);
500 }
501
502 public Result get(final Get get) throws IOException {
503 return connection.getRegionServerWithRetries(
504 new ServerCallable<Result>(connection, tableName, get.getRow()) {
505 public Result call() throws IOException {
506 return server.get(location.getRegionInfo().getRegionName(), get);
507 }
508 }
509 );
510 }
511
512 public void delete(final Delete delete)
513 throws IOException {
514 connection.getRegionServerWithRetries(
515 new ServerCallable<Boolean>(connection, tableName, delete.getRow()) {
516 public Boolean call() throws IOException {
517 server.delete(location.getRegionInfo().getRegionName(), delete);
518 return null;
519 }
520 }
521 );
522 }
523
524 public void delete(final List<Delete> deletes)
525 throws IOException {
526 int last = 0;
527 try {
528 last = connection.processBatchOfDeletes(deletes, this.tableName);
529 } finally {
530 deletes.subList(0, last).clear();
531 }
532 }
533
534 public void put(final Put put) throws IOException {
535 doPut(Arrays.asList(put));
536 }
537
538 public void put(final List<Put> puts) throws IOException {
539 doPut(puts);
540 }
541
542 private void doPut(final List<Put> puts) throws IOException {
543 for (Put put : puts) {
544 validatePut(put);
545 writeBuffer.add(put);
546 currentWriteBufferSize += put.heapSize();
547 }
548 if (autoFlush || currentWriteBufferSize > writeBufferSize) {
549 flushCommits();
550 }
551 }
552
553 public long incrementColumnValue(final byte [] row, final byte [] family,
554 final byte [] qualifier, final long amount)
555 throws IOException {
556 return incrementColumnValue(row, family, qualifier, amount, true);
557 }
558
559 @SuppressWarnings({"ThrowableInstanceNeverThrown"})
560 public long incrementColumnValue(final byte [] row, final byte [] family,
561 final byte [] qualifier, final long amount, final boolean writeToWAL)
562 throws IOException {
563 NullPointerException npe = null;
564 if (row == null) {
565 npe = new NullPointerException("row is null");
566 } else if (family == null) {
567 npe = new NullPointerException("column is null");
568 }
569 if (npe != null) {
570 throw new IOException(
571 "Invalid arguments to incrementColumnValue", npe);
572 }
573 return connection.getRegionServerWithRetries(
574 new ServerCallable<Long>(connection, tableName, row) {
575 public Long call() throws IOException {
576 return server.incrementColumnValue(
577 location.getRegionInfo().getRegionName(), row, family,
578 qualifier, amount, writeToWAL);
579 }
580 }
581 );
582 }
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 public boolean checkAndPut(final byte [] row,
598 final byte [] family, final byte [] qualifier, final byte [] value,
599 final Put put)
600 throws IOException {
601 return connection.getRegionServerWithRetries(
602 new ServerCallable<Boolean>(connection, tableName, row) {
603 public Boolean call() throws IOException {
604 return server.checkAndPut(location.getRegionInfo().getRegionName(),
605 row, family, qualifier, value, put) ? Boolean.TRUE : Boolean.FALSE;
606 }
607 }
608 );
609 }
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624 public boolean checkAndDelete(final byte [] row,
625 final byte [] family, final byte [] qualifier, final byte [] value,
626 final Delete delete)
627 throws IOException {
628 return connection.getRegionServerWithRetries(
629 new ServerCallable<Boolean>(connection, tableName, row) {
630 public Boolean call() throws IOException {
631 return server.checkAndDelete(
632 location.getRegionInfo().getRegionName(),
633 row, family, qualifier, value, delete)
634 ? Boolean.TRUE : Boolean.FALSE;
635 }
636 }
637 );
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651 public boolean exists(final Get get) throws IOException {
652 return connection.getRegionServerWithRetries(
653 new ServerCallable<Boolean>(connection, tableName, get.getRow()) {
654 public Boolean call() throws IOException {
655 return server.
656 exists(location.getRegionInfo().getRegionName(), get);
657 }
658 }
659 );
660 }
661
662 public void flushCommits() throws IOException {
663 try {
664 connection.processBatchOfPuts(writeBuffer,
665 tableName, pool);
666 } finally {
667
668 currentWriteBufferSize = 0;
669 for (Put aPut : writeBuffer) {
670 currentWriteBufferSize += aPut.heapSize();
671 }
672 }
673 }
674
675 public void close() throws IOException{
676 flushCommits();
677 }
678
679
680 private void validatePut(final Put put) throws IllegalArgumentException{
681 if (put.isEmpty()) {
682 throw new IllegalArgumentException("No columns to insert");
683 }
684 if (maxKeyValueSize > 0) {
685 for (List<KeyValue> list : put.getFamilyMap().values()) {
686 for (KeyValue kv : list) {
687 if (kv.getLength() > maxKeyValueSize) {
688 throw new IllegalArgumentException("KeyValue size too large");
689 }
690 }
691 }
692 }
693 }
694
695 public RowLock lockRow(final byte [] row)
696 throws IOException {
697 return connection.getRegionServerWithRetries(
698 new ServerCallable<RowLock>(connection, tableName, row) {
699 public RowLock call() throws IOException {
700 long lockId =
701 server.lockRow(location.getRegionInfo().getRegionName(), row);
702 return new RowLock(row,lockId);
703 }
704 }
705 );
706 }
707
708 public void unlockRow(final RowLock rl)
709 throws IOException {
710 connection.getRegionServerWithRetries(
711 new ServerCallable<Boolean>(connection, tableName, rl.getRow()) {
712 public Boolean call() throws IOException {
713 server.unlockRow(location.getRegionInfo().getRegionName(),
714 rl.getLockId());
715 return null;
716 }
717 }
718 );
719 }
720
721 public boolean isAutoFlush() {
722 return autoFlush;
723 }
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 public void setAutoFlush(boolean autoFlush) {
744 this.autoFlush = autoFlush;
745 }
746
747
748
749
750
751
752
753
754 public long getWriteBufferSize() {
755 return writeBufferSize;
756 }
757
758
759
760
761
762
763
764
765
766 public void setWriteBufferSize(long writeBufferSize) throws IOException {
767 this.writeBufferSize = writeBufferSize;
768 if(currentWriteBufferSize > writeBufferSize) {
769 flushCommits();
770 }
771 }
772
773
774
775
776
777 public ArrayList<Put> getWriteBuffer() {
778 return writeBuffer;
779 }
780
781
782
783
784
785
786 protected class ClientScanner implements ResultScanner {
787 private final Log CLIENT_LOG = LogFactory.getLog(this.getClass());
788
789 private Scan scan;
790 private boolean closed = false;
791
792
793 private HRegionInfo currentRegion = null;
794 private ScannerCallable callable = null;
795 private final LinkedList<Result> cache = new LinkedList<Result>();
796 private final int caching;
797 private long lastNext;
798
799 private Result lastResult = null;
800
801 protected ClientScanner(final Scan scan) {
802 if (CLIENT_LOG.isDebugEnabled()) {
803 CLIENT_LOG.debug("Creating scanner over "
804 + Bytes.toString(getTableName())
805 + " starting at key '" + Bytes.toStringBinary(scan.getStartRow()) + "'");
806 }
807 this.scan = scan;
808 this.lastNext = System.currentTimeMillis();
809
810
811 if (this.scan.getCaching() > 0) {
812 this.caching = this.scan.getCaching();
813 } else {
814 this.caching = HTable.this.scannerCaching;
815 }
816
817
818
819
820
821
822
823 }
824
825 public void initialize() throws IOException {
826 nextScanner(this.caching, false);
827 }
828
829 protected Scan getScan() {
830 return scan;
831 }
832
833 protected long getTimestamp() {
834 return lastNext;
835 }
836
837
838 private boolean checkScanStopRow(final byte [] endKey) {
839 if (this.scan.getStopRow().length > 0) {
840
841 byte [] stopRow = scan.getStopRow();
842 int cmp = Bytes.compareTo(stopRow, 0, stopRow.length,
843 endKey, 0, endKey.length);
844 if (cmp <= 0) {
845
846
847 return true;
848 }
849 }
850 return false;
851 }
852
853
854
855
856
857
858
859
860
861
862 private boolean nextScanner(int nbRows, final boolean done)
863 throws IOException {
864
865 if (this.callable != null) {
866 this.callable.setClose();
867 getConnection().getRegionServerWithRetries(callable);
868 this.callable = null;
869 }
870
871
872 byte [] localStartKey;
873
874
875 if (this.currentRegion != null) {
876 byte [] endKey = this.currentRegion.getEndKey();
877 if (endKey == null ||
878 Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY) ||
879 checkScanStopRow(endKey) ||
880 done) {
881 close();
882 if (CLIENT_LOG.isDebugEnabled()) {
883 CLIENT_LOG.debug("Finished with scanning at " + this.currentRegion);
884 }
885 return false;
886 }
887 localStartKey = endKey;
888 if (CLIENT_LOG.isDebugEnabled()) {
889 CLIENT_LOG.debug("Finished with region " + this.currentRegion);
890 }
891 } else {
892 localStartKey = this.scan.getStartRow();
893 }
894
895 if (CLIENT_LOG.isDebugEnabled()) {
896 CLIENT_LOG.debug("Advancing internal scanner to startKey at '" +
897 Bytes.toStringBinary(localStartKey) + "'");
898 }
899 try {
900 callable = getScannerCallable(localStartKey, nbRows);
901
902
903 getConnection().getRegionServerWithRetries(callable);
904 this.currentRegion = callable.getHRegionInfo();
905 } catch (IOException e) {
906 close();
907 throw e;
908 }
909 return true;
910 }
911
912 protected ScannerCallable getScannerCallable(byte [] localStartKey,
913 int nbRows) {
914 scan.setStartRow(localStartKey);
915 ScannerCallable s = new ScannerCallable(getConnection(),
916 getTableName(), scan);
917 s.setCaching(nbRows);
918 return s;
919 }
920
921 public Result next() throws IOException {
922
923
924 if (cache.size() == 0 && this.closed) {
925 return null;
926 }
927 if (cache.size() == 0) {
928 Result [] values = null;
929 long remainingResultSize = maxScannerResultSize;
930 int countdown = this.caching;
931
932
933 callable.setCaching(this.caching);
934
935
936 boolean skipFirst = false;
937 do {
938 try {
939
940
941
942 values = getConnection().getRegionServerWithRetries(callable);
943 if (skipFirst) {
944 skipFirst = false;
945
946 values = getConnection().getRegionServerWithRetries(callable);
947 }
948 } catch (DoNotRetryIOException e) {
949 if (e instanceof UnknownScannerException) {
950 long timeout = lastNext + scannerTimeout;
951
952
953
954 if (timeout < System.currentTimeMillis()) {
955 long elapsed = System.currentTimeMillis() - lastNext;
956 ScannerTimeoutException ex = new ScannerTimeoutException(
957 elapsed + "ms passed since the last invocation, " +
958 "timeout is currently set to " + scannerTimeout);
959 ex.initCause(e);
960 throw ex;
961 }
962 } else {
963 Throwable cause = e.getCause();
964 if (cause == null || !(cause instanceof NotServingRegionException)) {
965 throw e;
966 }
967 }
968
969
970 if (this.lastResult != null) {
971 this.scan.setStartRow(this.lastResult.getRow());
972
973
974 skipFirst = true;
975 }
976
977 this.currentRegion = null;
978 continue;
979 }
980 lastNext = System.currentTimeMillis();
981 if (values != null && values.length > 0) {
982 for (Result rs : values) {
983 cache.add(rs);
984 for (KeyValue kv : rs.raw()) {
985 remainingResultSize -= kv.heapSize();
986 }
987 countdown--;
988 this.lastResult = rs;
989 }
990 }
991
992 } while (remainingResultSize > 0 && countdown > 0 && nextScanner(countdown, values == null));
993 }
994
995 if (cache.size() > 0) {
996 return cache.poll();
997 }
998 return null;
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 public Result [] next(int nbRows) throws IOException {
1011
1012 ArrayList<Result> resultSets = new ArrayList<Result>(nbRows);
1013 for(int i = 0; i < nbRows; i++) {
1014 Result next = next();
1015 if (next != null) {
1016 resultSets.add(next);
1017 } else {
1018 break;
1019 }
1020 }
1021 return resultSets.toArray(new Result[resultSets.size()]);
1022 }
1023
1024 public void close() {
1025 if (callable != null) {
1026 callable.setClose();
1027 try {
1028 getConnection().getRegionServerWithRetries(callable);
1029 } catch (IOException e) {
1030
1031
1032
1033
1034 }
1035 callable = null;
1036 }
1037 closed = true;
1038 }
1039
1040 public Iterator<Result> iterator() {
1041 return new Iterator<Result>() {
1042
1043 Result next = null;
1044
1045
1046
1047
1048
1049 public boolean hasNext() {
1050 if (next == null) {
1051 try {
1052 next = ClientScanner.this.next();
1053 return next != null;
1054 } catch (IOException e) {
1055 throw new RuntimeException(e);
1056 }
1057 }
1058 return true;
1059 }
1060
1061
1062
1063 public Result next() {
1064
1065
1066 if (!hasNext()) {
1067 return null;
1068 }
1069
1070
1071
1072
1073 Result temp = next;
1074 next = null;
1075 return temp;
1076 }
1077
1078 public void remove() {
1079 throw new UnsupportedOperationException();
1080 }
1081 };
1082 }
1083 }
1084
1085 static class DaemonThreadFactory implements ThreadFactory {
1086 static final AtomicInteger poolNumber = new AtomicInteger(1);
1087 final ThreadGroup group;
1088 final AtomicInteger threadNumber = new AtomicInteger(1);
1089 final String namePrefix;
1090
1091 DaemonThreadFactory() {
1092 SecurityManager s = System.getSecurityManager();
1093 group = (s != null)? s.getThreadGroup() :
1094 Thread.currentThread().getThreadGroup();
1095 namePrefix = "pool-" +
1096 poolNumber.getAndIncrement() +
1097 "-thread-";
1098 }
1099
1100 public Thread newThread(Runnable r) {
1101 Thread t = new Thread(group, r,
1102 namePrefix + threadNumber.getAndIncrement(),
1103 0);
1104 if (!t.isDaemon())
1105 t.setDaemon(true);
1106 if (t.getPriority() != Thread.NORM_PRIORITY)
1107 t.setPriority(Thread.NORM_PRIORITY);
1108 return t;
1109 }
1110 }
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 public static void setRegionCachePrefetch(final byte[] tableName,
1121 boolean enable) {
1122 HConnectionManager.getConnection(HBaseConfiguration.create()).
1123 setRegionCachePrefetch(tableName, enable);
1124 }
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 public static void setRegionCachePrefetch(final Configuration conf,
1136 final byte[] tableName, boolean enable) {
1137 HConnectionManager.getConnection(conf).setRegionCachePrefetch(
1138 tableName, enable);
1139 }
1140
1141
1142
1143
1144
1145
1146
1147
1148 public static boolean getRegionCachePrefetch(final Configuration conf,
1149 final byte[] tableName) {
1150 return HConnectionManager.getConnection(conf).getRegionCachePrefetch(
1151 tableName);
1152 }
1153
1154
1155
1156
1157
1158
1159
1160 public static boolean getRegionCachePrefetch(final byte[] tableName) {
1161 return HConnectionManager.getConnection(HBaseConfiguration.create()).
1162 getRegionCachePrefetch(tableName);
1163 }
1164 }