1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 package org.rocksdb;
7 
8 import java.util.*;
9 
10 import org.junit.ClassRule;
11 import org.junit.Rule;
12 import org.junit.Test;
13 import org.junit.rules.TemporaryFolder;
14 
15 import static java.nio.charset.StandardCharsets.UTF_8;
16 import static org.assertj.core.api.Assertions.assertThat;
17 
18 public class ColumnFamilyTest {
19 
20   @ClassRule
21   public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE =
22       new RocksNativeLibraryResource();
23 
24   @Rule
25   public TemporaryFolder dbFolder = new TemporaryFolder();
26 
27   @Test
28   public void columnFamilyDescriptorName() throws RocksDBException {
29     final byte[] cfName = "some_name".getBytes(UTF_8);
startswith(StringRef Magic,const char (& S)[N])30 
31     try(final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions()) {
32       final ColumnFamilyDescriptor cfDescriptor =
33               new ColumnFamilyDescriptor(cfName, cfOptions);
34       assertThat(cfDescriptor.getName()).isEqualTo(cfName);
35     }
36   }
37 
38   @Test
39   public void columnFamilyDescriptorOptions() throws RocksDBException {
40     final byte[] cfName = "some_name".getBytes(UTF_8);
41 
42     try(final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions()
43             .setCompressionType(CompressionType.BZLIB2_COMPRESSION)) {
44       final ColumnFamilyDescriptor cfDescriptor =
45           new ColumnFamilyDescriptor(cfName, cfOptions);
46 
47         assertThat(cfDescriptor.getOptions().compressionType())
48             .isEqualTo(CompressionType.BZLIB2_COMPRESSION);
49     }
50   }
51 
52   @Test
53   public void listColumnFamilies() throws RocksDBException {
54     try (final Options options = new Options().setCreateIfMissing(true);
55          final RocksDB db = RocksDB.open(options,
56              dbFolder.getRoot().getAbsolutePath())) {
57       // Test listColumnFamilies
58       final List<byte[]> columnFamilyNames = RocksDB.listColumnFamilies(options,
59           dbFolder.getRoot().getAbsolutePath());
60       assertThat(columnFamilyNames).isNotNull();
61       assertThat(columnFamilyNames.size()).isGreaterThan(0);
62       assertThat(columnFamilyNames.size()).isEqualTo(1);
63       assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default");
64     }
65   }
66 
67   @Test
68   public void defaultColumnFamily() throws RocksDBException {
69     try (final Options options = new Options().setCreateIfMissing(true);
70          final RocksDB db = RocksDB.open(options,
71              dbFolder.getRoot().getAbsolutePath())) {
72       final ColumnFamilyHandle cfh = db.getDefaultColumnFamily();
73       try {
74         assertThat(cfh).isNotNull();
75 
76         assertThat(cfh.getName()).isEqualTo("default".getBytes(UTF_8));
77         assertThat(cfh.getID()).isEqualTo(0);
78 
79         final byte[] key = "key".getBytes();
80         final byte[] value = "value".getBytes();
81 
82         db.put(cfh, key, value);
83 
84         final byte[] actualValue = db.get(cfh, key);
85 
86         assertThat(cfh).isNotNull();
87         assertThat(actualValue).isEqualTo(value);
88       } finally {
89         cfh.close();
90       }
91     }
92   }
93 
94   @Test
95   public void createColumnFamily() throws RocksDBException {
96     final byte[] cfName = "new_cf".getBytes(UTF_8);
97     final ColumnFamilyDescriptor cfDescriptor = new ColumnFamilyDescriptor(cfName,
98             new ColumnFamilyOptions());
99 
100     try (final Options options = new Options().setCreateIfMissing(true);
101          final RocksDB db = RocksDB.open(options,
102                  dbFolder.getRoot().getAbsolutePath())) {
103 
104       final ColumnFamilyHandle columnFamilyHandle = db.createColumnFamily(cfDescriptor);
105 
106       try {
107         assertThat(columnFamilyHandle.getName()).isEqualTo(cfName);
108         assertThat(columnFamilyHandle.getID()).isEqualTo(1);
109 
110         final ColumnFamilyDescriptor latestDescriptor = columnFamilyHandle.getDescriptor();
111         assertThat(latestDescriptor.getName()).isEqualTo(cfName);
112 
113         final List<byte[]> columnFamilyNames = RocksDB.listColumnFamilies(
114                 options, dbFolder.getRoot().getAbsolutePath());
115         assertThat(columnFamilyNames).isNotNull();
116         assertThat(columnFamilyNames.size()).isGreaterThan(0);
117         assertThat(columnFamilyNames.size()).isEqualTo(2);
118         assertThat(new String(columnFamilyNames.get(0))).isEqualTo("default");
119         assertThat(new String(columnFamilyNames.get(1))).isEqualTo("new_cf");
120       } finally {
121         columnFamilyHandle.close();
122       }
123     }
124   }
125 
126   @Test
127   public void openWithColumnFamilies() throws RocksDBException {
128     final List<ColumnFamilyDescriptor> cfNames = Arrays.asList(
129         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
130         new ColumnFamilyDescriptor("new_cf".getBytes())
131     );
132 
133     final List<ColumnFamilyHandle> columnFamilyHandleList =
134         new ArrayList<>();
135 
136     // Test open database with column family names
137     try (final DBOptions options = new DBOptions()
138         .setCreateIfMissing(true)
139         .setCreateMissingColumnFamilies(true);
140          final RocksDB db = RocksDB.open(options,
141              dbFolder.getRoot().getAbsolutePath(), cfNames,
142              columnFamilyHandleList)) {
143 
144       try {
145         assertThat(columnFamilyHandleList.size()).isEqualTo(2);
146         db.put("dfkey1".getBytes(), "dfvalue".getBytes());
147         db.put(columnFamilyHandleList.get(0), "dfkey2".getBytes(),
148             "dfvalue".getBytes());
149         db.put(columnFamilyHandleList.get(1), "newcfkey1".getBytes(),
150             "newcfvalue".getBytes());
151 
152         String retVal = new String(db.get(columnFamilyHandleList.get(1),
153             "newcfkey1".getBytes()));
154         assertThat(retVal).isEqualTo("newcfvalue");
155         assertThat((db.get(columnFamilyHandleList.get(1),
156             "dfkey1".getBytes()))).isNull();
157         db.delete(columnFamilyHandleList.get(1), "newcfkey1".getBytes());
158         assertThat((db.get(columnFamilyHandleList.get(1),
159             "newcfkey1".getBytes()))).isNull();
160         db.delete(columnFamilyHandleList.get(0), new WriteOptions(),
161             "dfkey2".getBytes());
162         assertThat(db.get(columnFamilyHandleList.get(0), new ReadOptions(),
163             "dfkey2".getBytes())).isNull();
164       } finally {
165         for (final ColumnFamilyHandle columnFamilyHandle :
166             columnFamilyHandleList) {
167           columnFamilyHandle.close();
168         }
169       }
170     }
171   }
172 
173   @Test
174   public void getWithOutValueAndCf() throws RocksDBException {
175     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
176         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY));
177     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
178 
179     // Test open database with column family names
180     try (final DBOptions options = new DBOptions()
181         .setCreateIfMissing(true)
182         .setCreateMissingColumnFamilies(true);
183          final RocksDB db = RocksDB.open(options,
184              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
185              columnFamilyHandleList)) {
186       try {
187         db.put(columnFamilyHandleList.get(0), new WriteOptions(),
188             "key1".getBytes(), "value".getBytes());
189         db.put("key2".getBytes(), "12345678".getBytes());
190         final byte[] outValue = new byte[5];
191         // not found value
192         int getResult = db.get("keyNotFound".getBytes(), outValue);
193         assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
194         // found value which fits in outValue
195         getResult = db.get(columnFamilyHandleList.get(0), "key1".getBytes(),
196             outValue);
197         assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
198         assertThat(outValue).isEqualTo("value".getBytes());
199         // found value which fits partially
200         getResult = db.get(columnFamilyHandleList.get(0), new ReadOptions(),
201             "key2".getBytes(), outValue);
202         assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
203         assertThat(outValue).isEqualTo("12345".getBytes());
204       } finally {
205         for (final ColumnFamilyHandle columnFamilyHandle :
206             columnFamilyHandleList) {
207           columnFamilyHandle.close();
identify_magic(const Twine & Path,file_magic & Result)208         }
209       }
210     }
211   }
212 
213   @Test
214   public void createWriteDropColumnFamily() throws RocksDBException {
215     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
216         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
217         new ColumnFamilyDescriptor("new_cf".getBytes()));
218     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
219     try (final DBOptions options = new DBOptions()
220         .setCreateIfMissing(true)
221         .setCreateMissingColumnFamilies(true);
222          final RocksDB db = RocksDB.open(options,
223              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
224              columnFamilyHandleList)) {
225       ColumnFamilyHandle tmpColumnFamilyHandle = null;
226       try {
227         tmpColumnFamilyHandle = db.createColumnFamily(
228             new ColumnFamilyDescriptor("tmpCF".getBytes(),
229                 new ColumnFamilyOptions()));
230         db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes());
231         db.dropColumnFamily(tmpColumnFamilyHandle);
232         assertThat(tmpColumnFamilyHandle.isOwningHandle()).isTrue();
233       } finally {
234         if (tmpColumnFamilyHandle != null) {
235           tmpColumnFamilyHandle.close();
236         }
237         for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
238           columnFamilyHandle.close();
239         }
240       }
241     }
242   }
243 
244   @Test
245   public void createWriteDropColumnFamilies() throws RocksDBException {
246     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
247         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
248         new ColumnFamilyDescriptor("new_cf".getBytes()));
249     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
250     try (final DBOptions options = new DBOptions()
251         .setCreateIfMissing(true)
252         .setCreateMissingColumnFamilies(true);
253          final RocksDB db = RocksDB.open(options,
254              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
255              columnFamilyHandleList)) {
256       ColumnFamilyHandle tmpColumnFamilyHandle = null;
257       ColumnFamilyHandle tmpColumnFamilyHandle2 = null;
258       try {
259         tmpColumnFamilyHandle = db.createColumnFamily(
260             new ColumnFamilyDescriptor("tmpCF".getBytes(),
261                 new ColumnFamilyOptions()));
262         tmpColumnFamilyHandle2 = db.createColumnFamily(
263             new ColumnFamilyDescriptor("tmpCF2".getBytes(),
264                 new ColumnFamilyOptions()));
265         db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes());
266         db.put(tmpColumnFamilyHandle2, "key".getBytes(), "value".getBytes());
267         db.dropColumnFamilies(Arrays.asList(tmpColumnFamilyHandle, tmpColumnFamilyHandle2));
268         assertThat(tmpColumnFamilyHandle.isOwningHandle()).isTrue();
269         assertThat(tmpColumnFamilyHandle2.isOwningHandle()).isTrue();
270       } finally {
271         if (tmpColumnFamilyHandle != null) {
272           tmpColumnFamilyHandle.close();
273         }
274         if (tmpColumnFamilyHandle2 != null) {
275           tmpColumnFamilyHandle2.close();
276         }
277         for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
278           columnFamilyHandle.close();
279         }
280       }
281     }
282   }
283 
284   @Test
285   public void writeBatch() throws RocksDBException {
286     try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
287          final ColumnFamilyOptions defaultCfOptions = new ColumnFamilyOptions()
288              .setMergeOperator(stringAppendOperator)) {
289       final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
290           new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY,
291               defaultCfOptions),
292           new ColumnFamilyDescriptor("new_cf".getBytes()));
293       final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
294       try (final DBOptions options = new DBOptions()
295           .setCreateIfMissing(true)
296           .setCreateMissingColumnFamilies(true);
297            final RocksDB db = RocksDB.open(options,
298                dbFolder.getRoot().getAbsolutePath(),
299                cfDescriptors, columnFamilyHandleList);
300            final WriteBatch writeBatch = new WriteBatch();
301            final WriteOptions writeOpt = new WriteOptions()) {
302         try {
303           writeBatch.put("key".getBytes(), "value".getBytes());
304           writeBatch.put(db.getDefaultColumnFamily(),
305               "mergeKey".getBytes(), "merge".getBytes());
306           writeBatch.merge(db.getDefaultColumnFamily(), "mergeKey".getBytes(),
307               "merge".getBytes());
308           writeBatch.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
309               "value".getBytes());
310           writeBatch.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(),
311               "value2".getBytes());
312           writeBatch.delete("xyz".getBytes());
313           writeBatch.delete(columnFamilyHandleList.get(1), "xyz".getBytes());
314           db.write(writeOpt, writeBatch);
315 
316           assertThat(db.get(columnFamilyHandleList.get(1),
317               "xyz".getBytes()) == null);
318           assertThat(new String(db.get(columnFamilyHandleList.get(1),
319               "newcfkey".getBytes()))).isEqualTo("value");
320           assertThat(new String(db.get(columnFamilyHandleList.get(1),
321               "newcfkey2".getBytes()))).isEqualTo("value2");
322           assertThat(new String(db.get("key".getBytes()))).isEqualTo("value");
323           // check if key is merged
324           assertThat(new String(db.get(db.getDefaultColumnFamily(),
325               "mergeKey".getBytes()))).isEqualTo("merge,merge");
326         } finally {
327           for (final ColumnFamilyHandle columnFamilyHandle :
328               columnFamilyHandleList) {
329             columnFamilyHandle.close();
330           }
331         }
332       }
333     }
334   }
335 
336   @Test
337   public void iteratorOnColumnFamily() throws RocksDBException {
338     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
339         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
340         new ColumnFamilyDescriptor("new_cf".getBytes()));
341     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
342     try (final DBOptions options = new DBOptions()
343         .setCreateIfMissing(true)
344         .setCreateMissingColumnFamilies(true);
345          final RocksDB db = RocksDB.open(options,
346              dbFolder.getRoot().getAbsolutePath(),
347              cfDescriptors, columnFamilyHandleList)) {
348       try {
349 
350         db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
351             "value".getBytes());
352         db.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(),
353             "value2".getBytes());
354         try (final RocksIterator rocksIterator =
355                  db.newIterator(columnFamilyHandleList.get(1))) {
356           rocksIterator.seekToFirst();
357           Map<String, String> refMap = new HashMap<>();
358           refMap.put("newcfkey", "value");
359           refMap.put("newcfkey2", "value2");
360           int i = 0;
361           while (rocksIterator.isValid()) {
362             i++;
363             assertThat(refMap.get(new String(rocksIterator.key()))).
364                 isEqualTo(new String(rocksIterator.value()));
365             rocksIterator.next();
366           }
367           assertThat(i).isEqualTo(2);
368         }
369       } finally {
370         for (final ColumnFamilyHandle columnFamilyHandle :
371             columnFamilyHandleList) {
372           columnFamilyHandle.close();
373         }
374       }
375     }
376   }
377 
378   @Test
379   public void multiGet() throws RocksDBException {
380     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
381         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
382         new ColumnFamilyDescriptor("new_cf".getBytes()));
383     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
384     try (final DBOptions options = new DBOptions()
385         .setCreateIfMissing(true)
386         .setCreateMissingColumnFamilies(true);
387          final RocksDB db = RocksDB.open(options,
388              dbFolder.getRoot().getAbsolutePath(),
389              cfDescriptors, columnFamilyHandleList)) {
390       try {
391         db.put(columnFamilyHandleList.get(0), "key".getBytes(),
392             "value".getBytes());
393         db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
394             "value".getBytes());
395 
396         final List<byte[]> keys = Arrays.asList(new byte[][]{
397             "key".getBytes(), "newcfkey".getBytes()
398         });
399 
400         List<byte[]> retValues = db.multiGetAsList(columnFamilyHandleList, keys);
401         assertThat(retValues.size()).isEqualTo(2);
402         assertThat(new String(retValues.get(0)))
403             .isEqualTo("value");
404         assertThat(new String(retValues.get(1)))
405             .isEqualTo("value");
406         retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList,
407             keys);
408         assertThat(retValues.size()).isEqualTo(2);
409         assertThat(new String(retValues.get(0)))
410             .isEqualTo("value");
411         assertThat(new String(retValues.get(1)))
412             .isEqualTo("value");
413       } finally {
414         for (final ColumnFamilyHandle columnFamilyHandle :
415             columnFamilyHandleList) {
416           columnFamilyHandle.close();
417         }
418       }
419     }
420   }
421 
422   @Test
423   public void multiGetAsList() throws RocksDBException {
424     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
425         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
426         new ColumnFamilyDescriptor("new_cf".getBytes()));
427     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
428     try (final DBOptions options = new DBOptions()
429         .setCreateIfMissing(true)
430         .setCreateMissingColumnFamilies(true);
431          final RocksDB db = RocksDB.open(options,
432              dbFolder.getRoot().getAbsolutePath(),
433              cfDescriptors, columnFamilyHandleList)) {
434       try {
435         db.put(columnFamilyHandleList.get(0), "key".getBytes(),
436             "value".getBytes());
437         db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
438             "value".getBytes());
439 
440         final List<byte[]> keys = Arrays.asList(new byte[][]{
441             "key".getBytes(), "newcfkey".getBytes()
442         });
443         List<byte[]> retValues = db.multiGetAsList(columnFamilyHandleList,
444             keys);
445         assertThat(retValues.size()).isEqualTo(2);
446         assertThat(new String(retValues.get(0)))
447             .isEqualTo("value");
448         assertThat(new String(retValues.get(1)))
449             .isEqualTo("value");
450         retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList,
451             keys);
452         assertThat(retValues.size()).isEqualTo(2);
453         assertThat(new String(retValues.get(0)))
454             .isEqualTo("value");
455         assertThat(new String(retValues.get(1)))
456             .isEqualTo("value");
457       } finally {
458         for (final ColumnFamilyHandle columnFamilyHandle :
459             columnFamilyHandleList) {
460           columnFamilyHandle.close();
461         }
462       }
463     }
464   }
465 
466   @Test
467   public void properties() throws RocksDBException {
468     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
469         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
470         new ColumnFamilyDescriptor("new_cf".getBytes()));
471     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
472     try (final DBOptions options = new DBOptions()
473         .setCreateIfMissing(true)
474         .setCreateMissingColumnFamilies(true);
475          final RocksDB db = RocksDB.open(options,
476              dbFolder.getRoot().getAbsolutePath(),
477              cfDescriptors, columnFamilyHandleList)) {
478       try {
479         assertThat(db.getProperty("rocksdb.estimate-num-keys")).
480             isNotNull();
481         assertThat(db.getLongProperty(columnFamilyHandleList.get(0),
482             "rocksdb.estimate-num-keys")).isGreaterThanOrEqualTo(0);
483         assertThat(db.getProperty("rocksdb.stats")).isNotNull();
484         assertThat(db.getProperty(columnFamilyHandleList.get(0),
485             "rocksdb.sstables")).isNotNull();
486         assertThat(db.getProperty(columnFamilyHandleList.get(1),
487             "rocksdb.estimate-num-keys")).isNotNull();
488         assertThat(db.getProperty(columnFamilyHandleList.get(1),
489             "rocksdb.stats")).isNotNull();
490         assertThat(db.getProperty(columnFamilyHandleList.get(1),
491             "rocksdb.sstables")).isNotNull();
492         assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys")).
493             isNotNull();
494         assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys")).
495             isGreaterThanOrEqualTo(0);
496       } finally {
497         for (final ColumnFamilyHandle columnFamilyHandle :
498             columnFamilyHandleList) {
499           columnFamilyHandle.close();
500         }
501       }
502     }
503   }
504 
505 
506   @Test
507   public void iterators() throws RocksDBException {
508     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
509         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
510         new ColumnFamilyDescriptor("new_cf".getBytes()));
511     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
512     try (final DBOptions options = new DBOptions()
513         .setCreateIfMissing(true)
514         .setCreateMissingColumnFamilies(true);
515          final RocksDB db = RocksDB.open(options,
516              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
517              columnFamilyHandleList)) {
518       List<RocksIterator> iterators = null;
519       try {
520         iterators = db.newIterators(columnFamilyHandleList);
521         assertThat(iterators.size()).isEqualTo(2);
522         RocksIterator iter = iterators.get(0);
523         iter.seekToFirst();
524         final Map<String, String> defRefMap = new HashMap<>();
525         defRefMap.put("dfkey1", "dfvalue");
526         defRefMap.put("key", "value");
527         while (iter.isValid()) {
528           assertThat(defRefMap.get(new String(iter.key()))).
529               isEqualTo(new String(iter.value()));
530           iter.next();
531         }
532         // iterate over new_cf key/value pairs
533         final Map<String, String> cfRefMap = new HashMap<>();
534         cfRefMap.put("newcfkey", "value");
535         cfRefMap.put("newcfkey2", "value2");
536         iter = iterators.get(1);
537         iter.seekToFirst();
538         while (iter.isValid()) {
539           assertThat(cfRefMap.get(new String(iter.key()))).
540               isEqualTo(new String(iter.value()));
541           iter.next();
542         }
543       } finally {
544         if (iterators != null) {
545           for (final RocksIterator rocksIterator : iterators) {
546             rocksIterator.close();
547           }
548         }
549         for (final ColumnFamilyHandle columnFamilyHandle :
550             columnFamilyHandleList) {
551           columnFamilyHandle.close();
552         }
553       }
554     }
555   }
556 
557   @Test(expected = RocksDBException.class)
558   public void failPutDisposedCF() throws RocksDBException {
559     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
560         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
561         new ColumnFamilyDescriptor("new_cf".getBytes()));
562     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
563     try (final DBOptions options = new DBOptions()
564         .setCreateIfMissing(true);
565          final RocksDB db = RocksDB.open(options,
566              dbFolder.getRoot().getAbsolutePath(),
567              cfDescriptors, columnFamilyHandleList)) {
568       try {
569         db.dropColumnFamily(columnFamilyHandleList.get(1));
570         db.put(columnFamilyHandleList.get(1), "key".getBytes(),
571             "value".getBytes());
572       } finally {
573         for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
574           columnFamilyHandle.close();
575         }
576       }
577     }
578   }
579 
580   @Test(expected = RocksDBException.class)
581   public void failRemoveDisposedCF() throws RocksDBException {
582     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
583         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
584         new ColumnFamilyDescriptor("new_cf".getBytes()));
585     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
586     try (final DBOptions options = new DBOptions()
587         .setCreateIfMissing(true);
588          final RocksDB db = RocksDB.open(options,
589              dbFolder.getRoot().getAbsolutePath(),
590              cfDescriptors, columnFamilyHandleList)) {
591       try {
592         db.dropColumnFamily(columnFamilyHandleList.get(1));
593         db.delete(columnFamilyHandleList.get(1), "key".getBytes());
594       } finally {
595         for (final ColumnFamilyHandle columnFamilyHandle :
596             columnFamilyHandleList) {
597           columnFamilyHandle.close();
598         }
599       }
600     }
601   }
602 
603   @Test(expected = RocksDBException.class)
604   public void failGetDisposedCF() throws RocksDBException {
605     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
606         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
607         new ColumnFamilyDescriptor("new_cf".getBytes()));
608     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
609     try (final DBOptions options = new DBOptions()
610         .setCreateIfMissing(true);
611          final RocksDB db = RocksDB.open(options,
612              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
613              columnFamilyHandleList)) {
614       try {
615         db.dropColumnFamily(columnFamilyHandleList.get(1));
616         db.get(columnFamilyHandleList.get(1), "key".getBytes());
617       } finally {
618         for (final ColumnFamilyHandle columnFamilyHandle :
619             columnFamilyHandleList) {
620           columnFamilyHandle.close();
621         }
622       }
623     }
624   }
625 
626   @Test(expected = RocksDBException.class)
627   public void failMultiGetWithoutCorrectNumberOfCF() throws RocksDBException {
628     final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
629         new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
630         new ColumnFamilyDescriptor("new_cf".getBytes()));
631     final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
632     try (final DBOptions options = new DBOptions()
633         .setCreateIfMissing(true);
634          final RocksDB db = RocksDB.open(options,
635              dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
636              columnFamilyHandleList)) {
637       try {
638         final List<byte[]> keys = new ArrayList<>();
639         keys.add("key".getBytes());
640         keys.add("newcfkey".getBytes());
641         final List<ColumnFamilyHandle> cfCustomList = new ArrayList<>();
642         db.multiGetAsList(cfCustomList, keys);
643 
644       } finally {
645         for (final ColumnFamilyHandle columnFamilyHandle :
646             columnFamilyHandleList) {
647           columnFamilyHandle.close();
648         }
649       }
650     }
651   }
652 
653   @Test
654   public void testByteCreateFolumnFamily() throws RocksDBException {
655 
656     try (final Options options = new Options().setCreateIfMissing(true);
657          final RocksDB db = RocksDB.open(options,
658              dbFolder.getRoot().getAbsolutePath())
659     ) {
660       final byte[] b0 = new byte[]{(byte) 0x00};
661       final byte[] b1 = new byte[]{(byte) 0x01};
662       final byte[] b2 = new byte[]{(byte) 0x02};
663       ColumnFamilyHandle cf1 = null, cf2 = null, cf3 = null;
664       try {
665         cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
666         cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
667         final List<byte[]> families = RocksDB.listColumnFamilies(options,
668             dbFolder.getRoot().getAbsolutePath());
669         assertThat(families).contains("default".getBytes(), b0, b1);
670         cf3 = db.createColumnFamily(new ColumnFamilyDescriptor(b2));
671       } finally {
672         if (cf1 != null) {
673           cf1.close();
674         }
675         if (cf2 != null) {
676           cf2.close();
677         }
678         if (cf3 != null) {
679           cf3.close();
680         }
681       }
682     }
683   }
684 
685   @Test
686   public void testCFNamesWithZeroBytes() throws RocksDBException {
687     ColumnFamilyHandle cf1 = null, cf2 = null;
688     try (final Options options = new Options().setCreateIfMissing(true);
689          final RocksDB db = RocksDB.open(options,
690              dbFolder.getRoot().getAbsolutePath());
691     ) {
692       try {
693         final byte[] b0 = new byte[]{0, 0};
694         final byte[] b1 = new byte[]{0, 1};
695         cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
696         cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
697         final List<byte[]> families = RocksDB.listColumnFamilies(options,
698             dbFolder.getRoot().getAbsolutePath());
699         assertThat(families).contains("default".getBytes(), b0, b1);
700       } finally {
701         if (cf1 != null) {
702           cf1.close();
703         }
704         if (cf2 != null) {
705           cf2.close();
706         }
707       }
708     }
709   }
710 
711   @Test
712   public void testCFNameSimplifiedChinese() throws RocksDBException {
713     ColumnFamilyHandle columnFamilyHandle = null;
714     try (final Options options = new Options().setCreateIfMissing(true);
715          final RocksDB db = RocksDB.open(options,
716              dbFolder.getRoot().getAbsolutePath());
717     ) {
718       try {
719         final String simplifiedChinese = "\u7b80\u4f53\u5b57";
720         columnFamilyHandle = db.createColumnFamily(
721             new ColumnFamilyDescriptor(simplifiedChinese.getBytes()));
722 
723         final List<byte[]> families = RocksDB.listColumnFamilies(options,
724             dbFolder.getRoot().getAbsolutePath());
725         assertThat(families).contains("default".getBytes(),
726             simplifiedChinese.getBytes());
727       } finally {
728         if (columnFamilyHandle != null) {
729           columnFamilyHandle.close();
730         }
731       }
732     }
733   }
734 }
735