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;
21
22 import java.io.DataInput;
23 import java.io.DataOutput;
24 import java.io.IOException;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Map;
29 import java.util.Set;
30 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
31 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
32 import org.apache.hadoop.hbase.io.hfile.Compression;
33 import org.apache.hadoop.hbase.io.hfile.HFile;
34 import org.apache.hadoop.hbase.regionserver.StoreFile;
35 import org.apache.hadoop.hbase.regionserver.StoreFile.BloomType;
36 import org.apache.hadoop.hbase.regionserver.wal.HLog;
37 import org.apache.hadoop.hbase.util.Bytes;
38 import org.apache.hadoop.io.Text;
39 import org.apache.hadoop.io.WritableComparable;
40
41
42
43
44
45
46
47
48
49
50 public class HColumnDescriptor implements WritableComparable<HColumnDescriptor> {
51
52
53
54
55
56
57
58
59
60 private static final byte COLUMN_DESCRIPTOR_VERSION = (byte) 9;
61
62
63 public static final String COMPRESSION = "COMPRESSION";
64 public static final String COMPRESSION_COMPACT = "COMPRESSION_COMPACT";
65 public static final String ENCODE_ON_DISK =
66 "ENCODE_ON_DISK";
67 public static final String DATA_BLOCK_ENCODING =
68 "DATA_BLOCK_ENCODING";
69 public static final String BLOCKCACHE = "BLOCKCACHE";
70 public static final String CACHE_DATA_ON_WRITE = "CACHE_DATA_ON_WRITE";
71 public static final String CACHE_INDEX_ON_WRITE = "CACHE_INDEX_ON_WRITE";
72 public static final String CACHE_BLOOMS_ON_WRITE = "CACHE_BLOOMS_ON_WRITE";
73 public static final String EVICT_BLOCKS_ON_CLOSE = "EVICT_BLOCKS_ON_CLOSE";
74
75
76
77
78
79
80 public static final String BLOCKSIZE = "BLOCKSIZE";
81
82 public static final String LENGTH = "LENGTH";
83 public static final String TTL = "TTL";
84 public static final String BLOOMFILTER = "BLOOMFILTER";
85 public static final String FOREVER = "FOREVER";
86 public static final String REPLICATION_SCOPE = "REPLICATION_SCOPE";
87 public static final String MIN_VERSIONS = "MIN_VERSIONS";
88 public static final String KEEP_DELETED_CELLS = "KEEP_DELETED_CELLS";
89
90
91
92
93 public static final String DEFAULT_COMPRESSION =
94 Compression.Algorithm.NONE.getName();
95
96
97
98
99
100
101 public static final boolean DEFAULT_ENCODE_ON_DISK = true;
102
103
104 public static final String DEFAULT_DATA_BLOCK_ENCODING =
105 DataBlockEncoding.NONE.toString();
106
107
108
109
110 public static final int DEFAULT_VERSIONS = 3;
111
112
113
114
115 public static final int DEFAULT_MIN_VERSIONS = 0;
116
117
118
119
120
121 private volatile Integer blocksize = null;
122
123
124
125
126 public static final boolean DEFAULT_IN_MEMORY = false;
127
128
129
130
131 public static final boolean DEFAULT_KEEP_DELETED = false;
132
133
134
135
136 public static final boolean DEFAULT_BLOCKCACHE = true;
137
138
139
140
141
142 public static final boolean DEFAULT_CACHE_DATA_ON_WRITE = false;
143
144
145
146
147
148 public static final boolean DEFAULT_CACHE_INDEX_ON_WRITE = false;
149
150
151
152
153 public static final int DEFAULT_BLOCKSIZE = HFile.DEFAULT_BLOCKSIZE;
154
155
156
157
158 public static final String DEFAULT_BLOOMFILTER = StoreFile.BloomType.NONE.toString();
159
160
161
162
163
164 public static final boolean DEFAULT_CACHE_BLOOMS_ON_WRITE = false;
165
166
167
168
169 public static final int DEFAULT_TTL = HConstants.FOREVER;
170
171
172
173
174 public static final int DEFAULT_REPLICATION_SCOPE = HConstants.REPLICATION_SCOPE_LOCAL;
175
176
177
178
179
180 public static final boolean DEFAULT_EVICT_BLOCKS_ON_CLOSE = false;
181
182 private final static Map<String, String> DEFAULT_VALUES = new HashMap<String, String>();
183 private final static Set<ImmutableBytesWritable> RESERVED_KEYWORDS
184 = new HashSet<ImmutableBytesWritable>();
185 static {
186 DEFAULT_VALUES.put(BLOOMFILTER, DEFAULT_BLOOMFILTER);
187 DEFAULT_VALUES.put(REPLICATION_SCOPE, String.valueOf(DEFAULT_REPLICATION_SCOPE));
188 DEFAULT_VALUES.put(HConstants.VERSIONS, String.valueOf(DEFAULT_VERSIONS));
189 DEFAULT_VALUES.put(MIN_VERSIONS, String.valueOf(DEFAULT_MIN_VERSIONS));
190 DEFAULT_VALUES.put(COMPRESSION, DEFAULT_COMPRESSION);
191 DEFAULT_VALUES.put(TTL, String.valueOf(DEFAULT_TTL));
192 DEFAULT_VALUES.put(BLOCKSIZE, String.valueOf(DEFAULT_BLOCKSIZE));
193 DEFAULT_VALUES.put(HConstants.IN_MEMORY, String.valueOf(DEFAULT_IN_MEMORY));
194 DEFAULT_VALUES.put(BLOCKCACHE, String.valueOf(DEFAULT_BLOCKCACHE));
195 DEFAULT_VALUES.put(KEEP_DELETED_CELLS, String.valueOf(DEFAULT_KEEP_DELETED));
196 DEFAULT_VALUES.put(ENCODE_ON_DISK,
197 String.valueOf(DEFAULT_ENCODE_ON_DISK));
198 DEFAULT_VALUES.put(DATA_BLOCK_ENCODING,
199 String.valueOf(DEFAULT_DATA_BLOCK_ENCODING));
200 DEFAULT_VALUES.put(CACHE_DATA_ON_WRITE,
201 String.valueOf(DEFAULT_CACHE_DATA_ON_WRITE));
202 DEFAULT_VALUES.put(CACHE_INDEX_ON_WRITE,
203 String.valueOf(DEFAULT_CACHE_INDEX_ON_WRITE));
204 DEFAULT_VALUES.put(CACHE_BLOOMS_ON_WRITE,
205 String.valueOf(DEFAULT_CACHE_BLOOMS_ON_WRITE));
206 DEFAULT_VALUES.put(EVICT_BLOCKS_ON_CLOSE,
207 String.valueOf(DEFAULT_EVICT_BLOCKS_ON_CLOSE));
208 for (String s : DEFAULT_VALUES.keySet()) {
209 RESERVED_KEYWORDS.add(new ImmutableBytesWritable(Bytes.toBytes(s)));
210 }
211 }
212
213
214 private byte [] name;
215
216
217 protected final Map<ImmutableBytesWritable,ImmutableBytesWritable> values =
218 new HashMap<ImmutableBytesWritable,ImmutableBytesWritable>();
219
220
221
222
223 private int cachedMaxVersions = -1;
224
225
226
227
228 public HColumnDescriptor() {
229 this.name = null;
230 }
231
232
233
234
235
236
237
238
239 public HColumnDescriptor(final String familyName) {
240 this(Bytes.toBytes(familyName));
241 }
242
243
244
245
246
247
248
249
250 public HColumnDescriptor(final byte [] familyName) {
251 this (familyName == null || familyName.length <= 0?
252 HConstants.EMPTY_BYTE_ARRAY: familyName, DEFAULT_VERSIONS,
253 DEFAULT_COMPRESSION, DEFAULT_IN_MEMORY, DEFAULT_BLOCKCACHE,
254 DEFAULT_TTL, DEFAULT_BLOOMFILTER);
255 }
256
257
258
259
260
261
262
263 public HColumnDescriptor(HColumnDescriptor desc) {
264 super();
265 this.name = desc.name.clone();
266 for (Map.Entry<ImmutableBytesWritable, ImmutableBytesWritable> e:
267 desc.values.entrySet()) {
268 this.values.put(e.getKey(), e.getValue());
269 }
270 setMaxVersions(desc.getMaxVersions());
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 @Deprecated
293 public HColumnDescriptor(final byte [] familyName, final int maxVersions,
294 final String compression, final boolean inMemory,
295 final boolean blockCacheEnabled,
296 final int timeToLive, final String bloomFilter) {
297 this(familyName, maxVersions, compression, inMemory, blockCacheEnabled,
298 DEFAULT_BLOCKSIZE, timeToLive, bloomFilter, DEFAULT_REPLICATION_SCOPE);
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 @Deprecated
325 public HColumnDescriptor(final byte [] familyName, final int maxVersions,
326 final String compression, final boolean inMemory,
327 final boolean blockCacheEnabled, final int blocksize,
328 final int timeToLive, final String bloomFilter, final int scope) {
329 this(familyName, DEFAULT_MIN_VERSIONS, maxVersions, DEFAULT_KEEP_DELETED,
330 compression, DEFAULT_ENCODE_ON_DISK, DEFAULT_DATA_BLOCK_ENCODING,
331 inMemory, blockCacheEnabled, blocksize, timeToLive, bloomFilter,
332 scope);
333 }
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 @Deprecated
365 public HColumnDescriptor(final byte[] familyName, final int minVersions,
366 final int maxVersions, final boolean keepDeletedCells,
367 final String compression, final boolean encodeOnDisk,
368 final String dataBlockEncoding, final boolean inMemory,
369 final boolean blockCacheEnabled, final int blocksize,
370 final int timeToLive, final String bloomFilter, final int scope) {
371 isLegalFamilyName(familyName);
372 this.name = familyName;
373
374 if (maxVersions <= 0) {
375
376
377 throw new IllegalArgumentException("Maximum versions must be positive");
378 }
379
380 if (minVersions > 0) {
381 if (timeToLive == HConstants.FOREVER) {
382 throw new IllegalArgumentException("Minimum versions requires TTL.");
383 }
384 if (minVersions >= maxVersions) {
385 throw new IllegalArgumentException("Minimum versions must be < "
386 + "maximum versions.");
387 }
388 }
389
390 setMaxVersions(maxVersions);
391 setMinVersions(minVersions);
392 setKeepDeletedCells(keepDeletedCells);
393 setInMemory(inMemory);
394 setBlockCacheEnabled(blockCacheEnabled);
395 setTimeToLive(timeToLive);
396 setCompressionType(Compression.Algorithm.
397 valueOf(compression.toUpperCase()));
398 setEncodeOnDisk(encodeOnDisk);
399 setDataBlockEncoding(DataBlockEncoding.
400 valueOf(dataBlockEncoding.toUpperCase()));
401 setBloomFilterType(StoreFile.BloomType.
402 valueOf(bloomFilter.toUpperCase()));
403 setBlocksize(blocksize);
404 setScope(scope);
405 }
406
407
408
409
410
411
412
413
414
415 public static byte [] isLegalFamilyName(final byte [] b) {
416 if (b == null) {
417 return b;
418 }
419 if (b[0] == '.') {
420 throw new IllegalArgumentException("Family names cannot start with a " +
421 "period: " + Bytes.toString(b));
422 }
423 for (int i = 0; i < b.length; i++) {
424 if (Character.isISOControl(b[i]) || b[i] == ':' || b[i] == '\\' || b[i] == '/') {
425 throw new IllegalArgumentException("Illegal character <" + b[i] +
426 ">. Family names cannot contain control characters or colons: " +
427 Bytes.toString(b));
428 }
429 }
430 byte[] recoveredEdit = Bytes.toBytes(HLog.RECOVERED_EDITS_DIR);
431 if (Bytes.equals(recoveredEdit, b)) {
432 throw new IllegalArgumentException("Family name cannot be: " +
433 HLog.RECOVERED_EDITS_DIR);
434 }
435 return b;
436 }
437
438
439
440
441 public byte [] getName() {
442 return name;
443 }
444
445
446
447
448 public String getNameAsString() {
449 return Bytes.toString(this.name);
450 }
451
452
453
454
455
456 public byte[] getValue(byte[] key) {
457 ImmutableBytesWritable ibw = values.get(new ImmutableBytesWritable(key));
458 if (ibw == null)
459 return null;
460 return ibw.get();
461 }
462
463
464
465
466
467 public String getValue(String key) {
468 byte[] value = getValue(Bytes.toBytes(key));
469 if (value == null)
470 return null;
471 return Bytes.toString(value);
472 }
473
474
475
476
477 public Map<ImmutableBytesWritable,ImmutableBytesWritable> getValues() {
478
479 return Collections.unmodifiableMap(values);
480 }
481
482
483
484
485
486
487 public HColumnDescriptor setValue(byte[] key, byte[] value) {
488 values.put(new ImmutableBytesWritable(key),
489 new ImmutableBytesWritable(value));
490 return this;
491 }
492
493
494
495
496 public void remove(final byte [] key) {
497 values.remove(new ImmutableBytesWritable(key));
498 }
499
500
501
502
503
504
505 public HColumnDescriptor setValue(String key, String value) {
506 if (value == null) {
507 remove(Bytes.toBytes(key));
508 } else {
509 setValue(Bytes.toBytes(key), Bytes.toBytes(value));
510 }
511 return this;
512 }
513
514
515 public Compression.Algorithm getCompression() {
516 String n = getValue(COMPRESSION);
517 if (n == null) {
518 return Compression.Algorithm.NONE;
519 }
520 return Compression.Algorithm.valueOf(n.toUpperCase());
521 }
522
523
524
525 public Compression.Algorithm getCompactionCompression() {
526 String n = getValue(COMPRESSION_COMPACT);
527 if (n == null) {
528 return getCompression();
529 }
530 return Compression.Algorithm.valueOf(n.toUpperCase());
531 }
532
533
534 public int getMaxVersions() {
535 return this.cachedMaxVersions;
536 }
537
538
539
540
541
542 public HColumnDescriptor setMaxVersions(int maxVersions) {
543 setValue(HConstants.VERSIONS, Integer.toString(maxVersions));
544 cachedMaxVersions = maxVersions;
545 return this;
546 }
547
548
549
550
551 public synchronized int getBlocksize() {
552 if (this.blocksize == null) {
553 String value = getValue(BLOCKSIZE);
554 this.blocksize = (value != null)?
555 Integer.decode(value): Integer.valueOf(DEFAULT_BLOCKSIZE);
556 }
557 return this.blocksize.intValue();
558 }
559
560
561
562
563
564
565 public HColumnDescriptor setBlocksize(int s) {
566 setValue(BLOCKSIZE, Integer.toString(s));
567 this.blocksize = null;
568 return this;
569 }
570
571
572
573
574 public Compression.Algorithm getCompressionType() {
575 return getCompression();
576 }
577
578
579
580
581
582
583
584
585
586 public HColumnDescriptor setCompressionType(Compression.Algorithm type) {
587 return setValue(COMPRESSION, type.getName().toUpperCase());
588 }
589
590
591 public DataBlockEncoding getDataBlockEncodingOnDisk() {
592 String encodeOnDiskStr = getValue(ENCODE_ON_DISK);
593 boolean encodeOnDisk;
594 if (encodeOnDiskStr == null) {
595 encodeOnDisk = DEFAULT_ENCODE_ON_DISK;
596 } else {
597 encodeOnDisk = Boolean.valueOf(encodeOnDiskStr);
598 }
599
600 if (!encodeOnDisk) {
601
602 return DataBlockEncoding.NONE;
603 }
604 return getDataBlockEncoding();
605 }
606
607
608
609
610
611
612 public HColumnDescriptor setEncodeOnDisk(boolean encodeOnDisk) {
613 return setValue(ENCODE_ON_DISK, String.valueOf(encodeOnDisk));
614 }
615
616
617
618
619
620 public DataBlockEncoding getDataBlockEncoding() {
621 String type = getValue(DATA_BLOCK_ENCODING);
622 if (type == null) {
623 type = DEFAULT_DATA_BLOCK_ENCODING;
624 }
625 return DataBlockEncoding.valueOf(type);
626 }
627
628
629
630
631
632
633 public HColumnDescriptor setDataBlockEncoding(DataBlockEncoding type) {
634 String name;
635 if (type != null) {
636 name = type.toString();
637 } else {
638 name = DataBlockEncoding.NONE.toString();
639 }
640 return setValue(DATA_BLOCK_ENCODING, name);
641 }
642
643
644
645
646 public Compression.Algorithm getCompactionCompressionType() {
647 return getCompactionCompression();
648 }
649
650
651
652
653
654
655
656
657
658 public HColumnDescriptor setCompactionCompressionType(
659 Compression.Algorithm type) {
660 return setValue(COMPRESSION_COMPACT, type.getName().toUpperCase());
661 }
662
663
664
665
666 public boolean isInMemory() {
667 String value = getValue(HConstants.IN_MEMORY);
668 if (value != null)
669 return Boolean.valueOf(value).booleanValue();
670 return DEFAULT_IN_MEMORY;
671 }
672
673
674
675
676
677
678 public HColumnDescriptor setInMemory(boolean inMemory) {
679 return setValue(HConstants.IN_MEMORY, Boolean.toString(inMemory));
680 }
681
682 public boolean getKeepDeletedCells() {
683 String value = getValue(KEEP_DELETED_CELLS);
684 if (value != null) {
685 return Boolean.valueOf(value).booleanValue();
686 }
687 return DEFAULT_KEEP_DELETED;
688 }
689
690
691
692
693
694
695 public HColumnDescriptor setKeepDeletedCells(boolean keepDeletedCells) {
696 return setValue(KEEP_DELETED_CELLS, Boolean.toString(keepDeletedCells));
697 }
698
699
700
701
702 public int getTimeToLive() {
703 String value = getValue(TTL);
704 return (value != null)? Integer.valueOf(value).intValue(): DEFAULT_TTL;
705 }
706
707
708
709
710
711 public HColumnDescriptor setTimeToLive(int timeToLive) {
712 return setValue(TTL, Integer.toString(timeToLive));
713 }
714
715
716
717
718 public int getMinVersions() {
719 String value = getValue(MIN_VERSIONS);
720 return (value != null)? Integer.valueOf(value).intValue(): 0;
721 }
722
723
724
725
726
727
728 public HColumnDescriptor setMinVersions(int minVersions) {
729 return setValue(MIN_VERSIONS, Integer.toString(minVersions));
730 }
731
732
733
734
735 public boolean isBlockCacheEnabled() {
736 String value = getValue(BLOCKCACHE);
737 if (value != null)
738 return Boolean.valueOf(value).booleanValue();
739 return DEFAULT_BLOCKCACHE;
740 }
741
742
743
744
745
746 public HColumnDescriptor setBlockCacheEnabled(boolean blockCacheEnabled) {
747 return setValue(BLOCKCACHE, Boolean.toString(blockCacheEnabled));
748 }
749
750
751
752
753 public StoreFile.BloomType getBloomFilterType() {
754 String n = getValue(BLOOMFILTER);
755 if (n == null) {
756 n = DEFAULT_BLOOMFILTER;
757 }
758 return StoreFile.BloomType.valueOf(n.toUpperCase());
759 }
760
761
762
763
764
765 public HColumnDescriptor setBloomFilterType(final StoreFile.BloomType bt) {
766 return setValue(BLOOMFILTER, bt.toString());
767 }
768
769
770
771
772 public int getScope() {
773 String value = getValue(REPLICATION_SCOPE);
774 if (value != null) {
775 return Integer.valueOf(value).intValue();
776 }
777 return DEFAULT_REPLICATION_SCOPE;
778 }
779
780
781
782
783
784 public HColumnDescriptor setScope(int scope) {
785 return setValue(REPLICATION_SCOPE, Integer.toString(scope));
786 }
787
788
789
790
791 public boolean shouldCacheDataOnWrite() {
792 String value = getValue(CACHE_DATA_ON_WRITE);
793 if (value != null) {
794 return Boolean.valueOf(value).booleanValue();
795 }
796 return DEFAULT_CACHE_DATA_ON_WRITE;
797 }
798
799
800
801
802
803 public HColumnDescriptor setCacheDataOnWrite(boolean value) {
804 return setValue(CACHE_DATA_ON_WRITE, Boolean.toString(value));
805 }
806
807
808
809
810 public boolean shouldCacheIndexesOnWrite() {
811 String value = getValue(CACHE_INDEX_ON_WRITE);
812 if (value != null) {
813 return Boolean.valueOf(value).booleanValue();
814 }
815 return DEFAULT_CACHE_INDEX_ON_WRITE;
816 }
817
818
819
820
821
822 public HColumnDescriptor setCacheIndexesOnWrite(boolean value) {
823 return setValue(CACHE_INDEX_ON_WRITE, Boolean.toString(value));
824 }
825
826
827
828
829 public boolean shouldCacheBloomsOnWrite() {
830 String value = getValue(CACHE_BLOOMS_ON_WRITE);
831 if (value != null) {
832 return Boolean.valueOf(value).booleanValue();
833 }
834 return DEFAULT_CACHE_BLOOMS_ON_WRITE;
835 }
836
837
838
839
840
841 public HColumnDescriptor setCacheBloomsOnWrite(boolean value) {
842 return setValue(CACHE_BLOOMS_ON_WRITE, Boolean.toString(value));
843 }
844
845
846
847
848
849 public boolean shouldEvictBlocksOnClose() {
850 String value = getValue(EVICT_BLOCKS_ON_CLOSE);
851 if (value != null) {
852 return Boolean.valueOf(value).booleanValue();
853 }
854 return DEFAULT_EVICT_BLOCKS_ON_CLOSE;
855 }
856
857
858
859
860
861
862 public HColumnDescriptor setEvictBlocksOnClose(boolean value) {
863 return setValue(EVICT_BLOCKS_ON_CLOSE, Boolean.toString(value));
864 }
865
866
867
868
869 @Override
870 public String toString() {
871 StringBuilder s = new StringBuilder();
872 s.append('{');
873 s.append(HConstants.NAME);
874 s.append(" => '");
875 s.append(Bytes.toString(name));
876 s.append("'");
877 s.append(getValues(true));
878 s.append('}');
879 return s.toString();
880 }
881
882
883
884
885 public String toStringCustomizedValues() {
886 StringBuilder s = new StringBuilder();
887 s.append('{');
888 s.append(HConstants.NAME);
889 s.append(" => '");
890 s.append(Bytes.toString(name));
891 s.append("'");
892 s.append(getValues(false));
893 s.append('}');
894 return s.toString();
895 }
896
897 private StringBuilder getValues(boolean printDefaults) {
898 StringBuilder s = new StringBuilder();
899
900 boolean hasConfigKeys = false;
901
902
903 for (ImmutableBytesWritable k : values.keySet()) {
904 if (!RESERVED_KEYWORDS.contains(k)) {
905 hasConfigKeys = true;
906 continue;
907 }
908 String key = Bytes.toString(k.get());
909 String value = Bytes.toString(values.get(k).get());
910 if (printDefaults
911 || !DEFAULT_VALUES.containsKey(key)
912 || !DEFAULT_VALUES.get(key).equalsIgnoreCase(value)) {
913 s.append(", ");
914 s.append(key);
915
916 s.append(" => ");
917 s.append('\'').append(value).append('\'');
918 }
919 }
920
921
922 if (hasConfigKeys) {
923 s.append(", ");
924 s.append(HConstants.CONFIG).append(" => ");
925 s.append('{');
926 boolean printComma = false;
927 for (ImmutableBytesWritable k : values.keySet()) {
928 if (RESERVED_KEYWORDS.contains(k)) {
929 continue;
930 }
931 String key = Bytes.toString(k.get());
932 String value = Bytes.toString(values.get(k).get());
933 if (printComma) {
934 s.append(", ");
935 }
936 printComma = true;
937 s.append('\'').append(key).append('\'');
938 s.append(" => ");
939 s.append('\'').append(value).append('\'');
940 }
941 s.append('}');
942 }
943 return s;
944 }
945
946 public static Map<String, String> getDefaultValues() {
947 return Collections.unmodifiableMap(DEFAULT_VALUES);
948 }
949
950
951
952
953 @Override
954 public boolean equals(Object obj) {
955 if (this == obj) {
956 return true;
957 }
958 if (obj == null) {
959 return false;
960 }
961 if (!(obj instanceof HColumnDescriptor)) {
962 return false;
963 }
964 return compareTo((HColumnDescriptor)obj) == 0;
965 }
966
967
968
969
970 @Override
971 public int hashCode() {
972 int result = Bytes.hashCode(this.name);
973 result ^= Byte.valueOf(COLUMN_DESCRIPTOR_VERSION).hashCode();
974 result ^= values.hashCode();
975 return result;
976 }
977
978
979
980 public void readFields(DataInput in) throws IOException {
981 int version = in.readByte();
982 if (version < 6) {
983 if (version <= 2) {
984 Text t = new Text();
985 t.readFields(in);
986 this.name = t.getBytes();
987
988
989
990
991 } else {
992 this.name = Bytes.readByteArray(in);
993 }
994 this.values.clear();
995 setMaxVersions(in.readInt());
996 int ordinal = in.readInt();
997 setCompressionType(Compression.Algorithm.values()[ordinal]);
998 setInMemory(in.readBoolean());
999 setBloomFilterType(in.readBoolean() ? BloomType.ROW : BloomType.NONE);
1000 if (getBloomFilterType() != BloomType.NONE && version < 5) {
1001
1002
1003
1004
1005 throw new UnsupportedClassVersionError(this.getClass().getName() +
1006 " does not support backward compatibility with versions older " +
1007 "than version 5");
1008 }
1009 if (version > 1) {
1010 setBlockCacheEnabled(in.readBoolean());
1011 }
1012 if (version > 2) {
1013 setTimeToLive(in.readInt());
1014 }
1015 } else {
1016
1017 this.name = Bytes.readByteArray(in);
1018 this.values.clear();
1019 int numValues = in.readInt();
1020 for (int i = 0; i < numValues; i++) {
1021 ImmutableBytesWritable key = new ImmutableBytesWritable();
1022 ImmutableBytesWritable value = new ImmutableBytesWritable();
1023 key.readFields(in);
1024 value.readFields(in);
1025
1026
1027 if (version < 8 && Bytes.toString(key.get()).equals(BLOOMFILTER)) {
1028 value.set(Bytes.toBytes(
1029 Boolean.getBoolean(Bytes.toString(value.get()))
1030 ? BloomType.ROW.toString()
1031 : BloomType.NONE.toString()));
1032 }
1033
1034 values.put(key, value);
1035 }
1036 if (version == 6) {
1037
1038 setValue(COMPRESSION, Compression.Algorithm.NONE.getName());
1039 }
1040 String value = getValue(HConstants.VERSIONS);
1041 this.cachedMaxVersions = (value != null)?
1042 Integer.valueOf(value).intValue(): DEFAULT_VERSIONS;
1043 }
1044 }
1045
1046 public void write(DataOutput out) throws IOException {
1047 out.writeByte(COLUMN_DESCRIPTOR_VERSION);
1048 Bytes.writeByteArray(out, this.name);
1049 out.writeInt(values.size());
1050 for (Map.Entry<ImmutableBytesWritable, ImmutableBytesWritable> e:
1051 values.entrySet()) {
1052 e.getKey().write(out);
1053 e.getValue().write(out);
1054 }
1055 }
1056
1057
1058
1059 public int compareTo(HColumnDescriptor o) {
1060 int result = Bytes.compareTo(this.name, o.getName());
1061 if (result == 0) {
1062
1063 result = this.values.hashCode() - o.values.hashCode();
1064 if (result < 0)
1065 result = -1;
1066 else if (result > 0)
1067 result = 1;
1068 }
1069 return result;
1070 }
1071 }