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