Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Iterator performance#270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
stroomdev66 wants to merge17 commits intomaster
base:master
Choose a base branch
Loading
fromiterator-performance
Draft

Conversation

@stroomdev66
Copy link
Collaborator

@stroomdev66stroomdev66 commentedNov 4, 2025
edited
Loading

This is just a draft for now to show iterator performance improvements when using specific classes for cursor direction etc and removing the state machine approach.

Closesgh-269

@stroomdev66
Copy link
CollaboratorAuthor

This is just a draft for discussion. If the approach is accepted then the current iterator would be replaced to maintain API compatability.

@codecov
Copy link

codecovbot commentedNov 4, 2025
edited
Loading

Codecov Report

❌ Patch coverage is65.05190% with202 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.64%. Comparing base (65df2ee) to head (7d04445).

Files with missing linesPatch %Lines
src/main/java/org/lmdbjava/DirectBufferProxy.java0.00%40 Missing⚠️
src/main/java/org/lmdbjava/KeyRange.java68.68%31 Missing⚠️
src/main/java/org/lmdbjava/Dbi.java28.57%23 Missing and 2 partials⚠️
src/main/java/org/lmdbjava/ByteArrayProxy.java0.00%24 Missing⚠️
src/main/java/org/lmdbjava/ByteBufferProxy.java38.46%16 Missing and 8 partials⚠️
src/main/java/org/lmdbjava/LmdbIterable.java84.24%15 Missing and 8 partials⚠️
src/main/java/org/lmdbjava/LmdbStream.java85.41%14 Missing and 7 partials⚠️
src/main/java/org/lmdbjava/ByteBufProxy.java0.00%12 Missing⚠️
src/main/java/org/lmdbjava/CursorIterable.java87.50%0 Missing and 2 partials⚠️
Additional details and impacted files
@@             Coverage Diff              @@##             master     #270      +/-   ##============================================- Coverage     89.06%   82.64%   -6.43%- Complexity      413      449      +36============================================  Files            32       34       +2       Lines          1482     2040     +558       Branches        125      227     +102     ============================================+ Hits           1320     1686     +366- Misses           92      261     +169- Partials         70       93      +23

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report?Share it here.

