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.classification.InterfaceAudience;
28 import org.apache.hadoop.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
80
81
82 @SuppressWarnings("unchecked")
83 public Increment add(Cell cell) throws IOException{
84 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
85 byte [] family = kv.getFamily();
86 List<Cell> list = getCellList(family);
87
88 int res = Bytes.compareTo(this.row, 0, row.length,
89 kv.getBuffer(), kv.getRowOffset(), kv.getRowLength());
90 if (res != 0) {
91 throw new WrongRowIOException("The row in " + kv.toString() +
92 " doesn't match the original one " + Bytes.toStringBinary(this.row));
93 }
94 list.add(kv);
95 familyMap.put(family, list);
96 return this;
97 }
98
99
100
101
102
103
104
105
106
107
108
109 @SuppressWarnings("unchecked")
110 public Increment addColumn(byte [] family, byte [] qualifier, long amount) {
111 if (family == null) {
112 throw new IllegalArgumentException("family cannot be null");
113 }
114 if (qualifier == null) {
115 throw new IllegalArgumentException("qualifier cannot be null");
116 }
117 List<Cell> list = getCellList(family);
118 KeyValue kv = createPutKeyValue(family, qualifier, ts, Bytes.toBytes(amount));
119 list.add(kv);
120 familyMap.put(kv.getFamily(), list);
121 return this;
122 }
123
124
125
126
127
128 public TimeRange getTimeRange() {
129 return this.tr;
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public Increment setTimeRange(long minStamp, long maxStamp)
147 throws IOException {
148 tr = new TimeRange(minStamp, maxStamp);
149 return this;
150 }
151
152
153
154
155
156 public int numFamilies() {
157 return this.familyMap.size();
158 }
159
160
161
162
163
164 public boolean hasFamilies() {
165 return !this.familyMap.isEmpty();
166 }
167
168
169
170
171
172
173
174
175
176 public Map<byte[], NavigableMap<byte [], Long>> getFamilyMapOfLongs() {
177 NavigableMap<byte[], List<Cell>> map = super.getFamilyCellMap();
178 Map<byte [], NavigableMap<byte[], Long>> results =
179 new TreeMap<byte[], NavigableMap<byte [], Long>>(Bytes.BYTES_COMPARATOR);
180 for (Map.Entry<byte [], List<Cell>> entry: map.entrySet()) {
181 NavigableMap<byte [], Long> longs = new TreeMap<byte [], Long>(Bytes.BYTES_COMPARATOR);
182 for (Cell cell: entry.getValue()) {
183 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
184 longs.put(kv.getQualifier(), Bytes.toLong(kv.getValue()));
185 }
186 results.put(entry.getKey(), longs);
187 }
188 return results;
189 }
190
191
192
193
194 @Override
195 public String toString() {
196 StringBuilder sb = new StringBuilder();
197 sb.append("row=");
198 sb.append(Bytes.toStringBinary(this.row));
199 if(this.familyMap.size() == 0) {
200 sb.append(", no columns set to be incremented");
201 return sb.toString();
202 }
203 sb.append(", families=");
204 boolean moreThanOne = false;
205 for(Map.Entry<byte [], List<Cell>> entry: this.familyMap.entrySet()) {
206 if(moreThanOne) {
207 sb.append("), ");
208 } else {
209 moreThanOne = true;
210 sb.append("{");
211 }
212 sb.append("(family=");
213 sb.append(Bytes.toString(entry.getKey()));
214 sb.append(", columns=");
215 if(entry.getValue() == null) {
216 sb.append("NONE");
217 } else {
218 sb.append("{");
219 boolean moreThanOneB = false;
220 for(Cell cell : entry.getValue()) {
221 if(moreThanOneB) {
222 sb.append(", ");
223 } else {
224 moreThanOneB = true;
225 }
226 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
227 sb.append(Bytes.toStringBinary(kv.getKey()) + "+=" + Bytes.toLong(kv.getValue()));
228 }
229 sb.append("}");
230 }
231 }
232 sb.append("}");
233 return sb.toString();
234 }
235
236 @Override
237 public int compareTo(Row i) {
238
239 return Bytes.compareTo(this.getRow(), i.getRow());
240 }
241
242 @Override
243 public int hashCode() {
244
245
246 return Bytes.hashCode(this.getRow());
247 }
248
249 @Override
250 public boolean equals(Object obj) {
251
252 if (this == obj) {
253 return true;
254 }
255 if (obj == null || getClass() != obj.getClass()) {
256 return false;
257 }
258 Row other = (Row) obj;
259 return compareTo(other) == 0;
260 }
261
262 protected long extraHeapSize(){
263 return HEAP_OVERHEAD;
264 }
265 }