Package com.netflix.zeno.fastblob

Source Code of com.netflix.zeno.fastblob.FastBlobHeapFriendlyClientFrameworkSerializer

/*
*
*  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. <p/>
*
* 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<Object> deserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(typeName);

        int ordinal = findObject(deserializationState, obj, fieldName);

        VarInt.writeVInt(fieldBuffer, ordinal);
    }

    @Override
    public <T> void serializeList(FastBlobSerializationRecord rec, String fieldName, String typeName, Collection<T> 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<Object> 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 <T> void serializeSet(FastBlobSerializationRecord rec, String fieldName, String typeName, Set<T> 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<Object> 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 <K, V> void serializeMap(FastBlobSerializationRecord rec, String fieldName, String keyTypeName, String valueTypeName, Map<K, V> 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<Object> keyDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(keyTypeName);
        FastBlobTypeDeserializationState<Object> valueDeserializationState = ((FastBlobStateEngine) framework).getTypeDeserializationState(valueTypeName);

        long mapEntries[] = new long[map.size()];

        int i = 0;
        for (Map.Entry<K, V> 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 <T> int findObject(FastBlobTypeDeserializationState<Object> 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;
    }

}
TOP

Related Classes of com.netflix.zeno.fastblob.FastBlobHeapFriendlyClientFrameworkSerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.