1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.NavigableMap;
25 import java.util.TreeMap;
26
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.classification.InterfaceStability;
29 import org.apache.hadoop.hbase.Cell;
30 import org.apache.hadoop.hbase.KeyValue;
31 import org.apache.hadoop.hbase.KeyValueUtil;
32 import org.apache.hadoop.hbase.io.TimeRange;
33 import org.apache.hadoop.hbase.util.Bytes;
34 import org.apache.hadoop.hbase.util.ClassSize;
35
36
37
38
39
40
41
42
43
44
45
46
47
48 @InterfaceAudience.Public
49 @InterfaceStability.Stable
50 public class Increment extends Mutation implements Comparable<Row> {
51 private static final long HEAP_OVERHEAD = ClassSize.REFERENCE + ClassSize.TIMERANGE;
52
53 private TimeRange tr = new TimeRange();
54
55
56
57
58
59
60
61 public Increment(byte [] row) {
62 this(row, 0, row.length);
63 }
64
65
66
67
68
69
70
71 public Increment(final byte [] row, final int offset, final int length) {
72 checkRow(row, offset, length);
73 this.row = Bytes.copy(row, offset, length);
74 }
75
76
77
78
79 public Increment(Increment i) {
80 this.row = i.getRow();
81 this.ts = i.getTimeStamp();
82 this.tr = i.getTimeRange();
83 this.familyMap.putAll(i.getFamilyCellMap());
84 for (Map.Entry<String, byte[]> entry : i.getAttributesMap().entrySet()) {
85 this.setAttribute(entry.getKey(), entry.getValue());
86 }
87 }
88
89
90
91
92
93
94
95 @SuppressWarnings("unchecked")
96 public Increment add(Cell cell) throws IOException{
97 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
98 byte [] family = kv.getFamily();
99 List<Cell> list = getCellList(family);
100
101 int res = Bytes.compareTo(this.row, 0, row.length,
102 kv.getBuffer(), kv.getRowOffset(), kv.getRowLength());
103 if (res != 0) {
104 throw new WrongRowIOException("The row in " + kv.toString() +
105 " doesn't match the original one " + Bytes.toStringBinary(this.row));
106 }
107 list.add(kv);
108 familyMap.put(family, list);
109 return this;
110 }
111
112
113
114
115
116
117
118
119
120
121
122 @SuppressWarnings("unchecked")
123 public Increment addColumn(byte [] family, byte [] qualifier, long amount) {
124 if (family == null) {
125 throw new IllegalArgumentException("family cannot be null");
126 }
127 if (qualifier == null) {
128 throw new IllegalArgumentException("qualifier cannot be null");
129 }
130 List<Cell> list = getCellList(family);
131 KeyValue kv = createPutKeyValue(family, qualifier, ts, Bytes.toBytes(amount));
132 list.add(kv);
133 familyMap.put(kv.getFamily(), list);
134 return this;
135 }
136
137
138
139
140
141 public TimeRange getTimeRange() {
142 return this.tr;
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 public Increment setTimeRange(long minStamp, long maxStamp)
160 throws IOException {
161 tr = new TimeRange(minStamp, maxStamp);
162 return this;
163 }
164
165
166
167
168
169 public int numFamilies() {
170 return this.familyMap.size();
171 }
172
173
174
175
176
177 public boolean hasFamilies() {
178 return !this.familyMap.isEmpty();
179 }
180
181
182
183
184
185
186
187
188
189 public Map<byte[], NavigableMap<byte [], Long>> getFamilyMapOfLongs() {
190 NavigableMap<byte[], List<Cell>> map = super.getFamilyCellMap();
191 Map<byte [], NavigableMap<byte[], Long>> results =
192 new TreeMap<byte[], NavigableMap<byte [], Long>>(Bytes.BYTES_COMPARATOR);
193 for (Map.Entry<byte [], List<Cell>> entry: map.entrySet()) {
194 NavigableMap<byte [], Long> longs = new TreeMap<byte [], Long>(Bytes.BYTES_COMPARATOR);
195 for (Cell cell: entry.getValue()) {
196 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
197 longs.put(kv.getQualifier(),
198 Bytes.toLong(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength()));
199 }
200 results.put(entry.getKey(), longs);
201 }
202 return results;
203 }
204
205
206
207
208 @Override
209 public String toString() {
210 StringBuilder sb = new StringBuilder();
211 sb.append("row=");
212 sb.append(Bytes.toStringBinary(this.row));
213 if(this.familyMap.size() == 0) {
214 sb.append(", no columns set to be incremented");
215 return sb.toString();
216 }
217 sb.append(", families=");
218 boolean moreThanOne = false;
219 for(Map.Entry<byte [], List<Cell>> entry: this.familyMap.entrySet()) {
220 if(moreThanOne) {
221 sb.append("), ");
222 } else {
223 moreThanOne = true;
224 sb.append("{");
225 }
226 sb.append("(family=");
227 sb.append(Bytes.toString(entry.getKey()));
228 sb.append(", columns=");
229 if(entry.getValue() == null) {
230 sb.append("NONE");
231 } else {
232 sb.append("{");
233 boolean moreThanOneB = false;
234 for(Cell cell : entry.getValue()) {
235 if(moreThanOneB) {
236 sb.append(", ");
237 } else {
238 moreThanOneB = true;
239 }
240 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
241 sb.append(Bytes.toStringBinary(kv.getKey()) + "+=" +
242 Bytes.toLong(kv.getValueArray(), kv.getValueOffset(), kv.getValueLength()));
243 }
244 sb.append("}");
245 }
246 }
247 sb.append("}");
248 return sb.toString();
249 }
250
251 @Override
252 public int compareTo(Row i) {
253
254 return Bytes.compareTo(this.getRow(), i.getRow());
255 }
256
257 @Override
258 public int hashCode() {
259
260
261 return Bytes.hashCode(this.getRow());
262 }
263
264 @Override
265 public boolean equals(Object obj) {
266
267 if (this == obj) {
268 return true;
269 }
270 if (obj == null || getClass() != obj.getClass()) {
271 return false;
272 }
273 Row other = (Row) obj;
274 return compareTo(other) == 0;
275 }
276
277 protected long extraHeapSize(){
278 return HEAP_OVERHEAD;
279 }
280 }