diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/Database.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/Database.java index 190eaf9..a654295 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/Database.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/Database.java @@ -287,7 +287,7 @@ private Entry getEqOrGE(Transaction tx, NativeBuffer keyBuffer) { if (rc == MDBX_NOTFOUND) { return null; } - checkErrorCode(env, rc); + checkErrorCode(env, tx, rc); return value.toByteArray(); } @@ -301,7 +301,7 @@ private Entry getEqOrGE(Transaction tx, NativeBuffer keyBuffer) { if (rc == MDBX_NOTFOUND) { return null; } - checkErrorCode(env, rc); + checkErrorCode(env, tx, rc); return new EntryCount(key.toByteArray(), value.toByteArray(), valCnt[0]); } @@ -313,7 +313,7 @@ private Entry getEqOrGE(Transaction tx, NativeBuffer keyBuffer) { if (rc == MDBX_NOTFOUND) { return null; } - checkErrorCode(env, rc); + checkErrorCode(env, tx, rc); return new Entry(key.toByteArray(), value.toByteArray()); } @@ -458,8 +458,8 @@ public byte[] put(Transaction tx, byte[] key, byte[] value, int flags, long valu try { long now = System.currentTimeMillis(); byte[] rc = put(tx, new Value(keyBuffer), value1, value2, flags); - if (log.isDebugEnabled()) - log.debug("Db put:{}, ms:{}", key, System.currentTimeMillis() - now); +// if (log.isDebugEnabled()) +// log.debug("Db put:{}, ms:{}", key, System.currentTimeMillis() - now); return rc; } finally { @@ -791,7 +791,7 @@ private boolean delete(Transaction tx, Value keySlice, Value valueSlice) { if (rc == MDBX_NOTFOUND) { return false; } - checkErrorCode(env, rc); + checkErrorCode(env, tx, rc); deleteSecondaries(tx, keySlice, valueSlices); return true; @@ -834,7 +834,7 @@ public Cursor openCursor(Transaction tx) { long[] cursor = new long[1]; if (log.isTraceEnabled()) log.trace("Calling cursor open for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_cursor_open(tx.pointer(), pointer(), cursor)); + checkErrorCode(env, tx, mdbx_cursor_open(tx.pointer(), pointer(), cursor)); return new Cursor(env, cursor[0], tx, this); } catch (Exception e) { @@ -854,7 +854,7 @@ public SecondaryCursor openSecondaryCursor(Transaction tx) { long[] cursor = new long[1]; if (log.isTraceEnabled()) log.trace("Calling sec cursor open for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_cursor_open(tx.pointer(), pointer(), cursor)); + checkErrorCode(env, tx, mdbx_cursor_open(tx.pointer(), pointer(), cursor)); return new SecondaryCursor(env, cursor[0], tx, this); } catch (Exception e) { @@ -877,7 +877,7 @@ public int getFlags(Transaction tx) { long[] flags = new long[1]; if (log.isTraceEnabled()) log.trace("Calling db flags for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_dbi_flags(tx.pointer(), pointer(), flags)); + checkErrorCode(env, tx, mdbx_dbi_flags(tx.pointer(), pointer(), flags)); return (int)flags[0]; } @@ -886,7 +886,7 @@ public FlagState getFlagsState(Transaction tx) { long[] state = new long[1]; if (log.isTraceEnabled()) log.trace("Calling db flags ex for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_dbi_flags_ex(tx.pointer(), pointer(), flags, state)); + checkErrorCode(env, tx, mdbx_dbi_flags_ex(tx.pointer(), pointer(), flags, state)); return new FlagState((int)flags[0], (int)state[0]); } @@ -894,7 +894,7 @@ public int getDupsortDepthMask(Transaction tx) { long[] mask = new long[1]; if (log.isTraceEnabled()) log.trace("Calling db dupsort for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_dbi_dupsort_depthmask(tx.pointer(), pointer(), mask)); + checkErrorCode(env, tx, mdbx_dbi_dupsort_depthmask(tx.pointer(), pointer(), mask)); return (int)mask[0]; } @@ -902,7 +902,24 @@ public int getSequence(Transaction tx, long increment) { long[] res = new long[1]; if (log.isTraceEnabled()) log.trace("Calling db sequence for {}", this); //$NON-NLS-1$ - checkErrorCode(env, mdbx_dbi_sequence(tx.pointer(), pointer(), res, increment)); + checkErrorCode(env, tx, mdbx_dbi_sequence(tx.pointer(), pointer(), res, increment)); + return (int)res[0]; + } + + public int rename(Transaction tx, String name) { + long[] res = new long[1]; + checkErrorCode(env, tx, mdbx_dbi_rename(tx.pointer(), pointer(), name)); + return (int)res[0]; + } + + @SuppressWarnings("nls") + public int rename2(Transaction tx, byte[] name) { + checkArgNotNull(tx, "tx"); + checkArgNotNull(name, "name"); + + NativeBuffer nameBuffer = NativeBuffer.create(name); + long[] res = new long[1]; + checkErrorCode(env, tx, mdbx_dbi_rename2(tx.pointer(), pointer(), new Value(nameBuffer))); return (int)res[0]; } diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/Env.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/Env.java index 266be39..e13e6bd 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/Env.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/Env.java @@ -80,13 +80,13 @@ public static String version() { return "" + JNI.MDBX_VERSION_MAJOR + '.' + JNI.MDBX_VERSION_MINOR; //$NON-NLS-1$ } -// public static BuildInfo buildInfo() { -// MDBX_build_info rc = new MDBX_build_info(); -// -// NativeBuffer buffer = NativeBuffer.create(JNI.SIZEOF_BUILDINFO); -// get_mdbx_build_info(buffer.pointer(), JNI.SIZEOF_BUILDINFO); -// return new BuildInfo(rc); -// } + public static BuildInfo buildInfo() { + MDBX_build_info rc = new MDBX_build_info(); + + NativeBuffer buffer = NativeBuffer.create(JNI.SIZEOF_BUILDINFO); +// mdbx_build(); + return new BuildInfo(rc); + } // printf("mdbx_copy version %d.%d.%d.%d\n" @@ -345,8 +345,8 @@ public void open(String path, EnvConfig config) { mainDb = new Database(this, 1L, MAIN_DB); } - if (config.isUsePooledCursors()) { CursorPoolConfig poolConfig = new CursorPoolConfig(); + if (config.isUsePooledCursors()) { poolConfig.setTimeBetweenEvictionRuns(config.getPooledCursorTimeBetweenEvictionRuns()); poolConfig.setMaxIdlePerKey(config.getPooledCursorMaxIdle()); poolConfig.setSoftMinEvictableIdleTime(config.getPooledCursorMinEvictableIdleTime()); @@ -856,7 +856,7 @@ public Database openDatabase(Transaction tx, String name, int flags) { checkArgNotNull(tx, "tx"); //$NON-NLS-1$ // checkArgNotNull(name, "name"); long[] dbi = new long[1]; - checkErrorCode(this, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); + checkErrorCode(this, tx, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); return new Database(this, dbi[0], name); } @@ -960,7 +960,7 @@ public Database openDatabase(Transaction tx, String name, int flags, Comparator< dataComparator = dataComp; } - checkErrorCode(this, mdbx_dbi_open_ex(tx.pointer(), name, flags, dbi, keyCmpAddr, dataCmpAddr)); + checkErrorCode(this, tx, mdbx_dbi_open_ex(tx.pointer(), name, flags, dbi, keyCmpAddr, dataCmpAddr)); return new Database(this, dbi[0], name); } @@ -1016,7 +1016,7 @@ public SecondaryDatabase openSecondaryDatabase(Transaction tx, Database primary, checkArgNotNull(primary, "primary"); //$NON-NLS-1$ // checkArgNotNull(name, "name"); long[] dbi = new long[1]; - checkErrorCode(this, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); + checkErrorCode(this, tx, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); SecondaryDbConfig config = new SecondaryDbConfig(); SecondaryDatabase secDb = new SecondaryDatabase(this, primary, dbi[0], name, config); @@ -1050,7 +1050,7 @@ public SecondaryDatabase openSecondaryDatabase(Transaction tx, Database primary, int flags = setFlags(config); long[] dbi = new long[1]; - checkErrorCode(this, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); + checkErrorCode(this, tx, mdbx_dbi_open(tx.pointer(), name, flags, dbi)); SecondaryDatabase secDb = new SecondaryDatabase(this, primary, dbi[0], name, config); if (associateDbs(tx, primary, secDb)) { diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/JNI.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/JNI.java index 498387c..64b3f45 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/JNI.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/JNI.java @@ -108,25 +108,6 @@ public static final native void buffer_copy ( @JniField(flags = { CONSTANT }) public static int MDBX_VERSION_MINOR; -// @JniClass(flags = {STRUCT}) -// public static class git { -// public String datetime; -// public String tree; -// public String commit; -// public String describe; -// -// @SuppressWarnings("nls") -// @Override -// public String toString() { -// return "{" + -// "datetime=" + datetime + -// ", tree=" + tree + -// ", commit=" + commit + -// ", describe=" + describe + -// '}'; -// } -// } - @JniClass(flags = STRUCT) public static class MDBX_version_info { @JniField(cast = "uint8_t") @@ -139,18 +120,16 @@ public static class MDBX_version_info { public int revision; @JniField(accessor="git.datetime", cast = "char *") - public static char[] git_datetime; + public char[] git_datetime; @JniField(accessor="git.tree", cast = "char *") - public static char[] git_tree; + public char[] git_tree; @JniField(accessor="git.commit", cast = "char *") - public static char[] git_commit; + public char[] git_commit; @JniField(accessor="git.describe", cast = "char *") - public static char[] git_describe; - @JniField(accessor="sourcery", cast = "char *") - public static char[] sourcery; + public char[] git_describe; -// @JniField(cast = "mdbx_version_info.git *") -// public git git = new git(); + @JniField(accessor="sourcery", cast = "char *") + public char[] sourcery; @SuppressWarnings("nls") @Override @@ -160,7 +139,11 @@ public String toString() { ", minor=" + minor + ", release=" + release + ", revision=" + revision + -// ", git=" + git + + ", revision=" + new String(git_datetime) + + ", git tree=" + new String(git_tree) + + ", git commit=" + new String(git_commit) + + ", git describe=" + new String(git_describe) + + ", sourcery=" + new String(sourcery) + '}'; } @@ -170,7 +153,11 @@ public String getVersionString() { } } +// @JniMethod(flags={CONSTANT_GETTER}) +// public static final native int mdbx_version(); + // @JniField(flags = { CONSTANT }) +// public static int mdbx_version; // public static MDBX_version_info mdbx_version; //====================================================// @@ -933,6 +920,8 @@ public String toString() { @JniField(flags = { CONSTANT }) public static int MDBX_EREMOTE; @JniField(flags = { CONSTANT }) + public static int MDBX_EDEADLK; + @JniField(flags = { CONSTANT }) public static int MDBX_SUCCESS; @JniField(flags = { CONSTANT }) public static int MDBX_RESULT_FALSE; @@ -1005,6 +994,8 @@ public String toString() { @JniField(flags = { CONSTANT }) public static int MDBX_DUPLICATED_CLK; @JniField(flags = { CONSTANT }) + public static int MDBX_DANGLING_DBI; + @JniField(flags = { CONSTANT }) public static int MDBX_LAST_ADDED_ERRCODE; // @JniClass(flags = {STRUCT}) @@ -1060,18 +1051,21 @@ public static class MDBX_envinfo { public long mi_latter_reader_txnid; /* ID of the last reader transaction */ @JniField(cast = "uint64_t") public long mi_self_latter_reader_txnid; /* ID of the last reader transaction of caller process */ - @JniField(cast = "uint64_t") + + @JniField(accessor="mi_meta_txnid[0]", cast = "uint64_t") public long mi_meta0_txnid; - @JniField(cast = "uint64_t") - public long mi_meta0_sign; - @JniField(cast = "uint64_t") + @JniField(accessor="mi_meta_txnid[1]", cast = "uint64_t") public long mi_meta1_txnid; - @JniField(cast = "uint64_t") - public long mi_meta1_sign; - @JniField(cast = "uint64_t") + @JniField(accessor="mi_meta_txnid[1]", cast = "uint64_t") public long mi_meta2_txnid; - @JniField(cast = "uint64_t") + + @JniField(accessor="mi_meta_sign[0]", cast = "uint64_t") + public long mi_meta0_sign; + @JniField(accessor="mi_meta_sign[1]", cast = "uint64_t") + public long mi_meta1_sign; + @JniField(accessor="mi_meta_sign[2]", cast = "uint64_t") public long mi_meta2_sign; + @JniField(cast = "uint32_t") public long mi_maxreaders; /* max reader slots in the environment */ @JniField(cast = "uint32_t") @@ -1084,18 +1078,20 @@ public static class MDBX_envinfo { public long mi_bootid_current_x; @JniField(accessor="mi_bootid.current.y", cast = "uint64_t") public long mi_bootid_current_y; - @JniField(accessor="mi_bootid.meta0.x", cast = "uint64_t") + + @JniField(accessor="mi_bootid.meta[0].x", cast = "uint64_t") public long mi_bootid_meta0_x; - @JniField(accessor="mi_bootid.meta0.y", cast = "uint64_t") + @JniField(accessor="mi_bootid.meta[0].y", cast = "uint64_t") public long mi_bootid_meta0_y; - @JniField(accessor="mi_bootid.meta1.x", cast = "uint64_t") + @JniField(accessor="mi_bootid.meta[1].x", cast = "uint64_t") public long mi_bootid_meta1_x; - @JniField(accessor="mi_bootid.meta1.y", cast = "uint64_t") + @JniField(accessor="mi_bootid.meta[1].y", cast = "uint64_t") public long mi_bootid_meta1_y; - @JniField(accessor="mi_bootid.meta2.x", cast = "uint64_t") + @JniField(accessor="mi_bootid.meta[2].x", cast = "uint64_t") public long mi_bootid_meta2_x; - @JniField(accessor="mi_bootid.meta2.y", cast = "uint64_t") + @JniField(accessor="mi_bootid.meta[2].y", cast = "uint64_t") public long mi_bootid_meta2_y; + @JniField(cast = "uint64_t") public long mi_unsync_volume; @JniField(cast = "uint64_t") @@ -1153,18 +1149,21 @@ public String toString() { ", mi_meta1_sign=" + mi_meta1_sign + ", mi_meta2_txnid=" + mi_meta2_txnid + ", mi_meta2_sign=" + mi_meta2_sign + + ", mi_maxreaders=" + mi_maxreaders + ", mi_numreaders=" + mi_numreaders + ", mi_dxb_pagesize=" + mi_dxb_pagesize + ", mi_sys_pagesize=" + mi_sys_pagesize + ", mi_bootid_current_x=" + mi_bootid_current_x + ", mi_bootid_current_y=" + mi_bootid_current_y + + ", mi_bootid_meta0_x=" + mi_bootid_meta0_x + ", mi_bootid_meta0_y=" + mi_bootid_meta0_y + ", mi_bootid_meta1_x=" + mi_bootid_meta1_x + ", mi_bootid_meta1_y=" + mi_bootid_meta1_y + ", mi_bootid_meta2_x=" + mi_bootid_meta2_x + ", mi_bootid_meta2_y=" + mi_bootid_meta2_y + + ", mi_unsync_volume=" + mi_unsync_volume + ", mi_autosync_threshold=" + mi_autosync_threshold + ", mi_since_sync_seconds16dot16=" + mi_since_sync_seconds16dot16 + @@ -1234,9 +1233,9 @@ public String toString() { // @JniField(accessor = "const struct MDBX_build_info", flags = { CONSTANT }) // public static MDBX_build_info mdbx_build; -//@JniField(accessor="mdbx_version", flags = { CONSTANT }) -// @JniField(cast = "const struct MDBX_version_info", flags = { CONSTANT }) -// public static MDBX_version_info mdbx_version; +// @JniField(accessor="mdbx_version", flags = { CONSTANT }) +// @JniField(cast = "const struct MDBX_version_info", flags = { CONSTANT }) +// public static MDBX_version_info mdbx_version; // ====================================================// @@ -1260,6 +1259,9 @@ public static final native void map_val( // @JniArg(cast = "void *", flags = {NO_IN}) long arg, // @JniArg(cast = "size_t") long bytes); +// @JniMethod +// public static final native int mdbx_build(); + // ====================================================// // Debug methods // ====================================================// @@ -1612,9 +1614,32 @@ public static final native void mdbx_txn_reset( public static final native int mdbx_txn_renew( @JniArg(cast = "MDBX_txn *") long txn); + /** + * \brief Unbind or closes all cursors of a given transaction. + * \ingroup c_cursors + * + * Unbinds either closes all cursors associated (opened or renewed) with + * a given transaction in a bulk with minimal overhead. + * + * \see mdbx_cursor_unbind() + * \see mdbx_cursor_close() + * + * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). + * \param [in] unbind If non-zero, unbinds cursors and leaves ones reusable. + * Otherwise close and dispose cursors. + * + * \returns A negative error value on failure or the number of closed cursors + * on success, some possible errors are: + * \retval MDBX_THREAD_MISMATCH Given transaction is not owned + * by current thread. + * \retval MDBX_BAD_TXN Given transaction is invalid or has + * a child/nested transaction transaction. + */ @JniMethod public static final native int mdbx_txn_release_all_cursors( - @JniArg(cast = "MDBX_txn *") long txn); + @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "int") int unbind + ); /** * Return information about the MDBX transaction. @@ -1644,6 +1669,25 @@ public static final native int mdbx_txn_set_userctx( public static final native long mdbx_txn_get_userctx( @JniArg(cast = "MDBX_txn *") long txn); + /** + * \brief Acquires write-transaction lock. + * Provided for custom and/or complex locking scenarios. + * \returns A non-zero error value on failure and 0 on success. + */ + @JniMethod + public static final native int mdbx_txn_lock( + @JniArg(cast = "MDBX_env *", flags = {NO_OUT}) long env, + @JniArg(cast = "int") int dont_wait); //_Bool + + /** + * \brief Releases write-transaction lock. + * Provided for custom and/or complex locking scenarios. + * \returns A non-zero error value on failure and 0 on success. + */ + @JniMethod + public static final native int mdbx_txn_unlock( + @JniArg(cast = "MDBX_env *", flags = {NO_OUT}) long env); + //====================================================// // DBI methods //====================================================// @@ -1665,20 +1709,20 @@ public static final native int mdbx_dbi_open_ex( @JniMethod public static final native int mdbx_dbi_stat( - @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "const MDBX_txn *") long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_stat *", flags = {NO_IN}) MDBX_stat stat, @JniArg(cast = "size_t") long bytes); @JniMethod public static final native int mdbx_dbi_flags( - @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "const MDBX_txn *") long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "unsigned *") long[] flags); @JniMethod public static final native int mdbx_dbi_flags_ex( - @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "const MDBX_txn *") long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "unsigned *") long[] flags, @JniArg(cast = "unsigned *") long[] state); @@ -1701,19 +1745,31 @@ public static final native int mdbx_dbi_sequence( @JniArg(cast = "uint64_t *", flags = {NO_IN}) long[] result, @JniArg(cast = "uint64_t") long increment); + @JniMethod + public static final native int mdbx_dbi_rename( + @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "uint32_t") long dbi, + @JniArg(cast = "const char *") String name); + + @JniMethod + public static final native int mdbx_dbi_rename2( + @JniArg(cast = "MDBX_txn *") long txn, + @JniArg(cast = "uint32_t") long dbi, + @JniArg(cast = "MDBX_val *", flags={NO_IN}) MDBX_val name); + //====================================================// // CRUD methods //====================================================// @JniMethod public static final native int mdbx_get( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_val *", flags={NO_OUT}) MDBX_val key, @JniArg(cast = "MDBX_val *") MDBX_val data); @JniMethod public static final native int mdbx_get_ex( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_val *") MDBX_val key, @JniArg(cast = "MDBX_val *") MDBX_val data, @@ -1729,7 +1785,7 @@ public static final native int mdbx_get_ex( @JniMethod public static final native int mdbx_get_equal_or_great( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_val *") MDBX_val key, @JniArg(cast = "MDBX_val *") MDBX_val data); @@ -1830,7 +1886,7 @@ public static final native int mdbx_canary_put( */ @JniMethod public static final native int mdbx_cursor_open( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_cursor **", flags={NO_IN}) long[] cursor); @@ -1840,12 +1896,12 @@ public static final native void mdbx_cursor_close( @JniMethod public static final native int mdbx_cursor_renew( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "MDBX_cursor *", flags={NO_OUT}) long cursor); @JniMethod public static final native int mdbx_cursor_bind( - @JniArg(cast = "MDBX_txn *", flags={NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags={NO_OUT}) long txn, @JniArg(cast = "MDBX_cursor *", flags={NO_OUT}) long cursor, @JniArg(cast = "uint32_t") long dbi); @@ -2082,7 +2138,7 @@ public static final native int mdbx_estimate_move( @JniMethod public static final native int mdbx_estimate_range( - @JniArg(cast = "MDBX_txn *", flags = {NO_OUT}) long txn, + @JniArg(cast = "const MDBX_txn *", flags = {NO_OUT}) long txn, @JniArg(cast = "uint32_t") long dbi, @JniArg(cast = "MDBX_val *") MDBX_val begin_key, @JniArg(cast = "MDBX_val *") MDBX_val begin_data, diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/JNIIntern.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/JNIIntern.java index cc5ba9e..c875e62 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/JNIIntern.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/JNIIntern.java @@ -142,7 +142,7 @@ public static class MDBX_cursor { public long mc_dbx; /** The mt_dbistate for this database */ @JniField(cast = "uint8_t *") - public long mc_dbistate; + public long mc_dbi_state; /** number of pushed pages */ @JniField(cast = "uint8_t") public short mc_snum; diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/MDBXException.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/MDBXException.java index c093af1..6b9f8bd 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/MDBXException.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/MDBXException.java @@ -40,6 +40,7 @@ public enum Status { EINTR(JNI.MDBX_EINTR, "Cancelled"), ENOFILE(JNI.MDBX_ENOFILE, "File not found"), EREMOTE(JNI.MDBX_EREMOTE, "Remote storage media error"), + EDEADLK(JNI.MDBX_EDEADLK, "Possible Deadlock"), RESULT_FALSE(JNI.MDBX_RESULT_FALSE, "Alias for Successful result"), RESULT_TRUE(JNI.MDBX_RESULT_TRUE, "Successful result with special meaning or a flag"), KEYEXIST(JNI.MDBX_KEYEXIST, "key/data pair already exists"), @@ -73,6 +74,9 @@ public enum Status { TOO_LARGE(JNI.MDBX_TOO_LARGE, "Database is too large for current system, e.g. could NOT be mapped into RAM."), THREAD_MISMATCH(JNI.MDBX_THREAD_MISMATCH, "A thread has attempted to use a not owned object, e.g. a transaction that started by another thread."), TXN_OVERLAPPING(JNI.MDBX_TXN_OVERLAPPING, "Overlapping read and write transactions for the current thread"), + BACKLOG_DEPLETED(JNI.MDBX_BACKLOG_DEPLETED, "Internal error returned if there is not enough free pages available when updating GC. Used as a debugging aid. From the user's point of view, semantically is equivalent to MDBX_PROBLEM."), + DUPLICATED_CLK(JNI.MDBX_DUPLICATED_CLK, "Alternative/Duplicate LCK-file is exists and should be removed manually"), + DANGLING_DBI(JNI.MDBX_DANGLING_DBI, "Some cursors and/or other resources should be closed before subDb or corresponding DBI-handle could be (re)used"), LAST_ADDED_ERRCODE(JNI.MDBX_LAST_ADDED_ERRCODE, "The last added error code"), ; diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/Transaction.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/Transaction.java index 1fc4716..c5baa0d 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/Transaction.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/Transaction.java @@ -55,6 +55,13 @@ public class Transaction extends NativeObject implements Closeable { this.readOnly = readOnly; } + /** + * @return true if the transaction is read only + */ + public boolean isReadOnly() { + return readOnly; + } + /** * Transaction are associated with a specific thread and will throw an MDBX_THREAD_MISMATCH if used with the * wrong thread. This method provides visibility into the creating thread. @@ -92,7 +99,7 @@ public void renew() { } public int releaseCursors() { - return mdbx_txn_release_all_cursors(pointer()); + return mdbx_txn_release_all_cursors(pointer(), 0); } /** @@ -229,7 +236,7 @@ public void setLogData(Object logData) { @Override public void close() { - if (readOnly) + if (isReadOnly()) abort(); commit(); } diff --git a/mdbxjni/src/main/java/com/castortech/mdbxjni/Util.java b/mdbxjni/src/main/java/com/castortech/mdbxjni/Util.java index 7ed5a1f..f5ff8db 100644 --- a/mdbxjni/src/main/java/com/castortech/mdbxjni/Util.java +++ b/mdbxjni/src/main/java/com/castortech/mdbxjni/Util.java @@ -68,7 +68,7 @@ public static void checkErrorCode(Env env, Transaction txn, int rc) { if (rc != JNI.MDBX_SUCCESS && rc != JNI.MDBX_RESULT_TRUE) { String msg = string(mdbx_strerror(rc)); if (env != null) { - log.info("MDBX Exception. Msg:{}, Env:{}", msg, env.info().toString()); + log.info("MDBX Exception. Msg:{}, Env:{}", msg, env.info(txn).toString()); } throw new MDBXException(msg, rc); }