All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.serializer.util.BinarySerializers Maven / Gradle / Ivy

Go to download

Extremely fast and space-efficient serializers. It was crafted using bytecode engineering.

There is a newer version: 3.1.0
Show newest version
/*
 * Copyright (C) 2015 SoftIndex LLC.
 *
 * 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 io.datakernel.serializer.util;

import io.datakernel.serializer.BinarySerializer;

import java.util.*;
import java.util.function.Supplier;

public final class BinarySerializers {

	public static final BinarySerializer BYTE_SERIALIZER = new BinarySerializer() {
		@Override
		public int encode(byte[] array, int pos, Byte item) {
			return BinaryOutputUtils.writeByte(array, pos, item);
		}

		@Override
		public Byte decode(byte[] array, int pos) {
			return array[pos];
		}

		@Override
		public void encode(BinaryOutput out, Byte item) throws ArrayIndexOutOfBoundsException {
			out.writeByte(item);
		}

		@Override
		public Byte decode(BinaryInput in) {
			return in.readByte();
		}
	};

	public static final BinarySerializer INT_SERIALIZER = new BinarySerializer() {
		@Override
		public int encode(byte[] array, int pos, Integer item) {
			array[pos] = (byte) (item >>> 24);
			array[pos + 1] = (byte) (item >>> 16);
			array[pos + 2] = (byte) (item >>> 8);
			array[pos + 3] = (byte) (int) item;
			return pos + 4;
		}

		@Override
		public Integer decode(byte[] array, int pos) {
			return ((array[pos] & 0xFF) << 24)
					| ((array[pos + 1] & 0xFF) << 16)
					| ((array[pos + 2] & 0xFF) << 8)
					| (array[pos + 3] & 0xFF);
		}

		@Override
		public void encode(BinaryOutput out, Integer item) throws ArrayIndexOutOfBoundsException {
			out.writeInt(item);
		}

		@Override
		public Integer decode(BinaryInput in) {
			return in.readInt();
		}
	};

	public static final BinarySerializer LONG_SERIALIZER = new BinarySerializer() {
		@Override
		public int encode(byte[] array, int pos, Long item) {
			int high = (int) (item >>> 32);
			int low = (int) (long) item;
			array[pos] = (byte) (high >>> 24);
			array[pos + 1] = (byte) (high >>> 16);
			array[pos + 2] = (byte) (high >>> 8);
			array[pos + 3] = (byte) high;
			array[pos + 4] = (byte) (low >>> 24);
			array[pos + 5] = (byte) (low >>> 16);
			array[pos + 6] = (byte) (low >>> 8);
			array[pos + 7] = (byte) low;
			return pos + 8;
		}

		@Override
		public Long decode(byte[] array, int pos) {
			return ((long) array[pos] << 56)
					| ((long) (array[pos + 1] & 0xFF) << 48)
					| ((long) (array[pos + 2] & 0xFF) << 40)
					| ((long) (array[pos + 3] & 0xFF) << 32)
					| ((long) (array[pos + 4] & 0xFF) << 24)
					| ((array[pos + 5] & 0xFF) << 16)
					| ((array[pos + 6] & 0xFF) << 8)
					| (array[pos + 7] & 0xFF);
		}

		@Override
		public void encode(BinaryOutput out, Long item) throws ArrayIndexOutOfBoundsException {
			out.writeLong(item);
		}

		@Override
		public Long decode(BinaryInput in) {
			return in.readLong();
		}
	};

	public static final BinarySerializer FLOAT_SERIALIZER = new BinarySerializer() {
		@Override
		public int encode(byte[] array, int pos, Float item) {
			int v = Float.floatToIntBits(item);
			array[pos] = (byte) (v >>> 24);
			array[pos + 1] = (byte) (v >>> 16);
			array[pos + 2] = (byte) (v >>> 8);
			array[pos + 3] = (byte) v;
			return pos + 4;
		}

		@Override
		public Float decode(byte[] array, int pos) {
			return Float.intBitsToFloat(((array[pos] & 0xFF) << 24)
					| ((array[pos + 1] & 0xFF) << 16)
					| ((array[pos + 2] & 0xFF) << 8)
					| (array[pos + 3] & 0xFF));
		}

		@Override
		public void encode(BinaryOutput out, Float item) throws ArrayIndexOutOfBoundsException {
			out.writeFloat(item);
		}

		@Override
		public Float decode(BinaryInput in) {
			return in.readFloat();
		}
	};

	public static final BinarySerializer DOUBLE_SERIALIZER = new BinarySerializer() {
		@Override
		public int encode(byte[] array, int pos, Double item) {
			return 0;
		}

		@Override
		public Double decode(byte[] array, int pos) {
			return null;
		}

		@Override
		public void encode(BinaryOutput out, Double item) throws ArrayIndexOutOfBoundsException {
			out.writeDouble(item);
		}

		@Override
		public Double decode(BinaryInput in) {
			return in.readDouble();
		}
	};

	public static final BinarySerializer UTF8_SERIALIZER = new BinarySerializer() {
		@Override
		public void encode(BinaryOutput out, String item) throws ArrayIndexOutOfBoundsException {
			out.writeUTF8(item);
		}

		@Override
		public String decode(BinaryInput in) {
			return in.readUTF8();
		}
	};

	public static final BinarySerializer ISO_88591_SERIALIZER = new BinarySerializer() {
		@Override
		public void encode(BinaryOutput out, String item) throws ArrayIndexOutOfBoundsException {
			out.writeIso88591(item);
		}

		@Override
		public String decode(BinaryInput in) {
			return in.readIso88591();
		}
	};

	public static final BinarySerializer UTF8_MB3_SERIALIZER = new BinarySerializer() {
		@Override
		public void encode(BinaryOutput out, String item) throws ArrayIndexOutOfBoundsException {
			out.writeUTF8mb3(item);
		}

		@Override
		public String decode(BinaryInput in) {
			return in.readUTF8mb3();
		}
	};

	public static final BinarySerializer BYTES_SERIALIZER = new BinarySerializer() {
		@Override
		public void encode(BinaryOutput out, byte[] item) throws ArrayIndexOutOfBoundsException {
			out.writeVarInt(item.length);
			out.write(item);
		}

		@Override
		public byte[] decode(BinaryInput in) {
			int size = in.readVarInt();
			byte[] bytes = new byte[size];
			in.read(bytes);
			return bytes;
		}
	};

	public static  BinarySerializer> ofOptional(BinarySerializer codec) {
		return new BinarySerializer>() {
			final BinarySerializer nullable = ofNullable(codec);

			@Override
			public void encode(BinaryOutput out, Optional item) {
				nullable.encode(out, item.orElse(null));
			}

			@Override
			public Optional decode(BinaryInput in) {
				return Optional.ofNullable(nullable.decode(in));
			}
		};
	}

	@SuppressWarnings("unchecked")
	public static  BinarySerializer ofNullable(BinarySerializer codec) {
		if (codec == UTF8_SERIALIZER) {
			return (BinarySerializer) new BinarySerializer() {
				@Override
				public void encode(BinaryOutput out, String item) {
					out.writeUTF8Nullable(item);
				}

				@Override
				public String decode(BinaryInput in) {
					return in.readUTF8Nullable();
				}
			};
		}
		if (codec == ISO_88591_SERIALIZER) {
			return (BinarySerializer) new BinarySerializer() {
				@Override
				public void encode(BinaryOutput out, String item) {
					out.writeIso88591Nullable(item);
				}

				@Override
				public String decode(BinaryInput in) {
					return in.readIso88591Nullable();
				}
			};
		}
		if (codec == UTF8_MB3_SERIALIZER) {
			return (BinarySerializer) new BinarySerializer() {
				@Override
				public void encode(BinaryOutput out, String item) {
					out.writeUTF8mb3Nullable(item);
				}

				@Override
				public String decode(BinaryInput in) {
					return in.readUTF8mb3Nullable();
				}
			};
		}
		return new BinarySerializer() {
			@Override
			public void encode(BinaryOutput out, T item) {
				if (item != null) {
					out.writeBoolean(true);
					codec.encode(out, item);
				} else {
					out.writeBoolean(false);
				}
			}

			@Override
			public T decode(BinaryInput in) {
				if (in.readBoolean()) {
					return codec.decode(in);
				} else {
					return null;
				}
			}
		};
	}

	private static > BinarySerializer ofCollection(BinarySerializer element, Supplier constructor) {
		return new BinarySerializer() {
			@Override
			public void encode(BinaryOutput out, C item) {
				out.writeVarInt(item.size());
				for (E v : item) {
					element.encode(out, v);
				}
			}

			@Override
			public C decode(BinaryInput in) {
				C collection = constructor.get();
				int size = in.readVarInt();
				for (int i = 0; i < size; i++) {
					collection.add(element.decode(in));
				}
				return collection;
			}
		};
	}

	public static  BinarySerializer> ofList(BinarySerializer element) {
		return ofCollection(element, ArrayList::new);
	}

	public static  BinarySerializer> ofSet(BinarySerializer element) {
		return ofCollection(element, LinkedHashSet::new);
	}

	public static  BinarySerializer> ofMap(BinarySerializer key, BinarySerializer value) {
		return new BinarySerializer>() {
			@Override
			public void encode(BinaryOutput out, Map item) {
				out.writeVarInt(item.size());
				for (Map.Entry entry : item.entrySet()) {
					key.encode(out, entry.getKey());
					value.encode(out, entry.getValue());
				}
			}

			@Override
			public Map decode(BinaryInput in) {
				Map map = new LinkedHashMap<>();
				int size = in.readVarInt();
				for (int i = 0; i < size; i++) {
					map.put(key.decode(in), value.decode(in));
				}
				return map;
			}
		};
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy