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