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;
  
  /**
   * Base class implementation for Rocks Iterators
   * in the Java API
   *
   * <p>Multiple threads can invoke const methods on an RocksIterator without
   * external synchronization, but if any of the threads may call a
   * non-const method, all threads accessing the same RocksIterator must use
   * external synchronization.</p>
   *
   * @param <P> The type of the Parent Object from which the Rocks Iterator was
   *          created. This is used by disposeInternal to avoid double-free
   *          issues with the underlying C++ object.
   * @see org.rocksdb.RocksObject
   */
  public abstract class AbstractRocksIterator<P extends RocksObject>
      extends RocksObject implements RocksIteratorInterface {
    final P parent_;
  
    protected AbstractRocksIterator(final P parent,
        final long nativeHandle) {
      super(nativeHandle);
      // parent must point to a valid RocksDB instance.
      assert (parent != null);
      // RocksIterator must hold a reference to the related parent instance
      // to guarantee that while a GC cycle starts RocksIterator instances
      // are freed prior to parent instances.
      parent_ = parent;
    }
  
    @Override
    public boolean isValid() {
      assert (isOwningHandle());
      return isValid0(nativeHandle_);
    }
  
    @Override
    public void seekToFirst() {
      assert (isOwningHandle());
      seekToFirst0(nativeHandle_);
    }
  
    @Override
    public void seekToLast() {
      assert (isOwningHandle());
      seekToLast0(nativeHandle_);
    }
  
    @Override
    public void seek(byte[] target) {
      assert (isOwningHandle());
      seek0(nativeHandle_, target, target.length);
    }
  
    @Override
    public void next() {
      assert (isOwningHandle());
      next0(nativeHandle_);
    }
  
    @Override
    public void prev() {
      assert (isOwningHandle());
      prev0(nativeHandle_);
    }
  
    @Override
    public void status() throws RocksDBException {
      assert (isOwningHandle());
      status0(nativeHandle_);
    }
  
    /**
     * <p>Deletes underlying C++ iterator pointer.</p>
     *
     * <p>Note: the underlying handle can only be safely deleted if the parent
     * instance related to a certain RocksIterator is still valid and initialized.
     * Therefore {@code disposeInternal()} checks if the parent is initialized
     * before freeing the native handle.</p>
     */
    @Override
    protected void disposeInternal() {
        if (parent_.isOwningHandle()) {
          disposeInternal(nativeHandle_);
        }
    }
  
    abstract boolean isValid0(long handle);
    abstract void seekToFirst0(long handle);
    abstract void seekToLast0(long handle);
    abstract void next0(long handle);
    abstract void prev0(long handle);
    abstract void seek0(long handle, byte[] target, int targetLen);
    abstract void status0(long handle) throws RocksDBException;
  }
  