content: // 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);
  }
  