1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.client;
22
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.TreeMap;
28 import java.util.UUID;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.KeyValue;
34 import org.apache.hadoop.hbase.util.Bytes;
35
36 public abstract class Mutation extends OperationWithAttributes implements Row {
37 private static final Log LOG = LogFactory.getLog(Mutation.class);
38
39 private static final String CLUSTER_ID_ATTR = "_c.id_";
40 private static final String DURABILITY_ID_ATTR = "_dur_";
41
42 protected byte [] row = null;
43 protected long ts = HConstants.LATEST_TIMESTAMP;
44 protected long lockId = -1L;
45 protected boolean writeToWAL = true;
46 protected Map<byte [], List<KeyValue>> familyMap =
47 new TreeMap<byte [], List<KeyValue>>(Bytes.BYTES_COMPARATOR);
48
49
50
51
52
53
54
55 @Override
56 public Map<String, Object> getFingerprint() {
57 Map<String, Object> map = new HashMap<String, Object>();
58 List<String> families = new ArrayList<String>();
59
60
61 map.put("families", families);
62 for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
63 families.add(Bytes.toStringBinary(entry.getKey()));
64 }
65 return map;
66 }
67
68
69
70
71
72
73
74
75 @Override
76 public Map<String, Object> toMap(int maxCols) {
77
78 Map<String, Object> map = getFingerprint();
79
80
81 Map<String, List<Map<String, Object>>> columns =
82 new HashMap<String, List<Map<String, Object>>>();
83 map.put("families", columns);
84 map.put("row", Bytes.toStringBinary(this.row));
85 int colCount = 0;
86
87 for (Map.Entry<byte [], List<KeyValue>> entry : this.familyMap.entrySet()) {
88
89 List<Map<String, Object>> qualifierDetails =
90 new ArrayList<Map<String, Object>>();
91 columns.put(Bytes.toStringBinary(entry.getKey()), qualifierDetails);
92 colCount += entry.getValue().size();
93 if (maxCols <= 0) {
94 continue;
95 }
96
97 for (KeyValue kv : entry.getValue()) {
98 if (--maxCols <= 0 ) {
99 continue;
100 }
101 Map<String, Object> kvMap = kv.toStringMap();
102
103 kvMap.remove("row");
104 kvMap.remove("family");
105 qualifierDetails.add(kvMap);
106 }
107 }
108 map.put("totalColumns", colCount);
109
110 if (getId() != null) {
111 map.put("id", getId());
112 }
113 return map;
114 }
115
116
117
118
119
120 public boolean getWriteToWAL() {
121 return this.writeToWAL;
122 }
123
124
125
126
127
128
129
130
131 public void setWriteToWAL(boolean write) {
132 setDurability(write ? Durability.USE_DEFAULT : Durability.SKIP_WAL);
133 }
134
135
136
137
138
139
140
141 public void setDurability(Durability d) {
142 setAttribute(DURABILITY_ID_ATTR, Bytes.toBytes(d.ordinal()));
143 this.writeToWAL = d != Durability.SKIP_WAL;
144 }
145
146
147 public Durability getDurability() {
148 byte[] attr = getAttribute(DURABILITY_ID_ATTR);
149 if (attr != null) {
150 try {
151 return Durability.valueOf(Bytes.toInt(attr));
152 } catch (IllegalArgumentException iax) {
153 LOG.warn("Invalid or unknown durability settting", iax);
154 }
155 }
156 return writeToWAL ? Durability.USE_DEFAULT : Durability.SKIP_WAL;
157 }
158
159
160
161
162
163 public Map<byte [], List<KeyValue>> getFamilyMap() {
164 return this.familyMap;
165 }
166
167
168
169
170 public void setFamilyMap(Map<byte [], List<KeyValue>> map) {
171 this.familyMap = map;
172 }
173
174
175
176
177
178 public boolean isEmpty() {
179 return familyMap.isEmpty();
180 }
181
182
183
184
185
186 @Override
187 public byte [] getRow() {
188 return this.row;
189 }
190
191 public int compareTo(final Row d) {
192 return Bytes.compareTo(this.getRow(), d.getRow());
193 }
194
195
196
197
198
199
200 public RowLock getRowLock() {
201 return new RowLock(this.row, this.lockId);
202 }
203
204
205
206
207
208
209
210 public long getLockId() {
211 return this.lockId;
212 }
213
214
215
216
217
218 public long getTimeStamp() {
219 return this.ts;
220 }
221
222
223
224
225
226 public void setClusterId(UUID clusterId) {
227 if (clusterId == null) return;
228 byte[] val = new byte[2*Bytes.SIZEOF_LONG];
229 Bytes.putLong(val, 0, clusterId.getMostSignificantBits());
230 Bytes.putLong(val, Bytes.SIZEOF_LONG, clusterId.getLeastSignificantBits());
231 setAttribute(CLUSTER_ID_ATTR, val);
232 }
233
234
235
236
237 public UUID getClusterId() {
238 byte[] attr = getAttribute(CLUSTER_ID_ATTR);
239 if (attr == null) {
240 return HConstants.DEFAULT_CLUSTER_ID;
241 }
242 return new UUID(Bytes.toLong(attr,0), Bytes.toLong(attr, Bytes.SIZEOF_LONG));
243 }
244
245
246
247
248 public int size() {
249 int size = 0;
250 for(List<KeyValue> kvList : this.familyMap.values()) {
251 size += kvList.size();
252 }
253 return size;
254 }
255
256
257
258
259 public int numFamilies() {
260 return familyMap.size();
261 }
262 }