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 /**
9  * <p>Base class for slices which will receive
10  * byte[] based access to the underlying data.</p>
11  *
12  * <p>byte[] backed slices typically perform better with
13  * small keys and values. When using larger keys and
14  * values consider using {@link org.rocksdb.DirectSlice}</p>
15  */
16 public class Slice extends AbstractSlice<byte[]> {
17 
18   /**
19    * Indicates whether we have to free the memory pointed to by the Slice
20    */
21   private volatile boolean cleared;
22   private volatile long internalBufferOffset = 0;
23 
24   /**
25    * <p>Called from JNI to construct a new Java Slice
26    * without an underlying C++ object set
27    * at creation time.</p>
28    *
29    * <p>Note: You should be aware that
30    * {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally
31    * called from the default Slice constructor, and that it is marked as
32    * private. This is so that developers cannot construct their own default
33    * Slice objects (at present). As developers cannot construct their own
34    * Slice objects through this, they are not creating underlying C++ Slice
35    * objects, and so there is nothing to free (dispose) from Java.</p>
36    */
37   @SuppressWarnings("unused")
Slice()38   private Slice() {
39     super();
40   }
41 
42   /**
43    * <p>Package-private Slice constructor which is used to construct
44    * Slice instances from C++ side. As the reference to this
45    * object is also managed from C++ side the handle will be disowned.</p>
46    *
47    * @param nativeHandle address of native instance.
48    */
Slice(final long nativeHandle)49   Slice(final long nativeHandle) {
50     this(nativeHandle, false);
51   }
52 
53   /**
54    * <p>Package-private Slice constructor which is used to construct
55    * Slice instances using a handle. </p>
56    *
57    * @param nativeHandle address of native instance.
58    * @param owningNativeHandle true if the Java side owns the memory pointed to
59    *     by this reference, false if ownership belongs to the C++ side
60    */
Slice(final long nativeHandle, final boolean owningNativeHandle)61   Slice(final long nativeHandle, final boolean owningNativeHandle) {
62     super();
63     setNativeHandle(nativeHandle, owningNativeHandle);
64   }
65 
66   /**
67    * <p>Constructs a slice where the data is taken from
68    * a String.</p>
69    *
70    * @param str String value.
71    */
Slice(final String str)72   public Slice(final String str) {
73     super(createNewSliceFromString(str));
74   }
75 
76   /**
77    * <p>Constructs a slice where the data is a copy of
78    * the byte array from a specific offset.</p>
79    *
80    * @param data byte array.
81    * @param offset offset within the byte array.
82    */
Slice(final byte[] data, final int offset)83   public Slice(final byte[] data, final int offset) {
84     super(createNewSlice0(data, offset));
85   }
86 
87   /**
88    * <p>Constructs a slice where the data is a copy of
89    * the byte array.</p>
90    *
91    * @param data byte array.
92    */
Slice(final byte[] data)93   public Slice(final byte[] data) {
94     super(createNewSlice1(data));
95   }
96 
97   @Override
clear()98   public void clear() {
99     clear0(getNativeHandle(), !cleared, internalBufferOffset);
100     cleared = true;
101   }
102 
103   @Override
removePrefix(final int n)104   public void removePrefix(final int n) {
105     removePrefix0(getNativeHandle(), n);
106     this.internalBufferOffset += n;
107   }
108 
109   /**
110    * <p>Deletes underlying C++ slice pointer
111    * and any buffered data.</p>
112    *
113    * <p>
114    * Note that this function should be called only after all
115    * RocksDB instances referencing the slice are closed.
116    * Otherwise an undefined behavior will occur.</p>
117    */
118   @Override
disposeInternal()119   protected void disposeInternal() {
120     final long nativeHandle = getNativeHandle();
121     if(!cleared) {
122       disposeInternalBuf(nativeHandle, internalBufferOffset);
123     }
124     super.disposeInternal(nativeHandle);
125   }
126 
data0(long handle)127   @Override protected final native byte[] data0(long handle);
createNewSlice0(final byte[] data, final int length)128   private native static long createNewSlice0(final byte[] data,
129       final int length);
createNewSlice1(final byte[] data)130   private native static long createNewSlice1(final byte[] data);
clear0(long handle, boolean internalBuffer, long internalBufferOffset)131   private native void clear0(long handle, boolean internalBuffer,
132       long internalBufferOffset);
removePrefix0(long handle, int length)133   private native void removePrefix0(long handle, int length);
disposeInternalBuf(final long handle, long internalBufferOffset)134   private native void disposeInternalBuf(final long handle,
135       long internalBufferOffset);
136 }
137