Code Monkey home page Code Monkey logo

Comments (5)

benalexau avatar benalexau commented on May 20, 2024 1

The working solution is below. I added a character to the value to help prove it's outputting in the correct order. The output is now:

255 000000FF a
256 00000100 b

As shown below with the *** CHANGED *** comments, you just needed to set the key's byte order to native, and remember to set the byte order on the returned Cursor buffer as well. This is necessary as LmdbJava does not have any opinion on which byte order your buffer used (eg a user who is writing a Java only application storing say string keys and integer values may rely on the Java Big Endian default, and would be surprised if the buffer was set to Little Endian behind the scenes on the returned buffer).

The code:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import org.lmdbjava.Cursor;
import org.lmdbjava.Dbi;
import org.lmdbjava.DbiFlags;
import org.lmdbjava.Env;
import org.lmdbjava.Txn;

/**
 * Created by devin on 4/18/17.
 */
public class LMDBIntKey {
    private final ByteBuffer KEY = ByteBuffer.allocateDirect(4);
    private final ByteBuffer VALUE = ByteBuffer.allocateDirect(2);

    private final Env<ByteBuffer> env;
    private final Dbi<ByteBuffer> db;

    public LMDBIntKey() throws IOException {
        final File dir = Files.createTempDirectory(LMDBIntKey.class.getSimpleName()).toFile();
        env = Env.create().open(dir);
        db = env.openDbi(
            LMDBIntKey.class.getSimpleName(),
            DbiFlags.MDB_CREATE,
            DbiFlags.MDB_INTEGERKEY);

        //KEY.order(ByteOrder.BIG_ENDIAN);
        //KEY.order(ByteOrder.LITTLE_ENDIAN);
        KEY.order(ByteOrder.nativeOrder());    /// <---- *** CHANGED ***
    }

    public void execute() {
        KEY.clear();
        KEY.putInt(0x000000FF); // 255
        KEY.flip();
        VALUE.clear();
        VALUE.putChar('a');
        VALUE.flip();
        db.put(KEY, VALUE);

        KEY.clear();
        KEY.putInt(0x00000100); // 256
        KEY.flip();
        VALUE.clear();
        VALUE.putChar('b');
        VALUE.flip();
        db.put(KEY, VALUE);

        try (final Txn<ByteBuffer> txn = env.txnRead()) {
            try (final Cursor<ByteBuffer> cursor = db.openCursor(txn)) {
                if (!cursor.first()) {
                    throw new IllegalStateException("Expected first()");
                }
                cursor.key().order(ByteOrder.nativeOrder());    /// <---- *** CHANGED ***
                System.out.println(String.format("%d %08X %c",
                    cursor.key().getInt(0),
                    cursor.key().getInt(0),
                    cursor.val().getChar(0)));
                if (!cursor.next()) {
                    throw new IllegalStateException("Expected next()");
                }
                System.out.println(String.format("%d %08X %c",
                    cursor.key().getInt(0),
                    cursor.key().getInt(0),
                    cursor.val().getChar(0)));
            }
        }
    }

    public static void main(String[] args) throws IOException {
        final LMDBIntKey wal = new LMDBIntKey();
        wal.execute();
    }
}

Thanks for trying LmdbJava. I hope you find it useful.

from lmdbjava.

benalexau avatar benalexau commented on May 20, 2024 1

It might be useful to consider an optional setting so this happens automatically.

The main challenge is LmdbJava's API tries to be buffer implementation agnostic and the various buffer implementations have distinct methods or idioms to get/set values by byte order. For example ByteBuffer has the order method, byte[] has no inbuilt byte order awareness at all, Agrona's DirectBuffer offers accessor methods with a byte order argument etc. As such most of the buffers don't even have a buffer-wide byte order method we could conveniently call.

We could change our BufferProxy.allocate() to BufferProxy.allocate(ByteOrder) and accept null to mean "don't change it", but I wonder if the complexity of the corresponding Env.Builder<T>.setDefaultOrder(ByteOrder) would be confusing for users where we cannot set the order anyway. It also seems undesirably asymmetric given users have to set byte orders on the put-time buffers anyway. /cc @krisskross thoughts on this?

from lmdbjava.

devinrsmith avatar devinrsmith commented on May 20, 2024

Ah, yes. I didn't think about changing the returned bytebuffers order. I'll assume that this fixes it for now and marked as closed, but will circle back around either way to give the thumbs up or down.

It might be useful to consider an optional setting so this happens automatically.

Thanks for the quick update.

from lmdbjava.

krisskross avatar krisskross commented on May 20, 2024

I agree with @benalexau. It would be quite confusing to have a different default for ByteBuffer. But maybe we could document, reference and/or provide a example the illustrate the ordering of keys and how they're stored?

from lmdbjava.

devinrsmith avatar devinrsmith commented on May 20, 2024

I've confirmed that setting the ByteOrder on the cursor's buffer fixed my issue :).

Documentation seems like the best way to go.

from lmdbjava.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.