1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.client;
22
23 import org.apache.hadoop.conf.Configuration;
24 import org.apache.hadoop.hbase.HConstants;
25 import org.apache.hadoop.hbase.HRegionInfo;
26 import org.apache.hadoop.hbase.TableNotFoundException;
27 import org.apache.hadoop.hbase.util.Bytes;
28 import org.apache.hadoop.hbase.util.Writables;
29
30 import java.io.IOException;
31
32
33
34
35
36
37
38
39
40 public class MetaScanner {
41
42
43
44
45
46
47
48
49
50 public static void metaScan(Configuration configuration,
51 MetaScannerVisitor visitor)
52 throws IOException {
53 metaScan(configuration, visitor, HConstants.EMPTY_START_ROW);
54 }
55
56
57
58
59
60
61
62
63
64
65 public static void metaScan(Configuration configuration,
66 MetaScannerVisitor visitor, byte[] tableName)
67 throws IOException {
68 metaScan(configuration, visitor, tableName, null, Integer.MAX_VALUE);
69 }
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public static void metaScan(Configuration configuration,
86 MetaScannerVisitor visitor, byte[] tableName, byte[] row,
87 int rowLimit)
88 throws IOException {
89 int rowUpperLimit = rowLimit > 0 ? rowLimit: Integer.MAX_VALUE;
90
91 HConnection connection = HConnectionManager.getConnection(configuration);
92
93
94 byte[] startRow;
95 if (row != null) {
96
97 assert tableName != null;
98 byte[] searchRow =
99 HRegionInfo.createRegionName(tableName, row, HConstants.NINES,
100 false);
101
102 HTable metaTable = new HTable(configuration, HConstants.META_TABLE_NAME);
103 Result startRowResult = metaTable.getRowOrBefore(searchRow,
104 HConstants.CATALOG_FAMILY);
105 if (startRowResult == null) {
106 throw new TableNotFoundException("Cannot find row in .META. for table: "
107 + Bytes.toString(tableName) + ", row=" + Bytes.toString(searchRow));
108 }
109 byte[] value = startRowResult.getValue(HConstants.CATALOG_FAMILY,
110 HConstants.REGIONINFO_QUALIFIER);
111 if (value == null || value.length == 0) {
112 throw new IOException("HRegionInfo was null or empty in Meta for " +
113 Bytes.toString(tableName) + ", row=" + Bytes.toString(searchRow));
114 }
115 HRegionInfo regionInfo = Writables.getHRegionInfo(value);
116
117 byte[] rowBefore = regionInfo.getStartKey();
118 startRow = HRegionInfo.createRegionName(tableName, rowBefore,
119 HConstants.ZEROES, false);
120 } else if (tableName == null || tableName.length == 0) {
121
122 startRow = HConstants.EMPTY_START_ROW;
123 } else {
124
125 startRow = HRegionInfo.createRegionName(
126 tableName, HConstants.EMPTY_START_ROW, HConstants.ZEROES, false);
127 }
128
129
130 ScannerCallable callable;
131 int rows = Math.min(rowLimit,
132 configuration.getInt("hbase.meta.scanner.caching", 100));
133 do {
134 final Scan scan = new Scan(startRow).addFamily(HConstants.CATALOG_FAMILY);
135 callable = new ScannerCallable(connection, HConstants.META_TABLE_NAME,
136 scan);
137
138 connection.getRegionServerWithRetries(callable);
139
140 int processedRows = 0;
141 try {
142 callable.setCaching(rows);
143 done: do {
144 if (processedRows >= rowUpperLimit) {
145 break;
146 }
147
148 Result [] rrs = connection.getRegionServerWithRetries(callable);
149 if (rrs == null || rrs.length == 0 || rrs[0].size() == 0) {
150 break;
151 }
152 for (Result rr : rrs) {
153 if (processedRows >= rowUpperLimit) {
154 break done;
155 }
156 if (!visitor.processRow(rr))
157 break done;
158 processedRows++;
159 }
160
161 } while(true);
162
163 startRow = callable.getHRegionInfo().getEndKey();
164 } finally {
165
166 callable.setClose();
167 connection.getRegionServerWithRetries(callable);
168 }
169 } while (Bytes.compareTo(startRow, HConstants.LAST_ROW) != 0);
170 }
171
172
173
174
175 public interface MetaScannerVisitor {
176
177
178
179
180
181
182
183
184
185 public boolean processRow(Result rowResult) throws IOException;
186 }
187 }