1 package org.apache.helix;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.TreeMap;
26
27 import org.apache.helix.ZNRecordDelta.MergeOperation;
28 import org.apache.log4j.Logger;
29 import org.codehaus.jackson.annotate.JsonCreator;
30 import org.codehaus.jackson.annotate.JsonIgnore;
31 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
32 import org.codehaus.jackson.annotate.JsonProperty;
33
34
35
36
37
38
39 @JsonIgnoreProperties(ignoreUnknown = true)
40 public class ZNRecord
41 {
42 static Logger _logger = Logger.getLogger(ZNRecord.class);
43 private final String id;
44
45 @JsonIgnore(true)
46 public static final String LIST_FIELD_BOUND = "listField.bound";
47
48 @JsonIgnore(true)
49 public static final int SIZE_LIMIT = 1000 * 1024;
50
51
52 private List<ZNRecordDelta> _deltaList = new ArrayList<ZNRecordDelta>();
53
54 private Map<String, String> simpleFields;
55 private Map<String, Map<String, String>> mapFields;
56 private Map<String, List<String>> listFields;
57
58
59 private int _version;
60
61 private long _creationTime;
62
63 private long _modifiedTime;
64
65 @JsonCreator
66 public ZNRecord(@JsonProperty("id") String id)
67 {
68 this.id = id;
69 simpleFields = new TreeMap<String, String>();
70 mapFields = new TreeMap<String, Map<String, String>>();
71 listFields = new TreeMap<String, List<String>>();
72 }
73
74 public ZNRecord(ZNRecord record)
75 {
76 this(record, record.getId());
77 }
78
79 public ZNRecord(ZNRecord record, String id)
80 {
81 this(id);
82 simpleFields.putAll(record.getSimpleFields());
83 mapFields.putAll(record.getMapFields());
84 listFields.putAll(record.getListFields());
85 _version = record.getVersion();
86 _creationTime = record.getCreationTime();
87 _modifiedTime = record.getModifiedTime();
88 }
89
90 public ZNRecord(ZNRecord record, int version)
91 {
92 this(record);
93 _version = version;
94 }
95
96 @JsonIgnore(true)
97 public void setDeltaList(List<ZNRecordDelta> deltaList)
98 {
99 _deltaList = deltaList;
100 }
101
102 @JsonIgnore(true)
103 public List<ZNRecordDelta> getDeltaList()
104 {
105 return _deltaList;
106 }
107
108 @JsonProperty
109 public Map<String, String> getSimpleFields()
110 {
111 return simpleFields;
112 }
113
114 @JsonProperty
115 public void setSimpleFields(Map<String, String> simpleFields)
116 {
117 this.simpleFields = simpleFields;
118 }
119
120 @JsonProperty
121 public Map<String, Map<String, String>> getMapFields()
122 {
123 return mapFields;
124 }
125
126 @JsonProperty
127 public void setMapFields(Map<String, Map<String, String>> mapFields)
128 {
129 this.mapFields = mapFields;
130 }
131
132 @JsonProperty
133 public Map<String, List<String>> getListFields()
134 {
135 return listFields;
136 }
137
138 @JsonProperty
139 public void setListFields(Map<String, List<String>> listFields)
140 {
141 this.listFields = listFields;
142 }
143
144 @JsonProperty
145 public void setSimpleField(String k, String v)
146 {
147 simpleFields.put(k, v);
148 }
149
150 @JsonProperty
151 public String getId()
152 {
153 return id;
154 }
155
156 public void setMapField(String k, Map<String, String> v)
157 {
158 mapFields.put(k, v);
159 }
160
161 public void setListField(String k, List<String> v)
162 {
163 listFields.put(k, v);
164 }
165
166 public String getSimpleField(String k)
167 {
168 return simpleFields.get(k);
169 }
170
171 public Map<String, String> getMapField(String k)
172 {
173 return mapFields.get(k);
174 }
175
176 public List<String> getListField(String k)
177 {
178 return listFields.get(k);
179 }
180
181 @Override
182 public String toString()
183 {
184 StringBuffer sb = new StringBuffer();
185 sb.append(id + ", ");
186 if (simpleFields != null)
187 {
188 sb.append(simpleFields);
189 }
190 if (mapFields != null)
191 {
192 sb.append(mapFields);
193 }
194 if (listFields != null)
195 {
196 sb.append(listFields);
197 }
198 return sb.toString();
199 }
200
201
202
203
204
205
206
207
208 public void merge(ZNRecord record)
209 {
210 if (record == null)
211 {
212 return;
213 }
214
215 if (record.getDeltaList().size() > 0)
216 {
217 _logger.info("Merging with delta list, recordId = " + id + " other:"
218 + record.getId());
219 merge(record.getDeltaList());
220 return;
221 }
222 simpleFields.putAll(record.simpleFields);
223 for (String key : record.mapFields.keySet())
224 {
225 Map<String, String> map = mapFields.get(key);
226 if (map != null)
227 {
228 map.putAll(record.mapFields.get(key));
229 } else
230 {
231 mapFields.put(key, record.mapFields.get(key));
232 }
233 }
234 for (String key : record.listFields.keySet())
235 {
236 List<String> list = listFields.get(key);
237 if (list != null)
238 {
239 list.addAll(record.listFields.get(key));
240 } else
241 {
242 listFields.put(key, record.listFields.get(key));
243 }
244 }
245 }
246
247 void merge(ZNRecordDelta delta)
248 {
249 if (delta.getMergeOperation() == MergeOperation.ADD)
250 {
251 merge(delta.getRecord());
252 } else if (delta.getMergeOperation() == MergeOperation.SUBTRACT)
253 {
254 subtract(delta.getRecord());
255 }
256 }
257
258 void merge(List<ZNRecordDelta> deltaList)
259 {
260 for (ZNRecordDelta delta : deltaList)
261 {
262 merge(delta);
263 }
264 }
265
266 @Override
267 public boolean equals(Object obj)
268 {
269 if (!(obj instanceof ZNRecord))
270 {
271 return false;
272 }
273 ZNRecord that = (ZNRecord) obj;
274 if (this.getSimpleFields().size() != that.getSimpleFields().size())
275 {
276 return false;
277 }
278 if (this.getMapFields().size() != that.getMapFields().size())
279 {
280 return false;
281 }
282 if (this.getListFields().size() != that.getListFields().size())
283 {
284 return false;
285 }
286 if (!this.getSimpleFields().equals(that.getSimpleFields()))
287 {
288 return false;
289 }
290 if (!this.getMapFields().equals(that.getMapFields()))
291 {
292 return false;
293 }
294 if (!this.getListFields().equals(that.getListFields()))
295 {
296 return false;
297 }
298
299 return true;
300 }
301
302
303
304
305
306 public void subtract(ZNRecord value)
307 {
308 for (String key : value.getSimpleFields().keySet())
309 {
310 if (simpleFields.containsKey(key))
311 {
312 simpleFields.remove(key);
313 }
314 }
315
316 for (String key : value.getListFields().keySet())
317 {
318 if (listFields.containsKey(key))
319 {
320 listFields.remove(key);
321 }
322 }
323
324 for (String key : value.getMapFields().keySet())
325 {
326 if (mapFields.containsKey(key))
327 {
328 mapFields.remove(key);
329 }
330 }
331 }
332
333 @JsonIgnore(true)
334 public int getVersion()
335 {
336 return _version;
337 }
338
339 @JsonIgnore(true)
340 public void setVersion(int version)
341 {
342 _version = version;
343 }
344
345 @JsonIgnore(true)
346 public long getCreationTime()
347 {
348 return _creationTime;
349 }
350
351 @JsonIgnore(true)
352 public void setCreationTime(long creationTime)
353 {
354 _creationTime = creationTime;
355 }
356
357 @JsonIgnore(true)
358 public long getModifiedTime()
359 {
360 return _modifiedTime;
361 }
362
363 @JsonIgnore(true)
364 public void setModifiedTime(long modifiedTime)
365 {
366 _modifiedTime = modifiedTime;
367 }
368 }