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
32 import org.apache.hadoop.hbase.KeyValue;
33 import org.apache.hadoop.hbase.codec.Decoder;
34 import org.apache.hadoop.hbase.codec.Encoder;
35 import org.apache.hadoop.hbase.io.HeapSize;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.ClassSize;
38 import org.apache.hadoop.io.Writable;
39
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 public class WALEdit implements Writable, HeapSize {
75
76 private final int VERSION_2 = -1;
77
78 private final ArrayList<KeyValue> kvs = new ArrayList<KeyValue>();
79 private NavigableMap<byte[], Integer> scopes;
80
81
82
83
84 private WALEditCodec codec = new WALEditCodec();
85
86 public WALEdit() {
87 }
88
89
90
91
92
93 @SuppressWarnings("javadoc")
94 public void setCompressionContext(final CompressionContext compression) {
95 this.codec.setCompression(compression);
96 }
97
98 public void setCodec(WALEditCodec codec) {
99 this.codec = codec;
100 }
101
102
103 public void add(KeyValue kv) {
104 this.kvs.add(kv);
105 }
106
107 public boolean isEmpty() {
108 return kvs.isEmpty();
109 }
110
111 public int size() {
112 return kvs.size();
113 }
114
115 public List<KeyValue> getKeyValues() {
116 return kvs;
117 }
118
119 public NavigableMap<byte[], Integer> getScopes() {
120 return scopes;
121 }
122
123
124 public void setScopes (NavigableMap<byte[], Integer> scopes) {
125
126
127 this.scopes = scopes;
128 }
129
130 public void readFields(DataInput in) throws IOException {
131 kvs.clear();
132 if (scopes != null) {
133 scopes.clear();
134 }
135 Decoder decoder = this.codec.getDecoder((DataInputStream) in);
136 int versionOrLength = in.readInt();
137 int length = versionOrLength;
138
139
140 if (versionOrLength == VERSION_2) {
141 length = in.readInt();
142 }
143
144
145 for(int i=0; i< length && decoder.advance(); i++) {
146 kvs.add(decoder.current());
147 }
148
149
150 if (versionOrLength == VERSION_2) {
151 int numFamilies = in.readInt();
152 if (numFamilies > 0) {
153 if (scopes == null) {
154 scopes = new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR);
155 }
156 for (int i = 0; i < numFamilies; i++) {
157 byte[] fam = Bytes.readByteArray(in);
158 int scope = in.readInt();
159 scopes.put(fam, scope);
160 }
161 }
162 }
163 }
164
165 public void write(DataOutput out) throws IOException {
166 Encoder kvEncoder = codec.getEncoder((DataOutputStream) out);
167 out.writeInt(VERSION_2);
168
169
170 out.writeInt(kvs.size());
171 for(KeyValue kv: kvs){
172 kvEncoder.write(kv);
173 }
174 kvEncoder.flush();
175
176 if (scopes == null) {
177 out.writeInt(0);
178 } else {
179 out.writeInt(scopes.size());
180 for (byte[] key : scopes.keySet()) {
181 Bytes.writeByteArray(out, key);
182 out.writeInt(scopes.get(key));
183 }
184 }
185 }
186
187 public long heapSize() {
188 long ret = 0;
189 for (KeyValue kv : kvs) {
190 ret += kv.heapSize();
191 }
192 if (scopes != null) {
193 ret += ClassSize.TREEMAP;
194 ret += ClassSize.align(scopes.size() * ClassSize.MAP_ENTRY);
195
196 }
197 return ret;
198 }
199
200 public String toString() {
201 StringBuilder sb = new StringBuilder();
202
203 sb.append("[#edits: " + kvs.size() + " = <");
204 for (KeyValue kv : kvs) {
205 sb.append(kv.toString());
206 sb.append("; ");
207 }
208 if (scopes != null) {
209 sb.append(" scopes: " + scopes.toString());
210 }
211 sb.append(">]");
212 return sb.toString();
213 }
214 }