package org.infinispan.server.hotrod; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Collections; import java.util.Set; import org.infinispan.commons.io.UnsignedNumeric; import org.infinispan.commons.marshall.AbstractExternalizer; import org.infinispan.container.versioning.NumericVersion; import org.infinispan.metadata.Metadata; import org.infinispan.notifications.cachelistener.filter.CacheEventConverter; import org.infinispan.notifications.cachelistener.filter.EventType; class KeyValueVersionConverter implements CacheEventConverter<byte[], byte[], byte[]> { private KeyValueVersionConverter() { } public static KeyValueVersionConverter SINGLETON = new KeyValueVersionConverter(); @Override public byte[] convert(byte[] key, byte[] oldValue, Metadata oldMetadata, byte[] newValue, Metadata newMetadata, EventType eventType) { int capacity = UnsignedNumeric.sizeUnsignedInt(key.length) + key.length + (newValue != null ? UnsignedNumeric.sizeUnsignedInt(newValue.length) + newValue.length + 8 : 0); byte[] out = new byte[capacity]; int offset = UnsignedNumeric.writeUnsignedInt(out, 0, key.length); offset += putBytes(key, offset, out); if (newValue != null) { offset += UnsignedNumeric.writeUnsignedInt(out, offset, newValue.length); offset += putBytes(newValue, offset, out); putLong(((NumericVersion) newMetadata.version()).getVersion(), offset, out); } return out; } private int putBytes(byte[] bytes, int offset, byte[] out) { int localOffset = offset; for (byte b : bytes) { out[localOffset] = b; localOffset += 1; } return localOffset - offset; } private int putLong(long l, int offset, byte[] out) { out[offset] = (byte) (l >> 56); out[offset + 1] = (byte) (l >> 48); out[offset + 2] = (byte) (l >> 40); out[offset + 3] = (byte) (l >> 32); out[offset + 4] = (byte) (l >> 24); out[offset + 5] = (byte) (l >> 16); out[offset + 6] = (byte) (l >> 8); out[offset + 7] = (byte) l; return offset + 8; } static class Externalizer extends AbstractExternalizer<KeyValueVersionConverter> { @Override public Set<Class<? extends KeyValueVersionConverter>> getTypeClasses() { return Collections.singleton(KeyValueVersionConverter.class); } @Override public void writeObject(ObjectOutput output, KeyValueVersionConverter object) throws IOException { } @Override public KeyValueVersionConverter readObject(ObjectInput input) throws IOException, ClassNotFoundException { return KeyValueVersionConverter.SINGLETON; } } }