ChronicleMap Value Type Example

317 views
Skip to first unread message

Paul Weiss

unread,
Nov 17, 2015, 9:18:25 AM11/17/15
to Chronicle
Hi,

I would like to create a class which is a value type that contains primitive arrays and other primitive values.  Is there an example I could look at to achieve this?  Ideally would like to persist nested types as well but not sure if that is possible because the size of the value would be variant.

thanks,
-paul

Roman Leventov

unread,
Nov 17, 2015, 9:22:42 AM11/17/15
to java-ch...@googlegroups.com
You should implement BytesMarshaller for your complex type, like in this example: https://github.com/OpenHFT/Chronicle-Map/blob/a13bf449d0b3f2fb1719e6385368529128f9400b/src/test/java/net/openhft/chronicle/map/example/ComplexSerializationTest.java and configure for the ChronicleMapBuilder,

map = ChronicleMap.of(Key.class, MyValue.class).entries(N).averageKey(...).valueMarshaller(MyValueMarshaller.INSTANCE).averageValue(...).create();

--
You received this message because you are subscribed to the Google Groups "Chronicle" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-chronicl...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Paul Weiss

unread,
Nov 17, 2015, 9:39:07 AM11/17/15
to Chronicle
Thanks Roman.  If I had an array of complex types (like A in the below example) and I wanted to ensure they remained offheap and are not copied how would I access individual elements without having to copy the entire array back to the JVM?

Peter Lawrey

unread,
Nov 17, 2015, 10:23:51 AM11/17/15
to java-ch...@googlegroups.com

You need a means of calculating the offset of each field. You can for example store the relative end of each array as an integer 16/32 bit. The start of the first array is the end of all the fixed data, the start of each array after it is the end of the previous one. E.g.
You have three arrays of 16 bytes, 24 bytes and 5 bytes. The types could be int or double etc.

16
40
45
16 x 0
24 x 0
5 x 0

To get the 3rd double of the second array.

public double getDoubleAt(int n) {
    short endOfFirst = bytes.readUnsignedShort(END_OF_FIRST);
    return bytes.readDouble(SIZE_OF_FIXED + endOfFirst + n * 8L);

--

Roman Leventov

unread,
Nov 17, 2015, 10:24:42 AM11/17/15
to java-ch...@googlegroups.com
This is a fundamential tradeoff -- fast access versus variable sized data. Flyweights from https://github.com/OpenHFT/Chronicle-Values take the first side -- e. g. they could have CharSequence fields, but with @MaxUtf8Length(N) annotation, i. e. all values in CharSequence fields of some value interface are limited in size. If the value is smaller, it wastes space until the limit.

Chronicle Map allows you to access raw off-heap value bytes -- what you do with them is entirely up to you. E. g.

try (c = map.queryContext(key)) {
    if ((e = c.entry()) != null) {
        RandomDataInput rawBytes = e.value().bytes();
        // access the raw bytes
    }
}



--

Peter Lawrey

unread,
Nov 17, 2015, 10:33:34 AM11/17/15
to java-ch...@googlegroups.com
Put another way. 
You have a portion of fixed length fields including the offsets of arrays.
You have fixed length fields which can be used to determine the offset of the variable length fields.  These can be accessed in a single lookup as these offset of these is known.
To get the start of the variable length fields, you first look up where that variable length field starts. Note: the first variable length starts at the end of the fixed fields so it doesn't need to be calculated and possibly not stored either. This is why you only need store the end of each field.

You may want to add validation in which case you can compare the offset of one array with the next to get the length or the maximum offset of the array.

Peter.
Reply all
Reply to author
Forward
0 new messages