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

com.netflix.zeno.fastblob.FastBlobHeapFriendlyClientFrameworkSerializer Maven / Gradle / Ivy

The newest version!
/*
 *
 *  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 java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import com.netflix.zeno.fastblob.record.ByteDataBuffer;
import com.netflix.zeno.fastblob.record.FastBlobSerializationRecord;
import com.netflix.zeno.fastblob.record.VarInt;
import com.netflix.zeno.fastblob.record.schema.FastBlobSchema.FieldType;
import com.netflix.zeno.fastblob.state.FastBlobTypeDeserializationState;

/**
 * Rather than adding objects to a serialization state and having the ByteArrayOrdinalMap assign ordinals,
 * during a double snapshot refresh, we must determine the ordinal of an object based on its deserialization state's
 * == mapping. 

* * This class overrides the appropriate methods to inject this functionality. * * @author dkoszewnik * */ public class FastBlobHeapFriendlyClientFrameworkSerializer extends FastBlobFrameworkSerializer { private boolean checkSerializationIntegrity = false; private boolean serializationIntegrityFlawed = false; public FastBlobHeapFriendlyClientFrameworkSerializer(FastBlobStateEngine framework) { super(framework); } @Override protected void serializeObject(FastBlobSerializationRecord rec, int position, String fieldName, String typeName, Object obj) { if(obj == null) return; FieldType fieldType = rec.getSchema().getFieldType(position); if(fieldType != FieldType.OBJECT) throw new IllegalArgumentException("Attempting to serialize an Object as " + fieldType + " in field " + fieldName + ". Carefully check your schema for type " + rec.getSchema().getName() + "."); ByteDataBuffer fieldBuffer = rec.getFieldBuffer(position); FastBlobTypeDeserializationState deserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(typeName); int ordinal = findObject(deserializationState, obj, fieldName); VarInt.writeVInt(fieldBuffer, ordinal); } @Override public void serializeList(FastBlobSerializationRecord rec, String fieldName, String typeName, Collection collection) { if(collection == null) return; int position = rec.getSchema().getPosition(fieldName); FieldType fieldType = rec.getSchema().getFieldType(position); if(fieldType != FieldType.LIST && fieldType != FieldType.COLLECTION) throw new IllegalArgumentException("Attempting to serialize a List as " + fieldType + " in field " + fieldName); ByteDataBuffer fieldBuffer = rec.getFieldBuffer(position); FastBlobTypeDeserializationState deserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(typeName); for (T obj : collection) { if(obj == null) { VarInt.writeVNull(fieldBuffer); } else { int ordinal = findObject(deserializationState, obj, fieldName); VarInt.writeVInt(fieldBuffer, ordinal); } } } @Override public void serializeSet(FastBlobSerializationRecord rec, String fieldName, String typeName, Set set) { if(set == null) return; int position = rec.getSchema().getPosition(fieldName); FieldType fieldType = rec.getSchema().getFieldType(position); if(fieldType != FieldType.SET && fieldType != FieldType.COLLECTION) throw new IllegalArgumentException("Attempting to serialize a Set as " + fieldType + " in field " + fieldName); ByteDataBuffer fieldBuffer = rec.getFieldBuffer(position); FastBlobTypeDeserializationState deserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(typeName); int setOrdinals[] = new int[set.size()]; int i = 0; for (T obj : set) { setOrdinals[i++] = findObject(deserializationState, obj, fieldName); } Arrays.sort(setOrdinals); int currentOrdinal = 0; for (i = 0; i < setOrdinals.length; i++) { VarInt.writeVInt(fieldBuffer, setOrdinals[i] - currentOrdinal); currentOrdinal = setOrdinals[i]; } } @Override public void serializeMap(FastBlobSerializationRecord rec, String fieldName, String keyTypeName, String valueTypeName, Map map) { if(map == null) return; int position = rec.getSchema().getPosition(fieldName); FieldType fieldType = rec.getSchema().getFieldType(position); if(fieldType != FieldType.MAP) throw new IllegalArgumentException("Attempting to serialize a Map as " + fieldType + " in field " + fieldName); ByteDataBuffer fieldBuffer = rec.getFieldBuffer(position); FastBlobTypeDeserializationState keyDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(keyTypeName); FastBlobTypeDeserializationState valueDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(valueTypeName); long mapEntries[] = new long[map.size()]; int i = 0; for (Map.Entry entry : map.entrySet()) { int keyOrdinal = -1; int valueOrdinal = -1; if(entry.getKey() != null) keyOrdinal = findObject(keyDeserializationState, entry.getKey(), fieldName + "(key)"); if(entry.getValue() != null) valueOrdinal = findObject(valueDeserializationState, entry.getValue(), fieldName + "(value)"); mapEntries[i++] = ((long)valueOrdinal << 32) | (keyOrdinal & 0xFFFFFFFFL); } Arrays.sort(mapEntries); int currentValueOrdinal = 0; for (i = 0; i < mapEntries.length; i++) { int keyOrdinal = (int) mapEntries[i]; int valueOrdinal = (int) (mapEntries[i] >> 32); if(keyOrdinal == -1) VarInt.writeVNull(fieldBuffer); else VarInt.writeVInt(fieldBuffer, keyOrdinal); if(valueOrdinal == -1) { VarInt.writeVNull(fieldBuffer); } else { VarInt.writeVInt(fieldBuffer, valueOrdinal - currentValueOrdinal); } currentValueOrdinal = valueOrdinal; } } private int findObject(FastBlobTypeDeserializationState deserializationState, T obj, String fieldName) { int ordinal = deserializationState.find(obj); if(checkSerializationIntegrity && ordinal < 0) { serializationIntegrityFlawed = true; } return ordinal; } public void setCheckSerializationIntegrity(boolean warn) { this.checkSerializationIntegrity = warn; } public boolean isSerializationIntegrityFlawed() { return serializationIntegrityFlawed; } public void clearSerializationIntegrityFlawedFlag() { serializationIntegrityFlawed = false; } }