package org.mapdb.serializer;
import org.jetbrains.annotations.NotNull;
import static org.mapdb.serializer.SerializerStringDelta2.ByteArrayKeys;
import org.mapdb.DataIO;
import org.mapdb.DataInput2;
import org.mapdb.DataOutput2;
import org.mapdb.Serializer;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
/**
* Created by jan on 2/29/16.
*/
public class SerializerByteArrayDelta2 implements GroupSerializer<byte[]> {
@Override
public int valueArraySearch(Object keys, byte[] key) {
Object[] v = valueArrayToArray(keys);
return Arrays.binarySearch(v, key, (Comparator)this);
}
@Override
public int valueArraySearch(Object keys, byte[] key, Comparator comparator) {
Object[] v = valueArrayToArray(keys);
return Arrays.binarySearch(v, key, comparator);
}
@Override
public void valueArraySerialize(DataOutput2 out, Object keys2) throws IOException {
ByteArrayKeys keys = (ByteArrayKeys) keys2;
int offset = 0;
//write sizes
for(int o:keys.offset){
out.packInt(o-offset);
offset = o;
}
//$DELAY$
//find and write common prefix
int prefixLen = keys.commonPrefixLen();
out.packInt(prefixLen);
out.write(keys.array,0,prefixLen);
//$DELAY$
//write suffixes
offset = prefixLen;
for(int o:keys.offset){
out.write(keys.array, offset, o-offset);
offset = o+prefixLen;
}
}
@Override
public ByteArrayKeys valueArrayDeserialize(DataInput2 in, int size) throws IOException {
//read data sizes
int[] offsets = new int[size];
int old=0;
for(int i=0;i<size;i++){
old+= in.unpackInt();
offsets[i]=old;
}
byte[] bb = new byte[old];
//$DELAY$
//read and distribute common prefix
int prefixLen = in.unpackInt();
in.readFully(bb, 0, prefixLen);
for(int i=0; i<offsets.length-1;i++){
System.arraycopy(bb, 0, bb, offsets[i], prefixLen);
}
//$DELAY$
//read suffixes
int offset = prefixLen;
for(int o:offsets){
in.readFully(bb,offset,o-offset);
offset = o+prefixLen;
}
return new ByteArrayKeys(offsets,bb);
}
@Override
public byte[] valueArrayGet(Object keys, int pos) {
return ((ByteArrayKeys)keys).getKey(pos);
}
@Override
public int valueArraySize(Object keys) {
return ((ByteArrayKeys)keys).length();
}
@Override
public ByteArrayKeys valueArrayEmpty() {
return new ByteArrayKeys(new int[0], new byte[0]);
}
@Override
public ByteArrayKeys valueArrayPut(Object keys, int pos, byte[] newValue) {
return ((ByteArrayKeys)keys).putKey(pos, newValue);
}
@Override
public ByteArrayKeys valueArrayUpdateVal(Object vals, int pos, byte[] newValue) {
// TODO PERF use specialized method, make this faster
Object[] v = valueArrayToArray(vals);
v[pos] = newValue;
return valueArrayFromArray(v);
}
@Override
public ByteArrayKeys valueArrayFromArray(Object[] keys) {
//fill offsets
int[] offsets = new int[keys.length];
int old=0;
for(int i=0;i<keys.length;i++){
byte[] b = (byte[]) keys[i];
old+=b.length;
offsets[i]=old;
}
//$DELAY$
//fill large array
byte[] bb = new byte[old];
old=0;
for(int i=0;i<keys.length;i++){
int curr = offsets[i];
System.arraycopy(keys[i], 0, bb, old, curr - old);
old=curr;
}
//$DELAY$
return new ByteArrayKeys(offsets,bb);
}
@Override
public ByteArrayKeys valueArrayCopyOfRange(Object keys, int from, int to) {
return ((ByteArrayKeys)keys).copyOfRange(from,to);
}
@Override
public ByteArrayKeys valueArrayDeleteValue(Object keys, int pos) {
//return keys.deleteKey(pos);
Object[] vv = valueArrayToArray(keys);
vv = DataIO.arrayDelete(vv, pos, 1);
return valueArrayFromArray(vv);
}
@Override
public void serialize(@NotNull DataOutput2 out, @NotNull byte[] value) throws IOException {
Serializer.BYTE_ARRAY.serialize(out, value);
}
@Override
public byte[] deserialize(@NotNull DataInput2 input, int available) throws IOException {
return Serializer.BYTE_ARRAY.deserialize(input, available);
}
@Override
public int compare(byte[] o1, byte[] o2) {
return Serializer.BYTE_ARRAY.compare(o1, o2);
}
@Override
public boolean equals(byte[] a1, byte[] a2) {
return Serializer.BYTE_ARRAY.equals(a1, a2);
}
@Override
public int hashCode(@NotNull byte[] bytes, int seed) {
return Serializer.BYTE_ARRAY.hashCode(bytes, seed);
}
@Override
public boolean isTrusted() {
return true;
}
}