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 import java.nio.ByteBuffer;
9 
10 /**
11  * Base class implementation for Rocks Iterators
12  * in the Java API
13  *
14  * <p>Multiple threads can invoke const methods on an RocksIterator without
15  * external synchronization, but if any of the threads may call a
16  * non-const method, all threads accessing the same RocksIterator must use
17  * external synchronization.</p>
18  *
19  * @param <P> The type of the Parent Object from which the Rocks Iterator was
20  *          created. This is used by disposeInternal to avoid double-free
21  *          issues with the underlying C++ object.
22  * @see org.rocksdb.RocksObject
23  */
24 public abstract class AbstractRocksIterator<P extends RocksObject>
25     extends RocksObject implements RocksIteratorInterface {
26   final P parent_;
27 
AbstractRocksIterator(final P parent, final long nativeHandle)28   protected AbstractRocksIterator(final P parent,
29       final long nativeHandle) {
30     super(nativeHandle);
31     // parent must point to a valid RocksDB instance.
32     assert (parent != null);
33     // RocksIterator must hold a reference to the related parent instance
34     // to guarantee that while a GC cycle starts RocksIterator instances
35     // are freed prior to parent instances.
36     parent_ = parent;
37   }
38 
39   @Override
isValid()40   public boolean isValid() {
41     assert (isOwningHandle());
42     return isValid0(nativeHandle_);
43   }
44 
45   @Override
seekToFirst()46   public void seekToFirst() {
47     assert (isOwningHandle());
48     seekToFirst0(nativeHandle_);
49   }
50 
51   @Override
seekToLast()52   public void seekToLast() {
53     assert (isOwningHandle());
54     seekToLast0(nativeHandle_);
55   }
56 
57   @Override
seek(byte[] target)58   public void seek(byte[] target) {
59     assert (isOwningHandle());
60     seek0(nativeHandle_, target, target.length);
61   }
62 
63  @Override
seekForPrev(byte[] target)64  public void seekForPrev(byte[] target) {
65    assert (isOwningHandle());
66    seekForPrev0(nativeHandle_, target, target.length);
67  }
68 
69  @Override
seek(ByteBuffer target)70  public void seek(ByteBuffer target) {
71    assert (isOwningHandle() && target.isDirect());
72    seekDirect0(nativeHandle_, target, target.position(), target.remaining());
73    target.position(target.limit());
74  }
75 
76  @Override
seekForPrev(ByteBuffer target)77  public void seekForPrev(ByteBuffer target) {
78    assert (isOwningHandle() && target.isDirect());
79    seekForPrevDirect0(nativeHandle_, target, target.position(), target.remaining());
80    target.position(target.limit());
81  }
82 
83   @Override
next()84   public void next() {
85     assert (isOwningHandle());
86     next0(nativeHandle_);
87   }
88 
89   @Override
prev()90   public void prev() {
91     assert (isOwningHandle());
92     prev0(nativeHandle_);
93   }
94 
95   @Override
status()96   public void status() throws RocksDBException {
97     assert (isOwningHandle());
98     status0(nativeHandle_);
99   }
100 
101   /**
102    * <p>Deletes underlying C++ iterator pointer.</p>
103    *
104    * <p>Note: the underlying handle can only be safely deleted if the parent
105    * instance related to a certain RocksIterator is still valid and initialized.
106    * Therefore {@code disposeInternal()} checks if the parent is initialized
107    * before freeing the native handle.</p>
108    */
109   @Override
disposeInternal()110   protected void disposeInternal() {
111       if (parent_.isOwningHandle()) {
112         disposeInternal(nativeHandle_);
113       }
114   }
115 
isValid0(long handle)116   abstract boolean isValid0(long handle);
seekToFirst0(long handle)117   abstract void seekToFirst0(long handle);
seekToLast0(long handle)118   abstract void seekToLast0(long handle);
next0(long handle)119   abstract void next0(long handle);
prev0(long handle)120   abstract void prev0(long handle);
seek0(long handle, byte[] target, int targetLen)121   abstract void seek0(long handle, byte[] target, int targetLen);
seekForPrev0(long handle, byte[] target, int targetLen)122   abstract void seekForPrev0(long handle, byte[] target, int targetLen);
seekDirect0(long handle, ByteBuffer target, int targetOffset, int targetLen)123   abstract void seekDirect0(long handle, ByteBuffer target, int targetOffset, int targetLen);
seekForPrevDirect0(long handle, ByteBuffer target, int targetOffset, int targetLen)124   abstract void seekForPrevDirect0(long handle, ByteBuffer target, int targetOffset, int targetLen);
status0(long handle)125   abstract void status0(long handle) throws RocksDBException;
126 }
127