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