+ * This option is applied only to {@link java.nio.ByteBuffer}, {@link org.agrona.DirectBuffer} and byte array keys. + * {@link io.netty.buffer.ByteBuf} keys are always compared in native byte order and as unsigned. + *
+ */ + MDB_UNSIGNEDKEY(0x30, false), /** * With {@link #MDB_DUPSORT}, use reverse string dups. * @@ -86,9 +95,15 @@ public enum DbiFlags implements MaskedFlag { MDB_CREATE(0x4_0000); private final int mask; + private final boolean propagatedToLmdb; - DbiFlags(final int mask) { + DbiFlags(final int mask, final boolean propagatedToLmdb) { this.mask = mask; + this.propagatedToLmdb = propagatedToLmdb; + } + + DbiFlags(final int mask) { + this(mask, true); } @Override @@ -96,4 +111,8 @@ public int getMask() { return mask; } + @Override + public boolean isPropagatedToLmdb() { + return propagatedToLmdb; + } } diff --git a/src/main/java/org/lmdbjava/DirectBufferProxy.java b/src/main/java/org/lmdbjava/DirectBufferProxy.java index 62b49095..3bde81ec 100644 --- a/src/main/java/org/lmdbjava/DirectBufferProxy.java +++ b/src/main/java/org/lmdbjava/DirectBufferProxy.java @@ -20,20 +20,20 @@ package org.lmdbjava; -import static java.lang.ThreadLocal.withInitial; -import static java.nio.ByteBuffer.allocateDirect; -import static java.nio.ByteOrder.BIG_ENDIAN; -import static java.util.Objects.requireNonNull; -import static org.lmdbjava.UnsafeAccess.UNSAFE; +import jnr.ffi.Pointer; +import org.agrona.DirectBuffer; +import org.agrona.MutableDirectBuffer; +import org.agrona.concurrent.UnsafeBuffer; import java.nio.ByteBuffer; import java.util.ArrayDeque; import java.util.Comparator; -import jnr.ffi.Pointer; -import org.agrona.DirectBuffer; -import org.agrona.MutableDirectBuffer; -import org.agrona.concurrent.UnsafeBuffer; +import static java.lang.ThreadLocal.withInitial; +import static java.nio.ByteBuffer.allocateDirect; +import static java.nio.ByteOrder.BIG_ENDIAN; +import static java.util.Objects.requireNonNull; +import static org.lmdbjava.UnsafeAccess.UNSAFE; /** * A buffer proxy backed by Agrona's {@link DirectBuffer}. @@ -42,6 +42,13 @@ * This class requires {@link UnsafeAccess} and Agrona must be in the classpath. */ public final class DirectBufferProxy extends BufferProxy- * The proxy is passed to the {@link Env#create(org.lmdbjava.BufferProxy)} - * method and is subsequently used by every {@link Txn}, {@link Dbi} and - * {@link Cursor} associated with the {@link Env}. + *
The proxy is passed to the {@link Env#create(org.lmdbjava.BufferProxy)} method and is
+ * subsequently used by every {@link Txn}, {@link Dbi} and {@link Cursor} associated with the {@link
+ * Env}.
*
* @param
- * The provided comparator must strictly match the lexicographical order of
- * keys in the native LMDB database.
+ * The provided comparator must strictly match the lexicographical order of keys in the native
+ * LMDB database.
*
* @param flags for the database
* @return a comparator that can be used (never null)
@@ -79,64 +82,51 @@ public abstract class BufferProxy {@link Env#create(org.lmdbjava.BufferProxy)}.
*/
public final class ByteArrayProxy extends BufferProxy
- * This class requires {@link UnsafeAccess} and netty-buffer must be in the
- * classpath.
+ * This class requires {@link UnsafeAccess} and netty-buffer must be in the classpath.
*/
public final class ByteBufProxy extends BufferProxy
- * There are two concrete {@link ByteBuffer} proxy implementations available:
+ * There are two concrete {@link ByteBuffer} proxy implementations available:
+ *
*
- * Users nominate which implementation they prefer by referencing the
- * {@link #PROXY_OPTIMAL} or {@link #PROXY_SAFE} field when invoking
- * {@link Env#create(org.lmdbjava.BufferProxy)}.
+ * Users nominate which implementation they prefer by referencing the {@link #PROXY_OPTIMAL} or
+ * {@link #PROXY_SAFE} field when invoking {@link Env#create(org.lmdbjava.BufferProxy)}.
*/
public final class ByteBufferProxy {
/**
- * The fastest {@link ByteBuffer} proxy that is available on this platform.
- * This will always be the same instance as {@link #PROXY_SAFE} if the
- * {@link UnsafeAccess#DISABLE_UNSAFE_PROP} has been set to
- * The cursor handle will be freed and must not be used again after this call.
- * Its transaction must still be live if it is a write-transaction.
+ * The cursor handle will be freed and must not be used again after this call. Its transaction
+ * must still be live if it is a write-transaction.
*/
@Override
public void close() {
@@ -90,9 +82,8 @@ public void close() {
/**
* Return count of duplicates for current key.
*
- *
- * This call is only valid on databases that support sorted duplicate data
- * items {@link DbiFlags#MDB_DUPSORT}.
+ * This call is only valid on databases that support sorted duplicate data items {@link
+ * DbiFlags#MDB_DUPSORT}.
*
* @return count of duplicates for current key
*/
@@ -110,8 +101,7 @@ public long count() {
/**
* Delete current key/data pair.
*
- *
- * This function deletes the key/data pair to which the cursor refers.
+ * This function deletes the key/data pair to which the cursor refers.
*
* @param f flags (either null or {@link PutFlags#MDB_NODUPDATA}
*/
@@ -138,9 +128,9 @@ public boolean first() {
/**
* Reposition the key/value buffers based on the passed key and operation.
*
- * @param key to search for
+ * @param key to search for
* @param data to search for
- * @param op options for this operation
+ * @param op options for this operation
* @return false if key not found
*/
public boolean get(final T key, final T data, final SeekOp op) {
@@ -154,8 +144,7 @@ public boolean get(final T key, final T data, final SeekOp op) {
kv.keyIn(key);
kv.valIn(data);
- final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv
- .pointerVal(), op.getCode());
+ final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv.pointerVal(), op.getCode());
if (rc == MDB_NOTFOUND) {
return false;
@@ -172,7 +161,7 @@ public boolean get(final T key, final T data, final SeekOp op) {
* Reposition the key/value buffers based on the passed key and operation.
*
* @param key to search for
- * @param op options for this operation
+ * @param op options for this operation
* @return false if key not found
*/
public boolean get(final T key, final GetOp op) {
@@ -185,8 +174,7 @@ public boolean get(final T key, final GetOp op) {
}
kv.keyIn(key);
- final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv
- .pointerVal(), op.getCode());
+ final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv.pointerVal(), op.getCode());
if (rc == MDB_NOTFOUND) {
return false;
@@ -238,14 +226,13 @@ public boolean prev() {
/**
* Store by cursor.
*
- *
- * This function stores key/data pairs into the database.
+ * This function stores key/data pairs into the database.
*
* @param key key to store
* @param val data to store
- * @param op options for this operation
- * @return true if the value was put, false if MDB_NOOVERWRITE or
- * MDB_NODUPDATA were set and the key/value existed already.
+ * @param op options for this operation
+ * @return true if the value was put, false if MDB_NOOVERWRITE or MDB_NODUPDATA were set and the
+ * key/value existed already.
*/
public boolean put(final T key, final T val, final PutFlags... op) {
if (SHOULD_CHECK) {
@@ -259,8 +246,7 @@ public boolean put(final T key, final T val, final PutFlags... op) {
kv.keyIn(key);
kv.valIn(val);
final int mask = mask(true, op);
- final int rc = LIB.mdb_cursor_put(ptrCursor, kv.pointerKey(),
- kv.pointerVal(), mask);
+ final int rc = LIB.mdb_cursor_put(ptrCursor, kv.pointerKey(), kv.pointerVal(), mask);
if (rc == MDB_KEYEXIST) {
if (isSet(mask, MDB_NOOVERWRITE)) {
kv.valOut(); // marked as in,out in LMDB C docs
@@ -276,23 +262,19 @@ public boolean put(final T key, final T val, final PutFlags... op) {
}
/**
- * Put multiple values into the database in one
- * The database must have been opened with {@link DbiFlags#MDB_DUPFIXED}. The
- * buffer must contain fixed-sized values to be inserted. The size of each
- * element is calculated from the buffer's size divided by the given element
- * count. For example, to populate 10 X 4 byte integers at once, present a
- * buffer of 40 bytes and specify the element as 10.
+ * The database must have been opened with {@link DbiFlags#MDB_DUPFIXED}. The buffer must
+ * contain fixed-sized values to be inserted. The size of each element is calculated from the
+ * buffer's size divided by the given element count. For example, to populate 10 X 4 byte integers
+ * at once, present a buffer of 40 bytes and specify the element as 10.
*
- * @param key key to store in the database (not null)
- * @param val value to store in the database (not null)
+ * @param key key to store in the database (not null)
+ * @param val value to store in the database (not null)
* @param elements number of elements contained in the passed value buffer
- * @param op options for operation (must set
- * A cursor is associated with a specific transaction and database. Cursors
- * that are only used in read-only transactions may be re-used, to avoid
- * unnecessary malloc/free overhead. The cursor may be associated with a new
- * read-only transaction, and referencing the same database handle as it was
- * created with. This may be done whether the previous transaction is live or
- * dead.
+ * A cursor is associated with a specific transaction and database. Cursors that are only used
+ * in read-only transactions may be re-used, to avoid unnecessary malloc/free overhead. The cursor
+ * may be associated with a new read-only transaction, and referencing the same database handle as
+ * it was created with. This may be done whether the previous transaction is live or dead.
*
* @param newTxn transaction handle
*/
@@ -341,19 +319,17 @@ public void renew(final Txn
- * This flag must not be specified if the database was opened with MDB_DUPSORT
+ * This flag must not be specified if the database was opened with MDB_DUPSORT
*
- * @param key key to store in the database (not null)
+ * @param key key to store in the database (not null)
* @param size size of the value to be stored in the database (not null)
- * @param op options for this operation
+ * @param op options for this operation
* @return a buffer that can be used to modify the value
*/
public T reserve(final T key, final int size, final PutFlags... op) {
@@ -367,8 +343,7 @@ public T reserve(final T key, final int size, final PutFlags... op) {
kv.keyIn(key);
kv.valIn(size);
final int flags = mask(true, op) | MDB_RESERVE.getMask();
- checkRc(LIB.mdb_cursor_put(ptrCursor, kv.pointerKey(), kv.pointerVal(),
- flags));
+ checkRc(LIB.mdb_cursor_put(ptrCursor, kv.pointerKey(), kv.pointerVal(), flags));
kv.valOut();
ReferenceUtil.reachabilityFence0(key);
return val();
@@ -388,8 +363,7 @@ public boolean seek(final SeekOp op) {
txn.checkReady();
}
- final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv
- .pointerVal(), op.getCode());
+ final int rc = LIB.mdb_cursor_get(ptrCursor, kv.pointerKey(), kv.pointerVal(), op.getCode());
if (rc == MDB_NOTFOUND) {
return false;
@@ -416,24 +390,18 @@ private void checkNotClosed() {
}
}
- /**
- * Cursor has already been closed.
- */
+ /** Cursor has already been closed. */
public static final class ClosedException extends LmdbException {
private static final long serialVersionUID = 1L;
- /**
- * Creates a new instance.
- */
+ /** Creates a new instance. */
public ClosedException() {
super("Cursor has already been closed");
}
}
- /**
- * Cursor stack too deep - internal error.
- */
+ /** Cursor stack too deep - internal error. */
public static final class FullException extends LmdbNativeException {
static final int MDB_CURSOR_FULL = -30_787;
@@ -443,5 +411,4 @@ public static final class FullException extends LmdbNativeException {
super(MDB_CURSOR_FULL, "Cursor stack too deep - internal error");
}
}
-
}
diff --git a/src/main/java/org/lmdbjava/CursorIterable.java b/src/main/java/org/lmdbjava/CursorIterable.java
index 39a6d58c..6a03bd90 100644
--- a/src/main/java/org/lmdbjava/CursorIterable.java
+++ b/src/main/java/org/lmdbjava/CursorIterable.java
@@ -1,23 +1,18 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
import static org.lmdbjava.CursorIterable.State.RELEASED;
@@ -30,21 +25,18 @@
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
-
import org.lmdbjava.KeyRangeType.CursorOp;
import org.lmdbjava.KeyRangeType.IteratorOp;
/**
- * {@link Iterable} that creates a single {@link Iterator} that will iterate
- * over a {@link Cursor} as specified by a {@link KeyRange}.
+ * {@link Iterable} that creates a single {@link Iterator} that will iterate over a {@link Cursor}
+ * as specified by a {@link KeyRange}.
*
- *
- * An instance will create and close its own cursor.
+ * An instance will create and close its own cursor.
*
* @param
- * As iteration of the returned iterator will cause movement of the underlying
- * LMDB cursor, an {@link IllegalStateException} is thrown if an attempt is
- * made to obtain the iterator more than once. For advanced cursor control
- * (such as being able to iterate over the same data multiple times etc)
- * please instead refer to {@link Dbi#openCursor(org.lmdbjava.Txn)}.
+ * As iteration of the returned iterator will cause movement of the underlying LMDB cursor, an
+ * {@link IllegalStateException} is thrown if an attempt is made to obtain the iterator more than
+ * once. For advanced cursor control (such as being able to iterate over the same data multiple
+ * times etc) please instead refer to {@link Dbi#openCursor(org.lmdbjava.Txn)}.
*
* @return an iterator
*/
@Override
- @SuppressWarnings("checkstyle:AnonInnerLength")
public Iterator
- * The same holder instance will always be returned for a given iterator.
- * The returned keys and values may change or point to different memory
- * locations following changes in the iterator, cursor or transaction.
+ * The same holder instance will always be returned for a given iterator. The returned keys and
+ * values may change or point to different memory locations following changes in the iterator,
+ * cursor or transaction.
*
* @param
- * It is very rare that closing a database handle is useful. There are also
- * many warnings/restrictions if closing a database handle (refer to the LMDB
- * C documentation). As such this is non-routine usage and this class does not
- * track the open/closed state of the {@link Dbi}. Advanced users are expected
- * to have specific reasons for using this method and will manage their own
- * state accordingly.
+ * It is very rare that closing a database handle is useful. There are also many
+ * warnings/restrictions if closing a database handle (refer to the LMDB C documentation). As such
+ * this is non-routine usage and this class does not track the open/closed state of the {@link
+ * Dbi}. Advanced users are expected to have specific reasons for using this method and will
+ * manage their own state accordingly.
*/
public void close() {
clean();
@@ -120,7 +118,6 @@ public void close() {
*
* @param key key to delete from the database (not null)
* @return true if the key/data pair was found, false otherwise
- *
* @see #delete(org.lmdbjava.Txn, java.lang.Object, java.lang.Object)
*/
public boolean delete(final T key) {
@@ -137,7 +134,6 @@ public boolean delete(final T key) {
* @param txn transaction handle (not null; not committed; must be R-W)
* @param key key to delete from the database (not null)
* @return true if the key/data pair was found, false otherwise
- *
* @see #delete(org.lmdbjava.Txn, java.lang.Object, java.lang.Object)
*/
public boolean delete(final Txn
- * If the database does not support sorted duplicate data items
- * ({@link DbiFlags#MDB_DUPSORT}) the value parameter is ignored. If the
- * database supports sorted duplicates and the value parameter is null, all of
- * the duplicate data items for the key will be deleted. Otherwise, if the
- * data parameter is non-null only the matching data item will be deleted.
+ * If the database does not support sorted duplicate data items ({@link DbiFlags#MDB_DUPSORT})
+ * the value parameter is ignored. If the database supports sorted duplicates and the value
+ * parameter is null, all of the duplicate data items for the key will be deleted. Otherwise, if
+ * the data parameter is non-null only the matching data item will be deleted.
*
* @param txn transaction handle (not null; not committed; must be R-W)
* @param key key to delete from the database (not null)
@@ -187,10 +181,8 @@ public boolean delete(final Txn
- * This method slightly differs from the LMDB C API in that it does not
- * provide support for also closing the DB handle. If closing the DB handle is
- * required, please see {@link #close()}.
+ * This method slightly differs from the LMDB C API in that it does not provide support for
+ * also closing the DB handle. If closing the DB handle is required, please see {@link #close()}.
*
* @param txn transaction handle (not null; not committed; must be R-W)
*/
@@ -199,11 +191,11 @@ public void drop(final Txn
- * This function retrieves key/data pairs from the database. The address and
- * length of the data associated with the specified \b key are returned in the
- * structure to which \b data refers. If the database supports duplicate keys
- * ({@link org.lmdbjava.DbiFlags#MDB_DUPSORT}) then the first data item for
- * the key will be returned. Retrieval of other items requires the use of
+ * This function retrieves key/data pairs from the database. The address and length of the data
+ * associated with the specified \b key are returned in the structure to which \b data refers. If
+ * the database supports duplicate keys ({@link org.lmdbjava.DbiFlags#MDB_DUPSORT}) then the first
+ * data item for the key will be returned. Retrieval of other items requires the use of
* #mdb_cursor_get().
*
* @param txn transaction handle (not null; not committed)
@@ -243,8 +233,7 @@ public T get(final Txn
- * A cursor is associated with a specific transaction and database. A cursor
- * cannot be used when its database handle is closed. Nor when its transaction
- * has ended, except with {@link Cursor#renew(org.lmdbjava.Txn)}. It can be
- * discarded with {@link Cursor#close()}. A cursor in a write-transaction can
- * be closed before its transaction ends, and will otherwise be closed when
- * its transaction ends. A cursor in a read-only transaction must be closed
- * explicitly, before or after its transaction ends. It can be reused with
- * {@link Cursor#renew(org.lmdbjava.Txn)} before finally closing it.
+ * A cursor is associated with a specific transaction and database. A cursor cannot be used
+ * when its database handle is closed. Nor when its transaction has ended, except with {@link
+ * Cursor#renew(org.lmdbjava.Txn)}. It can be discarded with {@link Cursor#close()}. A cursor in a
+ * write-transaction can be closed before its transaction ends, and will otherwise be closed when
+ * its transaction ends. A cursor in a read-only transaction must be closed explicitly, before or
+ * after its transaction ends. It can be reused with {@link Cursor#renew(org.lmdbjava.Txn)} before
+ * finally closing it.
*
* @param txn transaction handle (not null; not committed)
* @return cursor handle
@@ -347,8 +334,7 @@ public Cursor
- * This function stores key/data pairs in the database. The default behavior
- * is to enter the new key/data pair, replacing any previously existing key if
- * duplicates are disallowed, or adding a duplicate data item if duplicates
- * are allowed ({@link DbiFlags#MDB_DUPSORT}).
+ * This function stores key/data pairs in the database. The default behavior is to enter the
+ * new key/data pair, replacing any previously existing key if duplicates are disallowed, or
+ * adding a duplicate data item if duplicates are allowed ({@link DbiFlags#MDB_DUPSORT}).
*
- * @param txn transaction handle (not null; not committed; must be R-W)
- * @param key key to store in the database (not null)
- * @param val value to store in the database (not null)
+ * @param txn transaction handle (not null; not committed; must be R-W)
+ * @param key key to store in the database (not null)
+ * @param val value to store in the database (not null)
* @param flags Special options for this operation
- * @return true if the value was put, false if MDB_NOOVERWRITE or
- * MDB_NODUPDATA were set and the key/value existed already.
+ * @return true if the value was put, false if MDB_NOOVERWRITE or MDB_NODUPDATA were set and the
+ * key/value existed already.
*/
- public boolean put(final Txn
- * This flag must not be specified if the database was opened with MDB_DUPSORT
+ * This flag must not be specified if the database was opened with MDB_DUPSORT
*
- * @param txn transaction handle (not null; not committed; must be R-W)
- * @param key key to store in the database (not null)
+ * @param txn transaction handle (not null; not committed; must be R-W)
+ * @param key key to store in the database (not null)
* @param size size of the value to be stored in the database
- * @param op options for this operation
+ * @param op options for this operation
* @return a buffer that can be used to modify the value
*/
- public T reserve(final Txn
- * This can mean:
+ * This can mean:
+ *
*
- * Keys are strings to be compared in reverse order, from the end of the
- * strings to the beginning. By default, keys are treated as strings and
- * compared from beginning to end.
+ * Keys are strings to be compared in reverse order, from the end of the strings to the
+ * beginning. By default, keys are treated as strings and compared from beginning to end.
*/
MDB_REVERSEKEY(0x02),
/**
* Use sorted duplicates.
*
- *
- * Duplicate keys may be used in the database. Or, from another perspective,
- * keys may have multiple data items, stored in sorted order. By default keys
- * must be unique and may have only a single data item.
+ * Duplicate keys may be used in the database. Or, from another perspective, keys may have
+ * multiple data items, stored in sorted order. By default keys must be unique and may have only a
+ * single data item.
*/
MDB_DUPSORT(0x04),
/**
- * Numeric keys in native byte order: either unsigned int or size_t. The keys
- * must all be of the same size.
+ * Numeric keys in native byte order: either unsigned int or size_t. The keys must all be of the
+ * same size.
*/
MDB_INTEGERKEY(0x08),
/**
* With {@link #MDB_DUPSORT}, sorted dup items have fixed size.
*
- *
- * This flag may only be used in combination with {@link #MDB_DUPSORT}. This
- * option tells the library that the data items for this database are all the
- * same size, which allows further optimizations in storage and retrieval.
- * When all data items are the same size, the {@link SeekOp#MDB_GET_MULTIPLE}
- * and {@link SeekOp#MDB_NEXT_MULTIPLE} cursor operations may be used to
+ * This flag may only be used in combination with {@link #MDB_DUPSORT}. This option tells the
+ * library that the data items for this database are all the same size, which allows further
+ * optimizations in storage and retrieval. When all data items are the same size, the {@link
+ * SeekOp#MDB_GET_MULTIPLE} and {@link SeekOp#MDB_NEXT_MULTIPLE} cursor operations may be used to
* retrieve multiple items at once.
*/
MDB_DUPFIXED(0x10),
/**
* With {@link #MDB_DUPSORT}, dups are {@link #MDB_INTEGERKEY}-style integers.
*
- *
- * This option specifies that duplicate data items are binary integers,
- * similar to {@link #MDB_INTEGERKEY} keys.
+ * This option specifies that duplicate data items are binary integers, similar to {@link
+ * #MDB_INTEGERKEY} keys.
*/
MDB_INTEGERDUP(0x20),
/**
* Compare the numeric keys in native byte order and as unsigned.
*
- *
- * This option is applied only to {@link java.nio.ByteBuffer}, {@link org.agrona.DirectBuffer} and byte array keys.
- * {@link io.netty.buffer.ByteBuf} keys are always compared in native byte order and as unsigned.
- * This option is applied only to {@link java.nio.ByteBuffer}, {@link org.agrona.DirectBuffer}
+ * and byte array keys. {@link io.netty.buffer.ByteBuf} keys are always compared in native byte
+ * order and as unsigned.
*/
MDB_UNSIGNEDKEY(0x30, false),
/**
* With {@link #MDB_DUPSORT}, use reverse string dups.
*
- *
- * This option specifies that duplicate data items should be compared as
- * strings in reverse order.
+ * This option specifies that duplicate data items should be compared as strings in reverse
+ * order.
*/
MDB_REVERSEDUP(0x40),
/**
* Create the named database if it doesn't exist.
*
- *
- * This option is not allowed in a read-only transaction or a read-only
- * environment.
+ * This option is not allowed in a read-only transaction or a read-only environment.
*/
MDB_CREATE(0x4_0000);
diff --git a/src/main/java/org/lmdbjava/DirectBufferProxy.java b/src/main/java/org/lmdbjava/DirectBufferProxy.java
index 3bde81ec..156e60e9 100644
--- a/src/main/java/org/lmdbjava/DirectBufferProxy.java
+++ b/src/main/java/org/lmdbjava/DirectBufferProxy.java
@@ -1,73 +1,64 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
-import jnr.ffi.Pointer;
-import org.agrona.DirectBuffer;
-import org.agrona.MutableDirectBuffer;
-import org.agrona.concurrent.UnsafeBuffer;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayDeque;
-import java.util.Comparator;
-
import static java.lang.ThreadLocal.withInitial;
import static java.nio.ByteBuffer.allocateDirect;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.util.Objects.requireNonNull;
import static org.lmdbjava.UnsafeAccess.UNSAFE;
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.Comparator;
+import jnr.ffi.Pointer;
+import org.agrona.DirectBuffer;
+import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.UnsafeBuffer;
+
/**
* A buffer proxy backed by Agrona's {@link DirectBuffer}.
*
- *
- * This class requires {@link UnsafeAccess} and Agrona must be in the classpath.
+ * This class requires {@link UnsafeAccess} and Agrona must be in the classpath.
*/
public final class DirectBufferProxy extends BufferProxy
- * Will silently return if already closed or never opened.
+ * Will silently return if already closed or never opened.
*/
@Override
public void close() {
@@ -138,22 +127,19 @@ public void close() {
/**
* Copies an LMDB environment to the specified destination path.
*
- *
- * This function may be used to make a backup of an existing environment. No
- * lockfile is created, since it gets recreated at need.
+ * This function may be used to make a backup of an existing environment. No lockfile is
+ * created, since it gets recreated at need.
*
- *
- * If this environment was created using {@link EnvFlags#MDB_NOSUBDIR}, the
- * destination path must be a directory that exists but contains no files. If
- * {@link EnvFlags#MDB_NOSUBDIR} was used, the destination path must not
- * exist, but it must be possible to create a file at the provided path.
+ * If this environment was created using {@link EnvFlags#MDB_NOSUBDIR}, the destination path
+ * must be a directory that exists but contains no files. If {@link EnvFlags#MDB_NOSUBDIR} was
+ * used, the destination path must not exist, but it must be possible to create a file at the
+ * provided path.
*
- *
- * Note: This call can trigger significant file size growth if run in parallel
- * with write transactions, because it employs a read-only transaction. See
- * long-lived transactions under "Caveats" in the LMDB native documentation.
+ * Note: This call can trigger significant file size growth if run in parallel with write
+ * transactions, because it employs a read-only transaction. See long-lived transactions under
+ * "Caveats" in the LMDB native documentation.
*
- * @param path writable destination path as described above
+ * @param path writable destination path as described above
* @param flags special options for this copy
*/
public void copy(final File path, final CopyFlags... flags) {
@@ -166,13 +152,11 @@ public void copy(final File path, final CopyFlags... flags) {
/**
* Obtain the DBI names.
*
- *
- * This method is only compatible with {@link Env}s that use named databases.
- * If an unnamed {@link Dbi} is being used to store data, this method will
- * attempt to return all such keys from the unnamed database.
+ * This method is only compatible with {@link Env}s that use named databases. If an unnamed
+ * {@link Dbi} is being used to store data, this method will attempt to return all such keys from
+ * the unnamed database.
*
- *
- * This method must not be called from concurrent threads.
+ * This method must not be called from concurrent threads.
*
* @return a list of DBI names (never null)
*/
@@ -180,7 +164,7 @@ public List
- * This method will automatically commit the private transaction before
- * returning. This ensures the This method will automatically commit the private transaction before returning. This ensures
+ * the
- * The caller must commit the transaction after this method returns in order
- * to retain the
- * A {@link Comparator} may be provided when calling this method. Such
- * comparator is primarily used by {@link CursorIterable} instances. A
- * secondary (but uncommon) use of the comparator is to act as a callback from
- * the native library if
- * A default comparator will be provided if
- * This method (and its overloaded convenience variants) must not be called
- * from concurrent threads.
- *
- * @param txn transaction to use (required; not closed)
- * @param name name of the database (or null if no name is required)
+ * The caller must commit the transaction after this method returns in order to retain the
+ * A {@link Comparator} may be provided when calling this method. Such comparator is primarily
+ * used by {@link CursorIterable} instances. A secondary (but uncommon) use of the comparator is
+ * to act as a callback from the native library if A default comparator will be provided if This method (and its overloaded convenience variants) must not be called from concurrent
+ * threads.
+ *
+ * @param txn transaction to use (required; not closed)
+ * @param name name of the database (or null if no name is required)
* @param comparator custom comparator callback (or null to use LMDB default)
- * @param nativeCb whether native code should call back to the comparator
- * @param flags to open the database with
+ * @param nativeCb whether native code should call back to the comparator
+ * @param flags to open the database with
* @return a database that is ready to use
*/
- public Dbi
- * Use a fixed address for the mmap region. This flag must be specified when
- * creating the environment, and is stored persistently in the environment. If
- * successful, the memory map will always reside at the same virtual address
- * and pointers used to reference data items in the database will be constant
- * across multiple invocations. This option may not always work, depending on
- * how the operating system has allocated memory to shared libraries and other
- * uses. The feature is highly experimental.
+ * Use a fixed address for the mmap region. This flag must be specified when creating the
+ * environment, and is stored persistently in the environment. If successful, the memory map will
+ * always reside at the same virtual address and pointers used to reference data items in the
+ * database will be constant across multiple invocations. This option may not always work,
+ * depending on how the operating system has allocated memory to shared libraries and other uses.
+ * The feature is highly experimental.
*/
MDB_FIXEDMAP(0x01),
/**
* No environment directory.
*
- *
- * By default, LMDB creates its environment in a directory whose pathname is
- * given in path, and creates its data and lock files under that directory.
- * With this option, path is used as-is for the database main data file. The
- * database lock file is the path with "-lock" appended.
+ * By default, LMDB creates its environment in a directory whose pathname is given in path, and
+ * creates its data and lock files under that directory. With this option, path is used as-is for
+ * the database main data file. The database lock file is the path with "-lock" appended.
*/
MDB_NOSUBDIR(0x4000),
/**
* Open the environment in read-only mode.
*
- *
- * No write operations will be allowed. LMDB will still modify the lock file -
- * except on read-only filesystems, where LMDB does not use locks.
+ * No write operations will be allowed. LMDB will still modify the lock file - except on
+ * read-only filesystems, where LMDB does not use locks.
*/
MDB_RDONLY_ENV(0x2_0000),
/**
* Use a writeable memory map unless {@link #MDB_RDONLY_ENV} is set.
*
- *
- * This is faster and uses fewer mallocs, but loses protection from
- * application bugs like wild pointer writes and other bad updates into the
- * database. Incompatible with nested transactions. Do not mix processes with
- * and without {@link #MDB_WRITEMAP} on the same environment. This can defeat
- * durability ({@link Env#sync(boolean)} etc).
+ * This is faster and uses fewer mallocs, but loses protection from application bugs like wild
+ * pointer writes and other bad updates into the database. Incompatible with nested transactions.
+ * Do not mix processes with and without {@link #MDB_WRITEMAP} on the same environment. This can
+ * defeat durability ({@link Env#sync(boolean)} etc).
*/
MDB_WRITEMAP(0x8_0000),
/**
* Don't fsync metapage after commit.
*
- *
- * Flush system buffers to disk only once per transaction, omit the metadata
- * flush. Defer that until the system flushes files to disk, or next
- * non-{@link #MDB_RDONLY_ENV} commit or {@link Env#sync(boolean)}. This
- * optimization* maintains database integrity, but a system crash may undo the
- * last* committed transaction. I.e. it preserves the ACI (atomicity,
- * consistency, isolation) but not D (durability) database property.
+ * Flush system buffers to disk only once per transaction, omit the metadata flush. Defer that
+ * until the system flushes files to disk, or next non-{@link #MDB_RDONLY_ENV} commit or {@link
+ * Env#sync(boolean)}. This optimization* maintains database integrity, but a system crash may
+ * undo the last* committed transaction. I.e. it preserves the ACI (atomicity, consistency,
+ * isolation) but not D (durability) database property.
*/
MDB_NOMETASYNC(0x4_0000),
/**
* Don't fsync after commit.
*
- *
- * Don't flush system buffers to disk when committing a transaction. This
- * optimization means a system crash can corrupt the database or lose the last
- * transactions if buffers are not yet flushed to disk. The risk is governed
- * by how often the system flushes dirty buffers to disk and how often
- * {@link Env#sync(boolean)} is called. However, if the filesystem preserves
- * write order and the {@link #MDB_WRITEMAP} flag is not used, transactions
- * exhibit ACI (atomicity, consistency, isolation) properties and only lose D
- * (durability). I.e. database integrity is maintained, but a system crash may
- * undo the final transactions. Note that
- * ({@link #MDB_NOSYNC} | {@link #MDB_WRITEMAP}) leaves the system with no
- * hint for when to write transactions to disk, unless
- * {@link Env#sync(boolean)} is called.
- * ({@link #MDB_MAPASYNC} | {@link #MDB_WRITEMAP}) may be preferable.
+ * Don't flush system buffers to disk when committing a transaction. This optimization means a
+ * system crash can corrupt the database or lose the last transactions if buffers are not yet
+ * flushed to disk. The risk is governed by how often the system flushes dirty buffers to disk and
+ * how often {@link Env#sync(boolean)} is called. However, if the filesystem preserves write order
+ * and the {@link #MDB_WRITEMAP} flag is not used, transactions exhibit ACI (atomicity,
+ * consistency, isolation) properties and only lose D (durability). I.e. database integrity is
+ * maintained, but a system crash may undo the final transactions. Note that ({@link #MDB_NOSYNC}
+ * | {@link #MDB_WRITEMAP}) leaves the system with no hint for when to write transactions to disk,
+ * unless {@link Env#sync(boolean)} is called. ({@link #MDB_MAPASYNC} | {@link #MDB_WRITEMAP}) may
+ * be preferable.
*/
MDB_NOSYNC(0x1_0000),
/**
* Use asynchronous msync when {@link #MDB_WRITEMAP} is used.
*
- *
- * When using {@link #MDB_WRITEMAP}, use asynchronous flushes to disk.
- * As with {@link #MDB_NOSYNC}, a system crash can then corrupt the database
- * or lose the last transactions. Calling {@link Env#sync(boolean)} ensures
- * on-disk database integrity until next commit.
+ * When using {@link #MDB_WRITEMAP}, use asynchronous flushes to disk. As with {@link
+ * #MDB_NOSYNC}, a system crash can then corrupt the database or lose the last transactions.
+ * Calling {@link Env#sync(boolean)} ensures on-disk database integrity until next commit.
*/
MDB_MAPASYNC(0x10_0000),
/**
* Tie reader locktable slots to {@link Txn} objects instead of to threads.
*
- *
- * Don't use Thread-Local Storage. Tie reader locktable slots to {@link Txn}
- * objects instead of to threads. I.e. {@link Txn#reset()} keeps the slot
- * reseved for the {@link Txn} object. A thread may use parallel read-only
- * transactions. A read-only transaction may span threads if the user
- * synchronizes its use. Applications that multiplex many user threads over
- * individual OS threads need this option. Such an application must also
- * serialize the write transactions in an OS thread, since LMDB's write
- * locking is unaware of the user threads.
+ * Don't use Thread-Local Storage. Tie reader locktable slots to {@link Txn} objects instead of
+ * to threads. I.e. {@link Txn#reset()} keeps the slot reseved for the {@link Txn} object. A
+ * thread may use parallel read-only transactions. A read-only transaction may span threads if the
+ * user synchronizes its use. Applications that multiplex many user threads over individual OS
+ * threads need this option. Such an application must also serialize the write transactions in an
+ * OS thread, since LMDB's write locking is unaware of the user threads.
*/
MDB_NOTLS(0x20_0000),
/**
* Don't do any locking, caller must manage their own locks.
*
- *
- * Don't do any locking. If concurrent access is anticipated, the caller must
- * manage all concurrency itself. For proper operation the caller must enforce
- * single-writer semantics, and must ensure that no readers are using old
- * transactions while a writer is active. The simplest approach is to use an
- * exclusive lock so that no readers may be active at all when a writer
+ * Don't do any locking. If concurrent access is anticipated, the caller must manage all
+ * concurrency itself. For proper operation the caller must enforce single-writer semantics, and
+ * must ensure that no readers are using old transactions while a writer is active. The simplest
+ * approach is to use an exclusive lock so that no readers may be active at all when a writer
* begins.
*/
MDB_NOLOCK(0x40_0000),
/**
* Don't do readahead (no effect on Windows).
*
- *
- * Turn off readahead. Most operating systems perform readahead on read
- * requests by default. This option turns it off if the OS supports it.
- * Turning it off may help random read performance when the DB is larger than
- * RAM and system RAM is full. The option is not implemented on Windows.
+ * Turn off readahead. Most operating systems perform readahead on read requests by default.
+ * This option turns it off if the OS supports it. Turning it off may help random read performance
+ * when the DB is larger than RAM and system RAM is full. The option is not implemented on
+ * Windows.
*/
MDB_NORDAHEAD(0x80_0000),
/**
* Don't initialize malloc'd memory before writing to datafile.
*
- *
- * Don't initialize malloc'd memory before writing to unused spaces in the
- * data file. By default, memory for pages written to the data file is
- * obtained using malloc. While these pages may be reused in subsequent
- * transactions, freshly malloc'd pages will be initialized to zeroes before
- * use. This avoids persisting leftover data from other code (that used the
- * heap and subsequently freed the memory) into the data file. Note that many
- * other system libraries may allocate and free memory from the heap for
- * arbitrary uses. E.g., stdio may use the heap for file I/O buffers. This
- * initialization step has a modest performance cost so some applications may
- * want to disable it using this flag. This option can be a problem for
- * applications which handle sensitive data like passwords, and it makes
- * memory checkers like Valgrind noisy. This flag is not needed with
- * {@link #MDB_WRITEMAP}, which writes directly to the mmap instead of using
- * malloc for pages. The initialization is also skipped if
- * {@link PutFlags#MDB_RESERVE} is used; the caller is expected to overwrite
- * all of the memory that was reserved in that case.
+ * Don't initialize malloc'd memory before writing to unused spaces in the data file. By
+ * default, memory for pages written to the data file is obtained using malloc. While these pages
+ * may be reused in subsequent transactions, freshly malloc'd pages will be initialized to zeroes
+ * before use. This avoids persisting leftover data from other code (that used the heap and
+ * subsequently freed the memory) into the data file. Note that many other system libraries may
+ * allocate and free memory from the heap for arbitrary uses. E.g., stdio may use the heap for
+ * file I/O buffers. This initialization step has a modest performance cost so some applications
+ * may want to disable it using this flag. This option can be a problem for applications which
+ * handle sensitive data like passwords, and it makes memory checkers like Valgrind noisy. This
+ * flag is not needed with {@link #MDB_WRITEMAP}, which writes directly to the mmap instead of
+ * using malloc for pages. The initialization is also skipped if {@link PutFlags#MDB_RESERVE} is
+ * used; the caller is expected to overwrite all of the memory that was reserved in that case.
*/
MDB_NOMEMINIT(0x100_0000);
@@ -177,5 +144,4 @@ public enum EnvFlags implements MaskedFlag {
public int getMask() {
return mask;
}
-
}
diff --git a/src/main/java/org/lmdbjava/EnvInfo.java b/src/main/java/org/lmdbjava/EnvInfo.java
index a1ae62ba..71169d90 100644
--- a/src/main/java/org/lmdbjava/EnvInfo.java
+++ b/src/main/java/org/lmdbjava/EnvInfo.java
@@ -1,63 +1,48 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
-/**
- * Environment information, as returned by {@link Env#info()}.
- */
+/** Environment information, as returned by {@link Env#info()}. */
public final class EnvInfo {
- /**
- * ID of the last used page.
- */
+ /** ID of the last used page. */
public final long lastPageNumber;
- /**
- * ID of the last committed transaction.
- */
+ /** ID of the last committed transaction. */
public final long lastTransactionId;
- /**
- * Address of map, if fixed.
- */
+ /** Address of map, if fixed. */
public final long mapAddress;
- /**
- * Size of the data memory map.
- */
+ /** Size of the data memory map. */
public final long mapSize;
- /**
- * Max reader slots in the environment.
- */
+ /** Max reader slots in the environment. */
public final int maxReaders;
- /**
- * Max reader slots used in the environment.
- */
+ /** Max reader slots used in the environment. */
public final int numReaders;
- EnvInfo(final long mapAddress, final long mapSize, final long lastPageNumber,
- final long lastTransactionId, final int maxReaders,
- final int numReaders) {
+ EnvInfo(
+ final long mapAddress,
+ final long mapSize,
+ final long lastPageNumber,
+ final long lastTransactionId,
+ final int maxReaders,
+ final int numReaders) {
this.mapAddress = mapAddress;
this.mapSize = mapSize;
this.lastPageNumber = lastPageNumber;
@@ -68,10 +53,19 @@ public final class EnvInfo {
@Override
public String toString() {
- return "EnvInfo{" + "lastPageNumber=" + lastPageNumber
- + ", lastTransactionId=" + lastTransactionId + ", mapAddress="
- + mapAddress + ", mapSize=" + mapSize + ", maxReaders="
- + maxReaders + ", numReaders=" + numReaders + '}';
+ return "EnvInfo{"
+ + "lastPageNumber="
+ + lastPageNumber
+ + ", lastTransactionId="
+ + lastTransactionId
+ + ", mapAddress="
+ + mapAddress
+ + ", mapSize="
+ + mapSize
+ + ", maxReaders="
+ + maxReaders
+ + ", numReaders="
+ + numReaders
+ + '}';
}
-
}
diff --git a/src/main/java/org/lmdbjava/GetOp.java b/src/main/java/org/lmdbjava/GetOp.java
index 9d36c204..666f692c 100644
--- a/src/main/java/org/lmdbjava/GetOp.java
+++ b/src/main/java/org/lmdbjava/GetOp.java
@@ -1,45 +1,32 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
/**
- * Flags for use when performing a
- * {@link Cursor#get(java.lang.Object, org.lmdbjava.GetOp)}.
+ * Flags for use when performing a {@link Cursor#get(java.lang.Object, org.lmdbjava.GetOp)}.
*
- *
- * Unlike most other LMDB enums, this enum is not bit masked.
+ * Unlike most other LMDB enums, this enum is not bit masked.
*/
public enum GetOp {
- /**
- * Position at specified key.
- */
+ /** Position at specified key. */
MDB_SET(15),
- /**
- * Position at specified key, return key + data.
- */
+ /** Position at specified key, return key + data. */
MDB_SET_KEY(16),
- /**
- * Position at first key greater than or equal to specified key.
- */
+ /** Position at first key greater than or equal to specified key. */
MDB_SET_RANGE(17);
private final int code;
@@ -56,5 +43,4 @@ public enum GetOp {
public int getCode() {
return code;
}
-
}
diff --git a/src/main/java/org/lmdbjava/KeyRange.java b/src/main/java/org/lmdbjava/KeyRange.java
index d47c444c..553346e6 100644
--- a/src/main/java/org/lmdbjava/KeyRange.java
+++ b/src/main/java/org/lmdbjava/KeyRange.java
@@ -1,23 +1,18 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
import static java.util.Objects.requireNonNull;
@@ -27,8 +22,7 @@
/**
* Limits the range and direction of keys to iterate.
*
- *
- * Immutable once created (although the buffers themselves may not be).
+ * Immutable once created (although the buffers themselves may not be).
*
* @param
- * End user code may find it more expressive to use one of the static methods
- * provided on this class.
+ * End user code may find it more expressive to use one of the static methods provided on this
+ * class.
*
- * @param type key type
+ * @param type key type
* @param start start key (required if applicable for the passed range type)
- * @param stop stop key (required if applicable for the passed range type)
+ * @param stop stop key (required if applicable for the passed range type)
*/
public KeyRange(final KeyRangeType type, final T start, final T stop) {
requireNonNull(type, "Key range type is required");
@@ -87,7 +80,7 @@ public static MDB_val pointer in bytes.
- */
+ /** Size of a MDB_val pointer in bytes. */
protected static final int MDB_VAL_STRUCT_SIZE = BYTES * 2;
- /**
- * Offset from a pointer of the MDB_val.mv_data field.
- */
+ /** Offset from a pointer of the MDB_val.mv_data field. */
protected static final int STRUCT_FIELD_OFFSET_DATA = BYTES;
- /**
- * Offset from a pointer of the MDB_val.mv_size field.
- */
+ /** Offset from a pointer of the MDB_val.mv_size field. */
protected static final int STRUCT_FIELD_OFFSET_SIZE = 0;
+ /** Explicitly-defined default constructor to avoid warnings. */
+ protected BufferProxy() {}
+
/**
- * Allocate a new buffer suitable for passing to
- * {@link #out(java.lang.Object, jnr.ffi.Pointer, long)}.
+ * Allocate a new buffer suitable for passing to {@link #out(java.lang.Object, jnr.ffi.Pointer,
+ * long)}.
*
* @return a buffer for passing to the out method
*/
protected abstract T allocate();
+ /**
+ * Deallocate a buffer that was previously provided by {@link #allocate()}.
+ *
+ * @param buff the buffer to deallocate (required)
+ */
+ protected abstract void deallocate(T buff);
+
+ /**
+ * Obtain a copy of the bytes contained within the passed buffer.
+ *
+ * @param buffer a non-null buffer created by this proxy instance
+ * @return a copy of the bytes this buffer is currently representing
+ */
+ protected abstract byte[] getBytes(T buffer);
+
/**
* Get a suitable default {@link Comparator} given the provided flags.
*
- * MDB_val should be set to reflect the passed
- * buffer. This buffer will have been created by end users, not
- * {@link #allocate()}.
+ * Called when the MDB_val should be set to reflect the passed buffer. This buffer
+ * will have been created by end users, not {@link #allocate()}.
*
- * @param buffer the buffer to write to MDB_val
- * @param ptr the pointer to the MDB_val
+ * @param buffer the buffer to write to MDB_val
+ * @param ptr the pointer to the MDB_val
* @param ptrAddr the address of the MDB_val pointer
*/
protected abstract void in(T buffer, Pointer ptr, long ptrAddr);
/**
- * Called when the MDB_val should be set to reflect the passed
- * buffer.
+ * Called when the MDB_val should be set to reflect the passed buffer.
*
- * @param buffer the buffer to write to MDB_val
- * @param size the buffer size to write to MDB_val
- * @param ptr the pointer to the MDB_val
+ * @param buffer the buffer to write to MDB_val
+ * @param size the buffer size to write to MDB_val
+ * @param ptr the pointer to the MDB_val
* @param ptrAddr the address of the MDB_val pointer
*/
protected abstract void in(T buffer, int size, Pointer ptr, long ptrAddr);
/**
- * Called when the MDB_val may have changed and the passed buffer
- * should be modified to reflect the new MDB_val.
+ * Called when the MDB_val may have changed and the passed buffer should be modified
+ * to reflect the new MDB_val.
*
- * @param buffer the buffer to write to MDB_val
- * @param ptr the pointer to the MDB_val
+ * @param buffer the buffer to write to MDB_val
+ * @param ptr the pointer to the MDB_val
* @param ptrAddr the address of the MDB_val pointer
* @return the buffer for MDB_val
*/
@@ -150,5 +140,4 @@ protected Comparator
- *
*
- * true
- * and/or {@link UnsafeAccess} is unavailable. Guaranteed to never be null.
+ * The fastest {@link ByteBuffer} proxy that is available on this platform. This will always be
+ * the same instance as {@link #PROXY_SAFE} if the {@link UnsafeAccess#DISABLE_UNSAFE_PROP} has
+ * been set to true and/or {@link UnsafeAccess} is unavailable. Guaranteed to never
+ * be null.
*/
public static final BufferProxyMDB_MULTIPLE
- * operation.
+ * Put multiple values into the database in one MDB_MULTIPLE operation.
*
- * MDB_MULTIPLE)
+ * @param op options for operation (must set MDB_MULTIPLE)
*/
- public void putMultiple(final T key, final T val, final int elements,
- final PutFlags... op) {
+ public void putMultiple(final T key, final T val, final int elements, final PutFlags... op) {
if (SHOULD_CHECK) {
requireNonNull(txn);
requireNonNull(key);
@@ -307,8 +289,7 @@ public void putMultiple(final T key, final T val, final int elements,
}
txn.kv().keyIn(key);
final Pointer dataPtr = txn.kv().valInMulti(val, elements);
- final int rc = LIB.mdb_cursor_put(ptrCursor, txn.kv().pointerKey(),
- dataPtr, mask);
+ final int rc = LIB.mdb_cursor_put(ptrCursor, txn.kv().pointerKey(), dataPtr, mask);
checkRc(rc);
ReferenceUtil.reachabilityFence0(key);
ReferenceUtil.reachabilityFence0(val);
@@ -317,13 +298,10 @@ public void putMultiple(final T key, final T val, final int elements,
/**
* Renew a cursor handle.
*
- *
- *
*/
public static final class IncompatibleException extends LmdbNativeException {
@@ -527,14 +498,11 @@ public static final class IncompatibleException extends LmdbNativeException {
private static final long serialVersionUID = 1L;
IncompatibleException() {
- super(MDB_INCOMPATIBLE,
- "Operation and DB incompatible, or DB type changed");
+ super(MDB_INCOMPATIBLE, "Operation and DB incompatible, or DB type changed");
}
}
- /**
- * Key/data pair already exists.
- */
+ /** Key/data pair already exists. */
public static final class KeyExistsException extends LmdbNativeException {
static final int MDB_KEYEXIST = -30_799;
@@ -545,9 +513,7 @@ public static final class KeyExistsException extends LmdbNativeException {
}
}
- /**
- * Key/data pair not found (EOF).
- */
+ /** Key/data pair not found (EOF). */
public static final class KeyNotFoundException extends LmdbNativeException {
static final int MDB_NOTFOUND = -30_798;
@@ -558,9 +524,7 @@ public static final class KeyNotFoundException extends LmdbNativeException {
}
}
- /**
- * Database contents grew beyond environment mapsize.
- */
+ /** Database contents grew beyond environment mapsize. */
public static final class MapResizedException extends LmdbNativeException {
static final int MDB_MAP_RESIZED = -30_785;
diff --git a/src/main/java/org/lmdbjava/DbiFlags.java b/src/main/java/org/lmdbjava/DbiFlags.java
index 7277b55b..123ec9fd 100644
--- a/src/main/java/org/lmdbjava/DbiFlags.java
+++ b/src/main/java/org/lmdbjava/DbiFlags.java
@@ -1,96 +1,79 @@
-/*-
- * #%L
- * LmdbJava
- * %%
- * Copyright (C) 2016 - 2023 The LmdbJava Open Source Project
- * %%
+/*
+ * Copyright © 2016-2025 The LmdbJava Open Source Project
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * #L%
*/
-
package org.lmdbjava;
-/**
- * Flags for use when opening a {@link Dbi}.
- */
+/** Flags for use when opening a {@link Dbi}. */
public enum DbiFlags implements MaskedFlag {
/**
* Use reverse string keys.
*
- * Dbi is available in the
- * Env.
+ * Dbi is available in the Env.
*
- * @param name name of the database (or null if no name is required)
+ * @param name name of the database (or null if no name is required)
* @param comparator custom comparator callback (or null to use LMDB default)
- * @param nativeCb whether native code calls back to the Java comparator
- * @param flags to open the database with
+ * @param nativeCb whether native code calls back to the Java comparator
+ * @param flags to open the database with
* @return a database that is ready to use
*/
- public DbiDbi in the Env.
- *
- * nativeCb is true. This is
- * usually avoided due to the overhead of native code calling back into Java.
- * It is instead highly recommended to set the correct {@link DbiFlags} to
- * allow the native library to correctly order the intended keys.
- *
- * null is passed as the
- * comparator. If a custom comparator is provided, it must strictly match the
- * lexicographical order of keys in the native LMDB database.
- *
- * Dbi in the Env.
+ *
+ * nativeCb is true.
+ * This is usually avoided due to the overhead of native code calling back into Java. It is
+ * instead highly recommended to set the correct {@link DbiFlags} to allow the native library to
+ * correctly order the intended keys.
+ *
+ * null is passed as the comparator. If a
+ * custom comparator is provided, it must strictly match the lexicographical order of keys in the
+ * native LMDB database.
+ *
+ *