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

Appearance settings

closedOpen KeyRange not stopping before end key #169

Copy link
Copy link
@at055612

Description

@at055612
Issue body actions

There seems to be a problem with the byte buffer comparator that occurs when the buffers are larger than the value they hold and it is comparing values of different lengths. The test below illustrates the problem. When comparing key301 to key30 it is getting the wrong result so is incorrectly carrying on past it. When run it finds 6 entries not 3.

I will raise a PR in a minute with the fix to the comparator.

package org.lmdbjava;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class ClosedOpenTest {

    @Rule
    public final TemporaryFolder tmp = new TemporaryFolder();

    @Test
    public void testClosedOpen() throws IOException {

        final File path = tmp.newFile();

        final Env<ByteBuffer> env = Env.create()
                .setMapSize(1024 * 100)
                .setMaxReaders(1)
                .setMaxDbs(1)
                .open(path, TestUtils.POSIX_MODE, EnvFlags.MDB_NOSUBDIR);
        final Dbi<ByteBuffer> db = env.openDbi(TestUtils.DB_1, DbiFlags.MDB_CREATE);

        try (Txn<ByteBuffer> txn = env.txnWrite()) {
            final Cursor<ByteBuffer> c = db.openCursor(txn);
            c.put(bb("key101"), bb("val101"));
            c.put(bb("key102"), bb("val102"));
            c.put(bb("key103"), bb("val103"));
            c.put(bb("key201"), bb("val201"));
            c.put(bb("key202"), bb("val202"));
            c.put(bb("key203"), bb("val203"));
            c.put(bb("key301"), bb("val301"));
            c.put(bb("key302"), bb("val302"));
            c.put(bb("key303"), bb("val303"));
            txn.commit();
        }

        // Should find keys 201, 202 and 203 only
        final KeyRange<ByteBuffer> range = KeyRange.closedOpen(
                bb("key20"),
                bb("key30"));

        final List<String> keysFound = new ArrayList<>();
        try (final Txn<ByteBuffer> txn = env.txnRead();
            final CursorIterable<ByteBuffer> c = db.iterate(txn, range)) {

            for (final CursorIterable.KeyVal<ByteBuffer> kv : c) {
                final String key = StandardCharsets.UTF_8.decode(kv.key()).toString();
                System.out.println(key);
                keysFound.add(key);
            }
        }

        Assert.assertEquals(3, keysFound.size());

        env.close();
    }

    private static ByteBuffer bb(final String value) {
        // Buffer larger than the value
        final ByteBuffer bb = ByteBuffer.allocateDirect(10);
        bb.put(value.getBytes(StandardCharsets.UTF_8));
        bb.flip();
        return bb;
    }
}
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.