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