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.Arrays;
9 import java.util.Objects;
10 
11 /**
12  * ColumnFamilyHandle class to hold handles to underlying rocksdb
13  * ColumnFamily Pointers.
14  */
15 public class ColumnFamilyHandle extends RocksObject {
ColumnFamilyHandle(final RocksDB rocksDB, final long nativeHandle)16   ColumnFamilyHandle(final RocksDB rocksDB,
17       final long nativeHandle) {
18     super(nativeHandle);
19     // rocksDB must point to a valid RocksDB instance;
20     assert(rocksDB != null);
21     // ColumnFamilyHandle must hold a reference to the related RocksDB instance
22     // to guarantee that while a GC cycle starts ColumnFamilyHandle instances
23     // are freed prior to RocksDB instances.
24     this.rocksDB_ = rocksDB;
25   }
26 
27   /**
28    * Gets the name of the Column Family.
29    *
30    * @return The name of the Column Family.
31    *
32    * @throws RocksDBException if an error occurs whilst retrieving the name.
33    */
getName()34   public byte[] getName() throws RocksDBException {
35     assert(isOwningHandle() || isDefaultColumnFamily());
36     return getName(nativeHandle_);
37   }
38 
39   /**
40    * Gets the ID of the Column Family.
41    *
42    * @return the ID of the Column Family.
43    */
getID()44   public int getID() {
45     assert(isOwningHandle() || isDefaultColumnFamily());
46     return getID(nativeHandle_);
47   }
48 
49   /**
50    * Gets the up-to-date descriptor of the column family
51    * associated with this handle. Since it fills "*desc" with the up-to-date
52    * information, this call might internally lock and release DB mutex to
53    * access the up-to-date CF options. In addition, all the pointer-typed
54    * options cannot be referenced any longer than the original options exist.
55    *
56    * Note that this function is not supported in RocksDBLite.
57    *
58    * @return the up-to-date descriptor.
59    *
60    * @throws RocksDBException if an error occurs whilst retrieving the
61    *     descriptor.
62    */
getDescriptor()63   public ColumnFamilyDescriptor getDescriptor() throws RocksDBException {
64     assert(isOwningHandle() || isDefaultColumnFamily());
65     return getDescriptor(nativeHandle_);
66   }
67 
68   @Override
equals(final Object o)69   public boolean equals(final Object o) {
70     if (this == o) {
71       return true;
72     }
73     if (o == null || getClass() != o.getClass()) {
74       return false;
75     }
76 
77     final ColumnFamilyHandle that = (ColumnFamilyHandle) o;
78     try {
79       return rocksDB_.nativeHandle_ == that.rocksDB_.nativeHandle_ &&
80           getID() == that.getID() &&
81           Arrays.equals(getName(), that.getName());
82     } catch (RocksDBException e) {
83       throw new RuntimeException("Cannot compare column family handles", e);
84     }
85   }
86 
87   @Override
hashCode()88   public int hashCode() {
89     try {
90       return Objects.hash(getName(), getID(), rocksDB_.nativeHandle_);
91     } catch (RocksDBException e) {
92       throw new RuntimeException("Cannot calculate hash code of column family handle", e);
93     }
94   }
95 
isDefaultColumnFamily()96   protected boolean isDefaultColumnFamily() {
97     return nativeHandle_ == rocksDB_.getDefaultColumnFamily().nativeHandle_;
98   }
99 
100   /**
101    * <p>Deletes underlying C++ iterator pointer.</p>
102    *
103    * <p>Note: the underlying handle can only be safely deleted if the RocksDB
104    * instance related to a certain ColumnFamilyHandle is still valid and
105    * initialized. Therefore {@code disposeInternal()} checks if the RocksDB is
106    * initialized before freeing the native handle.</p>
107    */
108   @Override
disposeInternal()109   protected void disposeInternal() {
110     if(rocksDB_.isOwningHandle()) {
111       disposeInternal(nativeHandle_);
112     }
113   }
114 
getName(final long handle)115   private native byte[] getName(final long handle) throws RocksDBException;
getID(final long handle)116   private native int getID(final long handle);
getDescriptor(final long handle)117   private native ColumnFamilyDescriptor getDescriptor(final long handle) throws RocksDBException;
disposeInternal(final long handle)118   @Override protected final native void disposeInternal(final long handle);
119 
120   private final RocksDB rocksDB_;
121 }
122