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