
org.mapdb20.Serializer Maven / Gradle / Ivy
/*
* Copyright (c) 2012 Jan Kotek
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapdb20;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.UUID;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/**
* Provides serialization and deserialization
*
* @author Jan Kotek
*/
public abstract class Serializer {
public static final Serializer CHAR = new Serializer() {
@Override
public void serialize(DataOutput out, Character value) throws IOException {
out.writeChar(value.charValue());
}
@Override
public Character deserialize(DataInput in, int available) throws IOException {
return in.readChar();
}
@Override
public int fixedSize() {
return 2;
}
@Override
public boolean isTrusted() {
return true;
}
};
/**
*
* Serializes strings using UTF8 encoding.
* Stores string size so can be used as collection serializer.
* Does not handle null values
*
* Unlike {@link Serializer#STRING} this method hashes String with more reliable XXHash.
*
*/
public static final Serializer STRING_XXHASH = new StringValueSerializer (){
@Override
public void serialize(DataOutput out, String value) throws IOException {
out.writeUTF(value);
}
@Override
public String deserialize(DataInput in, int available) throws IOException {
return in.readUTF();
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.STRING;
}
@Override
public int hashCode(String s, int seed) {
char[] c = s.toCharArray();
return CHAR_ARRAY.hashCode(c, seed);
}
};
/**
* Serializes strings using UTF8 encoding.
* Stores string size so can be used as collection serializer.
* Does not handle null values
*/
public static final Serializer STRING = new StringValueSerializer (){
@Override
public void serialize(DataOutput out, String value) throws IOException {
out.writeUTF(value);
}
@Override
public String deserialize(DataInput in, int available) throws IOException {
return in.readUTF();
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.STRING;
}
};
private static abstract class StringValueSerializer extends Serializer{
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
DataIO.DataOutputByteArray out2 = (DataIO.DataOutputByteArray) out;
char[][] vals2 = (char[][]) vals;
for(char[] v:vals2){
out2.packInt(v.length);
for(char c:v){
out2.packInt(c);
}
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
DataIO.DataInputInternal in2 = (DataIO.DataInputInternal) in;
char[][] ret = new char[size][];
for(int i=0;i STRING_INTERN = new Serializer() {
@Override
public void serialize(DataOutput out, String value) throws IOException {
out.writeUTF(value);
}
@Override
public String deserialize(DataInput in, int available) throws IOException {
return in.readUTF().intern();
}
@Override
public boolean isTrusted() {
return true;
}
};
/**
* Serializes strings using ASCII encoding (8 bit character).
* Is faster compared to UTF8 encoding.
* Stores string size so can be used as collection serializer.
* Does not handle null values
*/
public static final Serializer STRING_ASCII = new Serializer() {
@Override
public void serialize(DataOutput out, String value) throws IOException {
int size = value.length();
DataIO.packInt(out, size);
for (int i = 0; i < size; i++) {
out.write(value.charAt(i));
}
}
@Override
public String deserialize(DataInput in, int available) throws IOException {
int size = DataIO.unpackInt(in);
StringBuilder result = new StringBuilder(size);
for (int i = 0; i < size; i++) {
result.append((char)in.readUnsignedByte());
}
return result.toString();
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.STRING; //TODO ascii specific serializer?
}
};
/**
* Serializes strings using UTF8 encoding.
* Used mainly for testing.
* Does not handle null values.
*/
public static final Serializer STRING_NOSIZE = new StringValueSerializer (){
private final Charset UTF8_CHARSET = Charset.forName("UTF8");
@Override
public void serialize(DataOutput out, String value) throws IOException {
final byte[] bytes = value.getBytes(UTF8_CHARSET);
out.write(bytes);
}
@Override
public String deserialize(DataInput in, int available) throws IOException {
if(available==-1) throw new IllegalArgumentException("STRING_NOSIZE does not work with collections.");
byte[] bytes = new byte[available];
in.readFully(bytes);
return new String(bytes, UTF8_CHARSET);
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.STRING;
}
};
abstract protected static class EightByteSerializer extends Serializer{
protected abstract E unpack(long l);
protected abstract long pack(E l);
@Override
public E valueArrayGet(Object vals, int pos){
return unpack(((long[]) vals)[pos]);
}
@Override
public int valueArraySize(Object vals){
return ((long[])vals).length;
}
@Override
public Object valueArrayEmpty(){
return new long[0];
}
@Override
public Object valueArrayPut(Object vals, int pos, E newValue) {
long[] array = (long[]) vals;
final long[] ret = Arrays.copyOf(array, array.length+1);
if(pos {
@Override
protected Long unpack(long l) {
return new Long(l);
}
@Override
protected long pack(Long l) {
return l.longValue();
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.LONG;
}
}
/** Serializes Long into 8 bytes, used mainly for testing.
* Does not handle null values.*/
public static final Serializer LONG = new LongSerializer() {
@Override
public void serialize(DataOutput out, Long value) throws IOException {
out.writeLong(value);
}
@Override
public Long deserialize(DataInput in, int available) throws IOException {
return in.readLong();
}
};
/**
* Packs positive LONG, so smaller positive values occupy less than 8 bytes.
* Large and negative values could occupy 8 or 9 bytes.
*/
public static final Serializer LONG_PACKED = new LongSerializer(){
@Override
public void serialize(DataOutput out, Long value) throws IOException {
((DataIO.DataOutputByteArray) out).packLong(value);
}
@Override
public Long deserialize(DataInput in, int available) throws IOException {
return ((DataIO.DataInputInternal)in).unpackLong();
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
DataIO.DataOutputByteArray out2 = (DataIO.DataOutputByteArray) out;
for(long o:(long[]) vals){
out2.packLong(o);
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
DataIO.DataInputInternal i = (DataIO.DataInputInternal) in;
long[] ret = new long[size];
i.unpackLongArray(ret,0,size);
return ret;
}
@Override
public int fixedSize() {
return -1;
}
};
/** packs Long so small values occupy less than 8 bytes. Large (positive and negative)
* values could occupy more 8 to 9 bytes. It uses zigzag conversion before packing,
* number is multiplied by two, with last bite indicating negativity.
*/
public static final Serializer LONG_PACKED_ZIGZAG = new LongSerializer(){
long wrap(long i){
long plus = i<0?1:0; //this could be improved by eliminating condition
return Math.abs(i*2)+plus;
}
long unwrap(long i){
long m = 1 - 2 * (i&1); // +1 if even, -1 if odd
return (i>>>1) * m;
}
@Override
public void serialize(DataOutput out, Long value) throws IOException {
((DataIO.DataOutputByteArray) out).packLong(wrap(value));
}
@Override
public Long deserialize(DataInput in, int available) throws IOException {
return unwrap(((DataIO.DataInputInternal) in).unpackLong());
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
DataIO.DataOutputByteArray out2 = (DataIO.DataOutputByteArray) out;
for(long o:(long[]) vals){
out2.packLong(wrap(o));
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
DataIO.DataInputInternal i = (DataIO.DataInputInternal) in;
long[] ret = new long[size];
i.unpackLongArray(ret,0,size);
for(int a=0;a extends Serializer{
protected abstract E unpack(int l);
protected abstract int pack(E l);
@Override
public boolean isTrusted() {
return true;
}
@Override
public int fixedSize() {
return 4;
}
@Override
public E valueArrayGet(Object vals, int pos){
return unpack(((int[])vals)[pos]);
}
@Override
public int valueArraySize(Object vals){
return ((int[])vals).length;
}
@Override
public Object valueArrayEmpty(){
return new int[0];
}
@Override
public Object valueArrayPut(Object vals, int pos, E newValue) {
int[] array = (int[]) vals;
final int[] ret = Arrays.copyOf(array, array.length+1);
if(pos {
@Override
protected Integer unpack(int l) {
return l;
}
@Override
protected int pack(Integer l) {
return l;
}
@Override
public BTreeKeySerializer getBTreeKeySerializer(Comparator comparator) {
if(comparator!=null && comparator!=Fun.COMPARATOR) {
return super.getBTreeKeySerializer(comparator);
}
return BTreeKeySerializer.INTEGER;
}
}
/** Serializes Integer into 4 bytes, used mainly for testing.
* Does not handle null values.*/
public static final Serializer INTEGER = new IntegerSerializer() {
@Override
public void serialize(DataOutput out, Integer value) throws IOException {
out.writeInt(value);
}
@Override
public Integer deserialize(DataInput in, int available) throws IOException {
return in.readInt();
}
};
/**
* Packs positive Integer, so smaller positive values occupy less than 4 bytes.
* Large and negative values could occupy 4 or 5 bytes.
*/
public static final Serializer INTEGER_PACKED = new IntegerSerializer(){
@Override
public void serialize(DataOutput out, Integer value) throws IOException {
((DataIO.DataOutputByteArray) out).packInt(value);
}
@Override
public Integer deserialize(DataInput in, int available) throws IOException {
return ((DataIO.DataInputInternal)in).unpackInt();
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
DataIO.DataOutputByteArray out2 = (DataIO.DataOutputByteArray) out;
for(int o:(int[]) vals){
out2.packIntBigger(o);
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
DataIO.DataInputInternal i = (DataIO.DataInputInternal) in;
int[] ret = new int[size];
i.unpackIntArray(ret, 0, size);
return ret;
}
@Override
public int fixedSize() {
return -1;
}
};
/** packs Integer so small values occupy less than 4 bytes. Large (positive and negative)
* values could occupy more 4 to 5 bytes. It uses zigzag conversion before packing,
* number is multiplied by two, with last bite indicating negativity.
*/
public static final Serializer INTEGER_PACKED_ZIGZAG = new IntegerSerializer(){
long wrap(int i){
long plus = i<0?1:0; //this could be improved by eliminating condition
return Math.abs(i*2)+plus;
}
int unwrap(long i){
long m = 1 - 2 * (i&1); // +1 if even, -1 if odd
return (int) ((i>>>1) * m);
}
@Override
public void serialize(DataOutput out, Integer value) throws IOException {
((DataIO.DataOutputByteArray) out).packLong(wrap(value));
}
@Override
public Integer deserialize(DataInput in, int available) throws IOException {
return unwrap(((DataIO.DataInputInternal)in).unpackLong());
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
DataIO.DataOutputByteArray out2 = (DataIO.DataOutputByteArray) out;
for(int o:(int[]) vals){
out2.packLong(wrap(o));
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
DataIO.DataInputInternal i = (DataIO.DataInputInternal) in;
int[] ret = new int[size];
for(int a=0;a BOOLEAN = new BooleanSer();
protected static class BooleanSer extends Serializer {
@Override
public void serialize(DataOutput out, Boolean value) throws IOException {
out.writeBoolean(value);
}
@Override
public Boolean deserialize(DataInput in, int available) throws IOException {
return in.readBoolean();
}
@Override
public int fixedSize() {
return 1;
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
for(boolean b:((boolean[])vals)){
out.writeBoolean(b);
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
boolean[] ret = new boolean[size];
for(int i=0;i RECID = new EightByteSerializer() {
@Override
public void serialize(DataOutput out, Long value) throws IOException {
DataIO.packRecid(out, value);
}
@Override
public Long deserialize(DataInput in, int available) throws IOException {
return DataIO.unpackRecid(in);
}
@Override
public int fixedSize() {
return -1;
}
@Override
protected Long unpack(long l) {
return l;
}
@Override
protected long pack(Long l) {
return l;
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public void valueArraySerialize(DataOutput out, Object vals) throws IOException {
for(long o:(long[]) vals){
DataIO.packRecid(out,o);
}
}
@Override
public Object valueArrayDeserialize(DataInput in, int size) throws IOException {
long[] ret = new long[size];
for(int i=0;i RECID_ARRAY = new Serializer() {
@Override
public void serialize(DataOutput out, long[] value) throws IOException {
DataIO.packInt(out,value.length);
for(long recid:value){
DataIO.packRecid(out,recid);
}
}
@Override
public long[] deserialize(DataInput in, int available) throws IOException {
int size = DataIO.unpackInt(in);
long[] ret = new long[size];
for(int i=0;i ILLEGAL_ACCESS = new Serializer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy