
com.netflix.zeno.fastblob.FastBlobFrameworkDeserializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netflix-zeno Show documentation
Show all versions of netflix-zeno Show documentation
netflix-zeno developed by Netflix
/*
*
* Copyright 2013 Netflix, Inc.
*
* 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 com.netflix.zeno.fastblob;
import static com.netflix.zeno.fastblob.FastBlobFrameworkSerializer.NULL_DOUBLE_BITS;
import static com.netflix.zeno.fastblob.FastBlobFrameworkSerializer.NULL_FLOAT_BITS;
import com.netflix.zeno.fastblob.record.ByteData;
import com.netflix.zeno.fastblob.record.FastBlobDeserializationRecord;
import com.netflix.zeno.fastblob.record.VarInt;
import com.netflix.zeno.fastblob.state.FastBlobTypeDeserializationState;
import com.netflix.zeno.serializer.FrameworkDeserializer;
import com.netflix.zeno.serializer.NFTypeSerializer;
import com.netflix.zeno.util.collections.CollectionImplementation;
import com.netflix.zeno.util.collections.MinimizedUnmodifiableCollections;
import com.netflix.zeno.util.collections.builder.ListBuilder;
import com.netflix.zeno.util.collections.builder.MapBuilder;
import com.netflix.zeno.util.collections.builder.SetBuilder;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
/**
*
* Defines the operations necessary to decode each of the "Zeno native" elements from FastBlob record fields.
*
* @author dkoszewnik
*
*/
public class FastBlobFrameworkDeserializer extends FrameworkDeserializer {
private MinimizedUnmodifiableCollections minimizedCollections = new MinimizedUnmodifiableCollections(CollectionImplementation.JAVA_UTIL);
public FastBlobFrameworkDeserializer(FastBlobStateEngine framework) {
super(framework);
}
public void setCollectionImplementation(CollectionImplementation impl) {
minimizedCollections = new MinimizedUnmodifiableCollections(impl);
}
/**
* Read a boolean as a single byte. Might be null.
*/
@Override
public Boolean deserializeBoolean(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
return byteData.get(fieldPosition) == (byte) 1 ? Boolean.TRUE : Boolean.FALSE;
}
/**
* Read a boolean as a single byte.
*/
@Override
public boolean deserializePrimitiveBoolean(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
return byteData.get(fieldPosition) == (byte) 1;
}
/**
* Read an integer as a variable-byte sequence. After read, the value must be zig-zag decoded. Might be null.
*/
@Override
public Integer deserializeInteger(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int value = VarInt.readVInt(byteData, fieldPosition);
return Integer.valueOf((value >>> 1) ^ ((value << 31) >> 31));
}
/**
* Read an integer as a variable-byte sequence. After read, the value must be zig-zag decoded.
*/
@Override
public int deserializePrimitiveInt(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
int value = VarInt.readVInt(byteData, fieldPosition);
return (value >>> 1) ^ ((value << 31) >> 31);
}
/**
* Read a long as a variable-byte sequence. After read, the value must be zig-zag decoded. Might be null.
*/
@Override
public Long deserializeLong(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
long value = VarInt.readVLong(byteData, fieldPosition);
return Long.valueOf((value >>> 1) ^ ((value << 63) >> 63));
}
/**
* Read a long as a variable-byte sequence. After read, the value must be zig-zag decoded.
*/
@Override
public long deserializePrimitiveLong(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
long value = VarInt.readVLong(byteData, fieldPosition);
return (value >>> 1) ^ ((value << 63) >> 63);
}
/**
* Read a float as a fixed-length sequence of 4 bytes. Might be null.
*/
@Override
public Float deserializeFloat(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1)
return null;
int intBits = readIntBits(byteData, fieldPosition);
if(intBits == NULL_FLOAT_BITS)
return null;
return Float.valueOf(Float.intBitsToFloat(intBits));
}
/**
* Read a float as a fixed-length sequence of 4 bytes.
*/
@Override
public float deserializePrimitiveFloat(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
int intBits = readIntBits(byteData, fieldPosition);
return Float.intBitsToFloat(intBits);
}
private int readIntBits(ByteData byteData, int fieldPosition) {
int intBits = (byteData.get(fieldPosition++) & 0xFF) << 24;
intBits |= (byteData.get(fieldPosition++) & 0xFF) << 16;
intBits |= (byteData.get(fieldPosition++) & 0xFF) << 8;
intBits |= (byteData.get(fieldPosition) & 0xFF);
return intBits;
}
/**
* Read a double as a fixed-length sequence of 8 bytes. Might be null.
*/
@Override
public Double deserializeDouble(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1)
return null;
long longBits = readLongBits(byteData, fieldPosition);
if(longBits == NULL_DOUBLE_BITS)
return null;
return Double.valueOf(Double.longBitsToDouble(longBits));
}
/**
* Read a double as a fixed-length sequence of 8 bytes.
*/
@Override
public double deserializePrimitiveDouble(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
long longBits = readLongBits(byteData, fieldPosition);
return Double.longBitsToDouble(longBits);
}
private long readLongBits(ByteData byteData, int fieldPosition) {
long longBits = (long) (byteData.get(fieldPosition++) & 0xFF) << 56;
longBits |= (long) (byteData.get(fieldPosition++) & 0xFF) << 48;
longBits |= (long) (byteData.get(fieldPosition++) & 0xFF) << 40;
longBits |= (long) (byteData.get(fieldPosition++) & 0xFF) << 32;
longBits |= (long) (byteData.get(fieldPosition++) & 0xFF) << 24;
longBits |= (byteData.get(fieldPosition++) & 0xFF) << 16;
longBits |= (byteData.get(fieldPosition++) & 0xFF) << 8;
longBits |= (byteData.get(fieldPosition) & 0xFF);
return longBits;
}
/**
* Read a String as UTF-8 encoded characters. The length is encoded as a variable-byte integer.
*/
@Override
public String deserializeString(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
return readString(byteData, fieldPosition, length);
}
/**
* Read a sequence of bytes directly from the stream. The length is encoded as a variable-byte integer.
*/
@Override
public byte[] deserializeBytes(FastBlobDeserializationRecord rec, String fieldName) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
byte data[] = new byte[length];
for(int i=0;i T deserializeObject(FastBlobDeserializationRecord rec, String fieldName, String typeName, Class clazz) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int ordinal = VarInt.readVInt(byteData, fieldPosition);
FastBlobTypeDeserializationState deserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(typeName);
return deserializationState.get(ordinal);
}
/**
* Read a List as a sequence of ordinals encoded as variable-byte integers. Use the framework to look up each Object by it's ordinals.
*/
@Override
public List deserializeList(FastBlobDeserializationRecord rec, String fieldName, NFTypeSerializer itemSerializer) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
int numElements = VarInt.countVarIntsInRange(byteData, fieldPosition, length);
if(numElements == 0)
return Collections.emptyList();
ListBuilder list = minimizedCollections.createListBuilder();
list.builderInit(numElements);
FastBlobTypeDeserializationState elementDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(itemSerializer.getName());
for(int i=0;i Set deserializeSet(FastBlobDeserializationRecord rec, String fieldName, NFTypeSerializer itemSerializer) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
int numElements = VarInt.countVarIntsInRange(byteData, fieldPosition, length);
if(numElements == 0)
return Collections.emptySet();
SetBuilder set = minimizedCollections.createSetBuilder();
set.builderInit(numElements);
FastBlobTypeDeserializationState elementDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(itemSerializer.getName());
int previousOrdinal = 0;
for(int i=0;i Map deserializeMap(FastBlobDeserializationRecord rec, String fieldName, NFTypeSerializer keySerializer, NFTypeSerializer valueSerializer) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if (fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
int numElements = VarInt.countVarIntsInRange(byteData, fieldPosition, length);
numElements /= 2;
if(numElements == 0)
return Collections.emptyMap();
MapBuilder map = minimizedCollections.createMapBuilder();
map.builderInit(numElements);
FastBlobTypeDeserializationState keyDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(keySerializer.getName());
FastBlobTypeDeserializationState valueDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(valueSerializer.getName());
populateMap(byteData, fieldPosition, numElements, map, keyDeserializationState, valueDeserializationState);
return minimizedCollections.minimizeMap(map.builderFinish());
}
/**
* Read a SortedMap as a sequence of key/value pairs encoded as variable-byte integers (value are gap-encoded). Use the framework to look up each Object by it's ordinals.
*/
@Override
public SortedMap deserializeSortedMap(FastBlobDeserializationRecord rec, String fieldName, NFTypeSerializer keySerializer, NFTypeSerializer valueSerializer) {
ByteData byteData = rec.getByteData();
int fieldPosition = rec.getPosition(fieldName);
if(fieldPosition == -1 || VarInt.readVNull(byteData, fieldPosition))
return null;
int length = VarInt.readVInt(byteData, fieldPosition);
fieldPosition += VarInt.sizeOfVInt(length);
int numElements = VarInt.countVarIntsInRange(byteData, fieldPosition, length);
numElements /= 2;
if(numElements == 0)
return minimizedCollections.emptySortedMap();
MapBuilder map = minimizedCollections.createSortedMapBuilder();
map.builderInit(numElements);
FastBlobTypeDeserializationState keyDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(keySerializer.getName());
FastBlobTypeDeserializationState valueDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(valueSerializer.getName());
populateMap(byteData, fieldPosition, numElements, map, keyDeserializationState, valueDeserializationState);
return minimizedCollections.minimizeSortedMap( (SortedMap) map.builderFinish() );
}
private void populateMap(ByteData byteData, int fieldPosition, int numElements, MapBuilder mapToPopulate, FastBlobTypeDeserializationState keyState, FastBlobTypeDeserializationState valueState) {
int previousValueOrdinal = 0;
for(int i=0;i
*
* @param str
* @param out
* @return
* @throws IOException
*/
private char chararr[] = new char[100];
protected String readString(ByteData data, int position, int length) {
int endPosition = position + length;
if(length > chararr.length)
chararr = new char[length];
int count = 0;
while(position < endPosition) {
int c = VarInt.readVInt(data, position);
chararr[count++] = (char)c;
position += VarInt.sizeOfVInt(c);
}
// The number of chars may be fewer than the number of bytes in the serialized data
return new String(chararr, 0, count);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy