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.mapreduce;
21
22 import java.io.DataInput;
23 import java.io.DataOutput;
24 import java.io.IOException;
25 import java.util.Arrays;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.client.Scan;
31 import org.apache.hadoop.hbase.util.Bytes;
32 import org.apache.hadoop.io.Writable;
33 import org.apache.hadoop.io.WritableUtils;
34 import org.apache.hadoop.mapreduce.InputSplit;
35
36
37
38
39
40 public class TableSplit extends InputSplit
41 implements Writable, Comparable<TableSplit> {
42 public static final Log LOG = LogFactory.getLog(TableSplit.class);
43
44
45
46 enum Version {
47 UNVERSIONED(0),
48
49 INITIAL(-1);
50
51 final int code;
52 static final Version[] byCode;
53 static {
54 byCode = Version.values();
55 for (int i = 0; i < byCode.length; i++) {
56 if (byCode[i].code != -1 * i) {
57 throw new AssertionError("Values in this enum should be descending by one");
58 }
59 }
60 }
61
62 Version(int code) {
63 this.code = code;
64 }
65
66 boolean atLeast(Version other) {
67 return code <= other.code;
68 }
69
70 static Version fromCode(int code) {
71 return byCode[code * -1];
72 }
73 }
74
75 private static final Version VERSION = Version.INITIAL;
76
77 private byte [] tableName;
78 private byte [] startRow;
79 private byte [] endRow;
80 private String regionLocation;
81 private String scan = "";
82
83
84 public TableSplit() {
85 this(HConstants.EMPTY_BYTE_ARRAY, null, HConstants.EMPTY_BYTE_ARRAY,
86 HConstants.EMPTY_BYTE_ARRAY, "");
87 }
88
89
90
91
92
93
94
95
96
97
98 public TableSplit(byte [] tableName, Scan scan, byte [] startRow, byte [] endRow,
99 final String location) {
100 this.tableName = tableName;
101 try {
102 this.scan =
103 (null == scan) ? "" : TableMapReduceUtil.convertScanToString(scan);
104 } catch (IOException e) {
105 LOG.warn("Failed to convert Scan to String", e);
106 }
107 this.startRow = startRow;
108 this.endRow = endRow;
109 this.regionLocation = location;
110 }
111
112
113
114
115
116
117
118
119
120 public TableSplit(byte[] tableName, byte[] startRow, byte[] endRow,
121 final String location) {
122 this(tableName, null, startRow, endRow, location);
123 }
124
125
126
127
128
129
130
131 public Scan getScan() throws IOException {
132 return TableMapReduceUtil.convertStringToScan(this.scan);
133 }
134
135
136
137
138
139
140 public byte [] getTableName() {
141 return tableName;
142 }
143
144
145
146
147
148
149 public byte [] getStartRow() {
150 return startRow;
151 }
152
153
154
155
156
157
158 public byte [] getEndRow() {
159 return endRow;
160 }
161
162
163
164
165
166
167 public String getRegionLocation() {
168 return regionLocation;
169 }
170
171
172
173
174
175
176
177 @Override
178 public String[] getLocations() {
179 return new String[] {regionLocation};
180 }
181
182
183
184
185
186
187
188 @Override
189 public long getLength() {
190
191 return 0;
192 }
193
194
195
196
197
198
199
200 @Override
201 public void readFields(DataInput in) throws IOException {
202 Version version = Version.UNVERSIONED;
203
204
205
206
207
208
209
210
211 int len = WritableUtils.readVInt(in);
212 if (len < 0) {
213
214 version = Version.fromCode(len);
215 len = WritableUtils.readVInt(in);
216 }
217 tableName = new byte[len];
218 in.readFully(tableName);
219 startRow = Bytes.readByteArray(in);
220 endRow = Bytes.readByteArray(in);
221 regionLocation = Bytes.toString(Bytes.readByteArray(in));
222 if (version.atLeast(Version.INITIAL)) {
223 scan = Bytes.toString(Bytes.readByteArray(in));
224 }
225 }
226
227
228
229
230
231
232
233 @Override
234 public void write(DataOutput out) throws IOException {
235 WritableUtils.writeVInt(out, VERSION.code);
236 Bytes.writeByteArray(out, tableName);
237 Bytes.writeByteArray(out, startRow);
238 Bytes.writeByteArray(out, endRow);
239 Bytes.writeByteArray(out, Bytes.toBytes(regionLocation));
240 Bytes.writeByteArray(out, Bytes.toBytes(scan));
241 }
242
243
244
245
246
247
248
249 @Override
250 public String toString() {
251 return regionLocation + ":" +
252 Bytes.toStringBinary(startRow) + "," + Bytes.toStringBinary(endRow);
253 }
254
255
256
257
258
259
260
261
262 @Override
263 public int compareTo(TableSplit split) {
264
265
266 int tableNameComparison =
267 Bytes.compareTo(getTableName(), split.getTableName());
268 return tableNameComparison != 0 ? tableNameComparison : Bytes.compareTo(
269 getStartRow(), split.getStartRow());
270 }
271
272 @Override
273 public boolean equals(Object o) {
274 if (o == null || !(o instanceof TableSplit)) {
275 return false;
276 }
277 return Bytes.equals(tableName, ((TableSplit)o).tableName) &&
278 Bytes.equals(startRow, ((TableSplit)o).startRow) &&
279 Bytes.equals(endRow, ((TableSplit)o).endRow) &&
280 regionLocation.equals(((TableSplit)o).regionLocation);
281 }
282
283 @Override
284 public int hashCode() {
285 int result = tableName != null ? Arrays.hashCode(tableName) : 0;
286 result = 31 * result + (scan != null ? scan.hashCode() : 0);
287 result = 31 * result + (startRow != null ? Arrays.hashCode(startRow) : 0);
288 result = 31 * result + (endRow != null ? Arrays.hashCode(endRow) : 0);
289 result = 31 * result + (regionLocation != null ? regionLocation.hashCode() : 0);
290 return result;
291 }
292 }