🚀 New features to boost your workflow:
  • ❄️Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));
}else {
returnbb(Long.parseLong(key.trim()));

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note test

Potential uncaught 'java.lang.NumberFormatException'.

Copilot Autofix

AI 2 days ago

To fix the problem, surround the parse operations in theparseKey method (lines 216, 218, 222, and 224) with try-catch blocks forNumberFormatException. If a parsing error occurs, the method should handle it appropriately; in this case, returningnull would gracefully indicate an unparseable key without propagating the exception. No additional imports are required, asNumberFormatException is injava.lang. The required change is limited to the body ofparseKey withinsrc/test/java/org/lmdbjava/LmdbStreamRangeTest.java. No changes needed to imports, method signatures, or globals.


Suggested changeset1
src/test/java/org/lmdbjava/LmdbStreamRangeTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git applydiff --git a/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java b/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java--- a/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java+++ b/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java@@ -211,18 +211,23 @@    private ByteBuffer parseKey(final String key, final int keyLen, final ByteOrder byteOrder) {     if (key != null) {-      if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {-        if (keyLen == Integer.BYTES) {-          return bbLeInt(Integer.parseInt(key.trim()));+      try {+        if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {+          if (keyLen == Integer.BYTES) {+            return bbLeInt(Integer.parseInt(key.trim()));+          } else {+            return bbLeLong(Long.parseLong(key.trim()));+          }         } else {-          return bbLeLong(Long.parseLong(key.trim()));+          if (keyLen == Integer.BYTES) {+            return bb(Integer.parseInt(key.trim()));+          } else {+            return bb(Long.parseLong(key.trim()));+          }         }-      } else {-        if (keyLen == Integer.BYTES) {-          return bb(Integer.parseInt(key.trim()));-        } else {-          return bb(Long.parseLong(key.trim()));-        }+      } catch (NumberFormatException e) {+        // Handle invalid key format by returning null+        return null;       }     }     return null;EOF
@@ -211,18 +211,23 @@

privateByteBufferparseKey(finalStringkey,finalintkeyLen,finalByteOrderbyteOrder) {
if (key !=null) {
if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {
if (keyLen ==Integer.BYTES) {
returnbbLeInt(Integer.parseInt(key.trim()));
try {
if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {
if (keyLen ==Integer.BYTES) {
returnbbLeInt(Integer.parseInt(key.trim()));
}else {
returnbbLeLong(Long.parseLong(key.trim()));
}
}else {
returnbbLeLong(Long.parseLong(key.trim()));
if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));
}else {
returnbb(Long.parseLong(key.trim()));
}
}
}else {
if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));
}else {
returnbb(Long.parseLong(key.trim()));
}
}catch (NumberFormatExceptione) {
// Handle invalid key format by returning null
returnnull;
}
}
returnnull;
}
}else {
if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note test

Potential uncaught 'java.lang.NumberFormatException'.

Copilot Autofix

AI 2 days ago

To fix the problem, we should wrap each call toInteger.parseInt andLong.parseLong withinparseKey in a try-catch block that catchesNumberFormatException. When a parsing error occurs, we should handle it in a way that fits the function's use case (for tests, often throwing an unchecked exception with a clear message is suitable, or, alternatively, returningnull or bubbling up as a specific checked/unchecked exception). Since this is a test utility, the best approach is probably to throw anIllegalArgumentException with an informative message so test failures are explicit and debuggable. Only the code withinparseKey (lines 212–229) needs to be changed, and no new imports are necessary sinceNumberFormatException andIllegalArgumentException are injava.lang.


Suggested changeset1
src/test/java/org/lmdbjava/LmdbStreamRangeTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git applydiff --git a/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java b/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java--- a/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java+++ b/src/test/java/org/lmdbjava/LmdbStreamRangeTest.java@@ -211,18 +211,23 @@    private ByteBuffer parseKey(final String key, final int keyLen, final ByteOrder byteOrder) {     if (key != null) {-      if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {-        if (keyLen == Integer.BYTES) {-          return bbLeInt(Integer.parseInt(key.trim()));+      try {+        if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {+          if (keyLen == Integer.BYTES) {+            return bbLeInt(Integer.parseInt(key.trim()));+          } else {+            return bbLeLong(Long.parseLong(key.trim()));+          }         } else {-          return bbLeLong(Long.parseLong(key.trim()));+          if (keyLen == Integer.BYTES) {+            return bb(Integer.parseInt(key.trim()));+          } else {+            return bb(Long.parseLong(key.trim()));+          }         }-      } else {-        if (keyLen == Integer.BYTES) {-          return bb(Integer.parseInt(key.trim()));-        } else {-          return bb(Long.parseLong(key.trim()));-        }+      } catch (NumberFormatException e) {+        throw new IllegalArgumentException("Could not parse key string '" + key + "' as a " ++            (keyLen == Integer.BYTES ? "integer" : "long") + ".", e);       }     }     return null;EOF
@@ -211,18 +211,23 @@

privateByteBufferparseKey(finalStringkey,finalintkeyLen,finalByteOrderbyteOrder) {
if (key !=null) {
if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {
if (keyLen ==Integer.BYTES) {
returnbbLeInt(Integer.parseInt(key.trim()));
try {
if (ByteOrder.LITTLE_ENDIAN.equals(byteOrder)) {
if (keyLen ==Integer.BYTES) {
returnbbLeInt(Integer.parseInt(key.trim()));
}else {
returnbbLeLong(Long.parseLong(key.trim()));
}
}else {
returnbbLeLong(Long.parseLong(key.trim()));
if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));
}else {
returnbb(Long.parseLong(key.trim()));
}
}
}else {
if (keyLen ==Integer.BYTES) {
returnbb(Integer.parseInt(key.trim()));
}else {
returnbb(Long.parseLong(key.trim()));
}
}catch (NumberFormatExceptione) {
thrownewIllegalArgumentException("Could not parse key string '" +key +"' as a " +
(keyLen ==Integer.BYTES ?"integer" :"long") +".",e);
}
}
returnnull;
() -> {
longcount =0;
try (finalTxn<ByteBuffer>txn =env.txnRead()) {
for (finalKeyVal<ByteBuffer>ignored :dbi.iterate(txn)) {

Check notice

Code scanning / CodeQL

Unread local variable Note test

Variable 'KeyVal ignored' is never read.

Copilot Autofix

AI 2 days ago

To fix the problem, we should eliminate the declaration of the unused variable in the for-each loop at line 164. The current loop:

for (finalKeyVal<ByteBuffer>ignored :dbi.iterate(txn)) {count++;}

can be rewritten as a standard for-each loop that simply increments the counter for each element, without naming the unused variable, but in Java this isn't technically possible without at least binding the variable. Therefore, as an alternative, we could use a normalfor loop over the result set or, if the variable truly serves no purpose, simply use theforEach method with a lambda that increments the count. This change minimizes the presence of an unread variable and makes the intent clear.

Best fix: Replace the for-each loop with a call to.forEach(e -> count++), which is idiomatic in Java when the loop variable is unused.

Where to change: Only the for-each loop at line 164, withintestIterationMethods insrc/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java.

What is needed: No additional imports or definitions are needed. Only a code change to the loop construct.

Suggested changeset1
src/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git applydiff --git a/src/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java b/src/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java--- a/src/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java+++ b/src/test/java/org/lmdbjava/TestLmdbStreamBenchmark.java@@ -161,9 +161,7 @@           () -> {             long count = 0;             try (final Txn<ByteBuffer> txn = env.txnRead()) {-              for (final KeyVal<ByteBuffer> ignored : dbi.iterate(txn)) {-                count++;-              }+              dbi.iterate(txn).forEach(e -> count++);             }             assertThat(count).isEqualTo(totalRows);           });EOF
@@ -161,9 +161,7 @@
() -> {
longcount =0;
try (finalTxn<ByteBuffer>txn =env.txnRead()) {
for (finalKeyVal<ByteBuffer>ignored :dbi.iterate(txn)) {
count++;
}
dbi.iterate(txn).forEach(e ->count++);
}
assertThat(count).isEqualTo(totalRows);
});
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@benalexaubenalexauAwaiting requested review from benalexau

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Improve iterator performance and add better stream support

2 participants

@stroomdev66

[8]ページ先頭

©2009-2025 Movatter.jp