Map of small maps

37 views
Skip to first unread message

Clive Cox

unread,
Jun 21, 2015, 2:56:17 PM6/21/15
to java-ch...@googlegroups.com
Hi,

 My use case is to use ChronicleMap for Map<Long,Map<String,Float>> or Map<Long,Map<Integer,Float>> where each of the value maps is usually quite small, e.g. 1-10 entries.
 I was thinking maybe I could create a BytesMarshalable class with int size, and two arrays for the variable length sets of data. Is this the best way/sensible way to handle this use case efficiently?
 If so, I'm not sure how to tell ChronicleMap the entry set size for variable sized data. Or do I not need to?

 Clive

Roman Leventov

unread,
Jun 21, 2015, 6:30:22 PM6/21/15
to java-ch...@googlegroups.com
Yes, your are right.

You can use this marshaller:

public final class IntFloatMapMarshaller
implements BytesReader<Map<Integer, Float>>, BytesWriter<Map<Integer, Float>> {

public static final IntFloatMapMarshaller INSTANCE = new IntFloatMapMarshaller();

private IntFloatMapMarshaller() {}

@NotNull
@Override
public Map<Integer, Float> read(@NotNull Bytes bytes, long sizeInBytes) {
return read(bytes, sizeInBytes, null);
}

@NotNull
@Override
public Map<Integer, Float> read(@NotNull Bytes bytes, long sizeInBytes,
@Nullable Map<Integer, Float> toReuse) {
int mapSize = (int) (sizeInBytes / 8);
if (toReuse == null) {
// Might want to create a more efficient, specialized Map here, instead of HashMap

// * 4 / 3 because HashMap's default load factor is 0.75
// This is java.util.HashMap-specific, not needed for a different Map impl
int hashMapCapacity = mapSize * 4 / 3 + 1;
toReuse = new HashMap<>(hashMapCapacity);
} else {
toReuse.clear();
}
for (int i = 0; i < mapSize; i++) {
toReuse.put(bytes.readInt(), bytes.readFloat());
}
return toReuse;
}

@Override
public long size(@NotNull Map<Integer, Float> map) {
return map.size() * 8L;
}

@Override
public void write(@NotNull Bytes bytes, @NotNull Map<Integer, Float> map) {
map.forEach((k, v) -> {
bytes.writeInt(k);
bytes.writeFloat(v);
});
}
}

Then specify:

ChronicleMapBuilder.of(...)..
   .valueMarshallers(IntFloatMapMarshaller.INSTANCE,  IntFloatMapMarshaller.INSTANCE)
   .averageValueSize(MY_AVERAGE_MAP_SIZE * 8) /* multiplying by 8 designates one entry takes 8 bytes in memory */




--
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.

Reply all
Reply to author
Forward
0 new messages