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.DataInputStream;
24 import java.io.DataOutput;
25 import java.io.DataOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.NavigableMap;
30 import java.util.TreeMap;
31 import java.util.UUID;
32
33 import org.apache.hadoop.hbase.KeyValue;
34 import org.apache.hadoop.hbase.codec.Decoder;
35 import org.apache.hadoop.hbase.codec.Encoder;
36 import org.apache.hadoop.hbase.io.HeapSize;
37 import org.apache.hadoop.hbase.util.Bytes;
38 import org.apache.hadoop.hbase.util.ClassSize;
39 import org.apache.hadoop.io.Writable;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class WALEdit implements Writable, HeapSize {
76
77
78
79
80
81
82
83
84 private static final String PREFIX_CLUSTER_KEY = ".";
85 private final int VERSION_2 = -1;
86
87 private final ArrayList<KeyValue> kvs = new ArrayList<KeyValue>();
88
89
90
91
92
93
94
95
96
97
98 private final NavigableMap<byte[], Integer> scopes = new TreeMap<byte[], Integer>(
99 Bytes.BYTES_COMPARATOR);
100
101
102
103
104 private WALEditCodec codec = new WALEditCodec();
105
106 public WALEdit() {
107 }
108
109
110
111
112
113 @SuppressWarnings("javadoc")
114 public void setCompressionContext(final CompressionContext compression) {
115 this.codec.setCompression(compression);
116 }
117
118 public void setCodec(WALEditCodec codec) {
119 this.codec = codec;
120 }
121
122
123 public void add(KeyValue kv) {
124 this.kvs.add(kv);
125 }
126
127 public boolean isEmpty() {
128 return kvs.isEmpty();
129 }
130
131 public int size() {
132 return kvs.size();
133 }
134
135 public List<KeyValue> getKeyValues() {
136 return kvs;
137 }
138
139 public Integer getFromScope(byte[] key) {
140 return scopes.get(key);
141 }
142
143
144
145
146
147 @Deprecated
148 public NavigableMap<byte[], Integer> getScopes() {
149 return scopes;
150 }
151
152
153
154
155
156
157 @Deprecated
158 public void setScopes(NavigableMap<byte[], Integer> scopes) {
159 this.scopes.clear();
160 this.scopes.putAll(scopes);
161 }
162
163 public void putIntoScope(byte[] key, Integer value) {
164 scopes.put(key, value);
165 }
166
167 public boolean hasKeyInScope(byte[] key) {
168 return scopes.containsKey(key);
169 }
170
171
172
173
174 public boolean hasClusterId(UUID clusterId) {
175 return hasKeyInScope(Bytes.toBytes(PREFIX_CLUSTER_KEY + clusterId.toString()));
176 }
177
178
179
180
181 public void addClusterId(UUID clusterId) {
182 scopes.put(Bytes.toBytes(PREFIX_CLUSTER_KEY + clusterId.toString()), 1);
183 }
184
185
186
187
188 public void addClusterIds(List<UUID> clusterIds) {
189 for (UUID clusterId : clusterIds) {
190 addClusterId(clusterId);
191 }
192 }
193
194
195
196
197 public List<UUID> getClusterIds() {
198 List<UUID> clusterIds = new ArrayList<UUID>();
199 for (byte[] keyBytes : scopes.keySet()) {
200 String key = Bytes.toString(keyBytes);
201 if (key.startsWith(PREFIX_CLUSTER_KEY)) {
202 clusterIds.add(UUID.fromString(key.substring(PREFIX_CLUSTER_KEY.length())));
203 }
204 }
205 return clusterIds;
206 }
207
208 public void readFields(DataInput in) throws IOException {
209 kvs.clear();
210 scopes.clear();
211 Decoder decoder = this.codec.getDecoder((DataInputStream) in);
212 int versionOrLength = in.readInt();
213 int length = versionOrLength;
214
215
216 if (versionOrLength == VERSION_2) {
217 length = in.readInt();
218 }
219
220
221 for(int i=0; i< length && decoder.advance(); i++) {
222 kvs.add(decoder.current());
223 }
224
225
226 if (versionOrLength == VERSION_2) {
227 int numEntries = in.readInt();
228 if (numEntries > 0) {
229 for (int i = 0; i < numEntries; i++) {
230 byte[] key = Bytes.readByteArray(in);
231 int scope = in.readInt();
232 scopes.put(key, scope);
233 }
234 }
235 }
236 }
237
238 public void write(DataOutput out) throws IOException {
239 Encoder kvEncoder = codec.getEncoder((DataOutputStream) out);
240 out.writeInt(VERSION_2);
241
242
243 out.writeInt(kvs.size());
244 for(KeyValue kv: kvs){
245 kvEncoder.write(kv);
246 }
247 kvEncoder.flush();
248
249 out.writeInt(scopes.size());
250 for (byte[] key : scopes.keySet()) {
251 Bytes.writeByteArray(out, key);
252 out.writeInt(scopes.get(key));
253 }
254 }
255
256 public long heapSize() {
257 long ret = 0;
258 for (KeyValue kv : kvs) {
259 ret += kv.heapSize();
260 }
261 ret += ClassSize.TREEMAP;
262 ret += ClassSize.align(scopes.size() * ClassSize.MAP_ENTRY);
263
264 return ret;
265 }
266
267 public String toString() {
268 StringBuilder sb = new StringBuilder();
269
270 sb.append("[#edits: " + kvs.size() + " = <");
271 for (KeyValue kv : kvs) {
272 sb.append(kv.toString());
273 sb.append("; ");
274 }
275 sb.append(" scopes: " + scopes.toString());
276 sb.append(">]");
277 return sb.toString();
278 }
279 }