Hello ChronicleMap Users,
I am trying to use ChronicleMap with custom Key and Value. The Key is composed of various inputs and Value is the result of a database lookup. I would like to store this in memory to speed up subsequent requests. However, I am struggling to decide on what should be the approach for Key & Value serializers. Here are my Key and Value with the base Key being CacheKey and an implementation being NetKey; I have few different keys to be used. I have tried few options but can't seem to seiralize/deserialize my key/value.
public interface CacheKey extends Serializable {
byte[] getKey();
void setKey(Object object);
}
public interface CacheValue extends Serializable {
byte[] getValue();
void setValue(Object object);
}
@Builder
public class NetKey implements CacheKey {
private String name;
private String productType;
private String dealDate;
@Override
public byte[] getKey() {
return Util.writeToByte(this);
}
@Override
public void setKey(Object object) {
if (object instanceof NetKey) {
NetKey o = (NetKey) object;
this.name = o.name;
this.productType = o.productType;
this.dealDate = o.dealDate;
}
}
//... override equals and hashCode
}
@Builder
public class NetValue implements CacheValue {
private String entity;
private String group;
private Service service;
@Override
public byte[] getValue() {
return Util.writeToByte(this);
}
@Override
public void setValue(Object object) {
if (object instanceof NetValue) {
NetValue o = (NetValue) object;
this.entity = o.entity;
this.group = o.group;
this.service = o.service;
}
}
// override equals and hashCode
}
public class MyKeySerializer implements BytesReader<CacheKey>, BytesWriter<CacheKey> {
private static MyKeySerializer INSTANCE = new MyKeySerializer();
public static MyKeySerializer getInstance() { return INSTANCE; }
private MyKeySerializer() {}
@NotNull
@Override
public CacheKey read(Bytes in, @Nullable CacheKey using) {
if (using == null) {
using = new CacheKey() {
@Override
public CacheKey getKey() {
return this;
}
@Override
public void setKey(CacheKey object) {
}
};
}
int len = in.readInt();
Object object = Util.readFromByte(in.toByteArray());
using.setKey(object == null ? null : (CacheKey) object);
return using;
}
@Override
public void write(Bytes out, @NotNull CacheKey toWrite) {
byte[] content = Util.writeToByte(toWrite.getKey());
out.writeInt(content.length);
out.write(content);
}
}
public class MyValueSerializer implements BytesReader<CacheValue>, BytesWriter<CacheValue> {
private static MyValueSerializer INSTANCE = new MyValueSerializer();
public static MyValueSerializer getInstance() { return INSTANCE; }
private MyValueSerializer() {}
@NotNull
@Override
public CacheValue read(Bytes in, @Nullable CacheValue using) {
// TODO need help to implement this method
}
@Override
public void write(Bytes out, @NotNull CacheValue toWrite) {
// TODO need help to implement this method
}
}
public class Test {
public static void main(String[] args) {
NetKey netKey = ...;
NetValue netValue = ...;
ChronicleMap<CacheKey, CacheValue> inMemoryMap = ChronicleMap.of(CacheKey.class, CacheKey.class)
.name("sample-map")
.entries(50)
.averageKey(netKey)
.averageValue(netValue)
.keyMarshallers(MyKeySerializer.class)
.valueMarshallers(MyValueSerializer.class)
.create();
inMemoryMap.put(netKey, netValue);
}
}
Update 1
Error I am seeing is StackOverflow
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.lang.RuntimeException.<init>(RuntimeException.java:52)
at java.base/java.lang.IllegalArgumentException.<init>(IllegalArgumentException.java:40)
at java.base/java.util.regex.PatternSyntaxException.<init>(PatternSyntaxException.java:58)
at java.base/java.util.regex.Pattern.error(Pattern.java:2028)
at java.base/java.util.regex.Pattern.<init>(Pattern.java:1432)
at java.base/java.util.regex.Pattern.compile(Pattern.java:1069)
at java.base/java.util.regex.Pattern.matches(Pattern.java:1174)
at java.base/java.lang.String.matches(String.java:2839)
at net.openhft.chronicle.values.CodeTemplate.lambda$null$20(CodeTemplate.java:206)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.TreeMap$KeySpliterator.tryAdvance(TreeMap.java:3088)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
at net.openhft.chronicle.values.CodeTemplate.lambda$methodsAndTemplatesByField$21(CodeTemplate.java:207)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at net.openhft.chronicle.values.CodeTemplate.methodsAndTemplatesByField(CodeTemplate.java:214)
at net.openhft.chronicle.values.CodeTemplate.createValueModel(CodeTemplate.java:104)
at net.openhft.chronicle.values.ValueModel$1.computeValue(ValueModel.java:46)
at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:228)
at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:210)
I was able to solve this by changing my key & value to Class and using custom serializers.