| // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
| // This source code is licensed under both the GPLv2 (found in the |
| // COPYING file in the root directory) and Apache 2.0 License |
| // (found in the LICENSE.Apache file in the root directory). |
| |
| package org.rocksdb; |
| |
| /** |
| * <p>Base class for slices which will receive |
| * byte[] based access to the underlying data.</p> |
| * |
| * <p>byte[] backed slices typically perform better with |
| * small keys and values. When using larger keys and |
| * values consider using {@link org.rocksdb.DirectSlice}</p> |
| */ |
| public class Slice extends AbstractSlice<byte[]> { |
| |
| /** |
| * Indicates whether we have to free the memory pointed to by the Slice |
| */ |
| private volatile boolean cleared; |
| private volatile long internalBufferOffset = 0; |
| |
| /** |
| * <p>Called from JNI to construct a new Java Slice |
| * without an underlying C++ object set |
| * at creation time.</p> |
| * |
| * <p>Note: You should be aware that |
| * {@see org.rocksdb.RocksObject#disOwnNativeHandle()} is intentionally |
| * called from the default Slice constructor, and that it is marked as |
| * private. This is so that developers cannot construct their own default |
| * Slice objects (at present). As developers cannot construct their own |
| * Slice objects through this, they are not creating underlying C++ Slice |
| * objects, and so there is nothing to free (dispose) from Java.</p> |
| */ |
| @SuppressWarnings("unused") |
| private Slice() { |
| super(); |
| } |
| |
| /** |
| * <p>Constructs a slice where the data is taken from |
| * a String.</p> |
| * |
| * @param str String value. |
| */ |
| public Slice(final String str) { |
| super(createNewSliceFromString(str)); |
| } |
| |
| /** |
| * <p>Constructs a slice where the data is a copy of |
| * the byte array from a specific offset.</p> |
| * |
| * @param data byte array. |
| * @param offset offset within the byte array. |
| */ |
| public Slice(final byte[] data, final int offset) { |
| super(createNewSlice0(data, offset)); |
| } |
| |
| /** |
| * <p>Constructs a slice where the data is a copy of |
| * the byte array.</p> |
| * |
| * @param data byte array. |
| */ |
| public Slice(final byte[] data) { |
| super(createNewSlice1(data)); |
| } |
| |
| @Override |
| public void clear() { |
| clear0(getNativeHandle(), !cleared, internalBufferOffset); |
| cleared = true; |
| } |
| |
| @Override |
| public void removePrefix(final int n) { |
| removePrefix0(getNativeHandle(), n); |
| this.internalBufferOffset += n; |
| } |
| |
| /** |
| * <p>Deletes underlying C++ slice pointer |
| * and any buffered data.</p> |
| * |
| * <p> |
| * Note that this function should be called only after all |
| * RocksDB instances referencing the slice are closed. |
| * Otherwise an undefined behavior will occur.</p> |
| */ |
| @Override |
| protected void disposeInternal() { |
| final long nativeHandle = getNativeHandle(); |
| if(!cleared) { |
| disposeInternalBuf(nativeHandle, internalBufferOffset); |
| } |
| super.disposeInternal(nativeHandle); |
| } |
| |
| @Override protected final native byte[] data0(long handle); |
| private native static long createNewSlice0(final byte[] data, |
| final int length); |
| private native static long createNewSlice1(final byte[] data); |
| private native void clear0(long handle, boolean internalBuffer, |
| long internalBufferOffset); |
| private native void removePrefix0(long handle, int length); |
| private native void disposeInternalBuf(final long handle, |
| long internalBufferOffset); |
| } |