1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver.wal;
20
21 import java.io.DataInput;
22 import java.io.DataOutput;
23 import java.io.EOFException;
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.UUID;
28
29 import org.apache.hadoop.classification.InterfaceAudience;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.util.Bytes;
32 import org.apache.hadoop.io.WritableComparable;
33 import org.apache.hadoop.io.WritableUtils;
34
35
36
37
38
39
40
41
42
43
44
45 @InterfaceAudience.Private
46 public class HLogKey implements WritableComparable<HLogKey> {
47
48
49 enum Version {
50 UNVERSIONED(0),
51
52 INITIAL(-1),
53
54
55 COMPRESSED(-2);
56
57 final int code;
58 static final Version[] byCode;
59 static {
60 byCode = Version.values();
61 for (int i = 0; i < byCode.length; i++) {
62 if (byCode[i].code != -1 * i) {
63 throw new AssertionError("Values in this enum should be descending by one");
64 }
65 }
66 }
67
68 Version(int code) {
69 this.code = code;
70 }
71
72 boolean atLeast(Version other) {
73 return code <= other.code;
74 }
75
76 static Version fromCode(int code) {
77 return byCode[code * -1];
78 }
79 }
80
81 private static final Version VERSION = Version.COMPRESSED;
82
83
84 private byte [] encodedRegionName;
85 private byte [] tablename;
86 private long logSeqNum;
87
88 private long writeTime;
89
90 private UUID clusterId;
91
92 private CompressionContext compressionContext;
93
94
95 public HLogKey() {
96 this(null, null, 0L, HConstants.LATEST_TIMESTAMP,
97 HConstants.DEFAULT_CLUSTER_ID);
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112 public HLogKey(final byte [] encodedRegionName, final byte [] tablename,
113 long logSeqNum, final long now, UUID clusterId) {
114 this.encodedRegionName = encodedRegionName;
115 this.tablename = tablename;
116 this.logSeqNum = logSeqNum;
117 this.writeTime = now;
118 this.clusterId = clusterId;
119 }
120
121
122
123
124 public void setCompressionContext(CompressionContext compressionContext) {
125 this.compressionContext = compressionContext;
126 }
127
128
129 public byte [] getEncodedRegionName() {
130 return encodedRegionName;
131 }
132
133
134 public byte [] getTablename() {
135 return tablename;
136 }
137
138
139 public long getLogSeqNum() {
140 return logSeqNum;
141 }
142
143 void setLogSeqNum(long logSeqNum) {
144 this.logSeqNum = logSeqNum;
145 }
146
147
148
149
150 public long getWriteTime() {
151 return this.writeTime;
152 }
153
154
155
156
157
158 public UUID getClusterId() {
159 return clusterId;
160 }
161
162
163
164
165
166 public void setClusterId(UUID clusterId) {
167 this.clusterId = clusterId;
168 }
169
170 @Override
171 public String toString() {
172 return Bytes.toString(tablename) + "/" + Bytes.toString(encodedRegionName) + "/" +
173 logSeqNum;
174 }
175
176
177
178
179
180
181
182
183 public Map<String, Object> toStringMap() {
184 Map<String, Object> stringMap = new HashMap<String, Object>();
185 stringMap.put("table", Bytes.toStringBinary(tablename));
186 stringMap.put("region", Bytes.toStringBinary(encodedRegionName));
187 stringMap.put("sequence", logSeqNum);
188 return stringMap;
189 }
190
191 @Override
192 public boolean equals(Object obj) {
193 if (this == obj) {
194 return true;
195 }
196 if (obj == null || getClass() != obj.getClass()) {
197 return false;
198 }
199 return compareTo((HLogKey)obj) == 0;
200 }
201
202 @Override
203 public int hashCode() {
204 int result = Bytes.hashCode(this.encodedRegionName);
205 result ^= this.logSeqNum;
206 result ^= this.writeTime;
207 result ^= this.clusterId.hashCode();
208 return result;
209 }
210
211 public int compareTo(HLogKey o) {
212 int result = Bytes.compareTo(this.encodedRegionName, o.encodedRegionName);
213 if (result == 0) {
214 if (this.logSeqNum < o.logSeqNum) {
215 result = -1;
216 } else if (this.logSeqNum > o.logSeqNum) {
217 result = 1;
218 }
219 if (result == 0) {
220 if (this.writeTime < o.writeTime) {
221 result = -1;
222 } else if (this.writeTime > o.writeTime) {
223 return 1;
224 }
225 }
226 }
227
228 return result;
229 }
230
231
232
233
234
235
236
237 void internTableName(byte []tablename) {
238
239
240 assert Bytes.equals(tablename, this.tablename);
241 this.tablename = tablename;
242 }
243
244
245
246
247
248
249
250 void internEncodedRegionName(byte []encodedRegionName) {
251
252
253 assert Bytes.equals(this.encodedRegionName, encodedRegionName);
254 this.encodedRegionName = encodedRegionName;
255 }
256
257 @Override
258 public void write(DataOutput out) throws IOException {
259 WritableUtils.writeVInt(out, VERSION.code);
260 if (compressionContext == null) {
261 Bytes.writeByteArray(out, this.encodedRegionName);
262 Bytes.writeByteArray(out, this.tablename);
263 } else {
264 Compressor.writeCompressed(this.encodedRegionName, 0,
265 this.encodedRegionName.length, out,
266 compressionContext.regionDict);
267 Compressor.writeCompressed(this.tablename, 0, this.tablename.length, out,
268 compressionContext.tableDict);
269 }
270 out.writeLong(this.logSeqNum);
271 out.writeLong(this.writeTime);
272
273 if (this.clusterId == HConstants.DEFAULT_CLUSTER_ID) {
274 out.writeBoolean(false);
275 } else {
276 out.writeBoolean(true);
277 out.writeLong(this.clusterId.getMostSignificantBits());
278 out.writeLong(this.clusterId.getLeastSignificantBits());
279 }
280 }
281
282 @Override
283 public void readFields(DataInput in) throws IOException {
284 Version version = Version.UNVERSIONED;
285
286
287
288
289
290
291
292
293 int len = WritableUtils.readVInt(in);
294 if (len < 0) {
295
296 version = Version.fromCode(len);
297
298
299 if (compressionContext == null || !version.atLeast(Version.COMPRESSED)) {
300 len = WritableUtils.readVInt(in);
301 }
302 }
303 if (compressionContext == null || !version.atLeast(Version.COMPRESSED)) {
304 this.encodedRegionName = new byte[len];
305 in.readFully(this.encodedRegionName);
306 this.tablename = Bytes.readByteArray(in);
307 } else {
308 this.encodedRegionName = Compressor.readCompressed(in, compressionContext.regionDict);
309 this.tablename = Compressor.readCompressed(in, compressionContext.tableDict);
310 }
311
312 this.logSeqNum = in.readLong();
313 this.writeTime = in.readLong();
314 this.clusterId = HConstants.DEFAULT_CLUSTER_ID;
315 if (version.atLeast(Version.INITIAL)) {
316 if (in.readBoolean()) {
317 this.clusterId = new UUID(in.readLong(), in.readLong());
318 }
319 } else {
320 try {
321
322 in.readByte();
323 } catch(EOFException e) {
324
325 }
326 }
327 }
328 }