Package com.hazelcast.nio.serialization

Source Code of com.hazelcast.nio.serialization.SerializationServiceImpl$ThreadLocalOutputCache

/*
* Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
*
* 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.hazelcast.nio.serialization;

import com.hazelcast.core.HazelcastInstanceNotActiveException;
import com.hazelcast.core.ManagedContext;
import com.hazelcast.core.PartitioningStrategy;
import com.hazelcast.instance.OutOfMemoryErrorDispatcher;
import com.hazelcast.nio.BufferObjectDataInput;
import com.hazelcast.nio.BufferObjectDataOutput;
import com.hazelcast.nio.DynamicByteBuffer;
import com.hazelcast.nio.IOUtil;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.ConstantSerializers.BooleanSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.ByteSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.CharArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.CharSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.DoubleArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.DoubleSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.FloatArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.FloatSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.IntegerArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.IntegerSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.LongArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.LongSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.ShortArraySerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.ShortSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.StringSerializer;
import com.hazelcast.nio.serialization.ConstantSerializers.TheByteArraySerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.BigDecimalSerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.BigIntegerSerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.ClassSerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.DateSerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.EnumSerializer;
import com.hazelcast.nio.serialization.DefaultSerializers.Externalizer;
import com.hazelcast.nio.serialization.DefaultSerializers.ObjectSerializer;
import com.hazelcast.util.ConcurrentReferenceHashMap;

import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReference;

public class SerializationServiceImpl implements SerializationService {

    protected static final PartitioningStrategy EMPTY_PARTITIONING_STRATEGY = new PartitioningStrategy() {
        public Object getPartitionKey(Object key) {
            return null;
        }
    };

    private static final int CONSTANT_SERIALIZERS_SIZE = SerializationConstants.CONSTANT_SERIALIZERS_LENGTH;

    protected final ManagedContext managedContext;
    protected final PortableContext portableContext;
    protected final InputOutputFactory inputOutputFactory;
    protected final PartitioningStrategy globalPartitioningStrategy;

    private final IdentityHashMap<Class, SerializerAdapter> constantTypesMap
            = new IdentityHashMap<Class, SerializerAdapter>(CONSTANT_SERIALIZERS_SIZE);
    private final SerializerAdapter[] constantTypeIds = new SerializerAdapter[CONSTANT_SERIALIZERS_SIZE];

    private final ConcurrentMap<Class, SerializerAdapter> typeMap = new ConcurrentHashMap<Class, SerializerAdapter>();
    private final ConcurrentMap<Integer, SerializerAdapter> idMap = new ConcurrentHashMap<Integer, SerializerAdapter>();
    private final AtomicReference<SerializerAdapter> global = new AtomicReference<SerializerAdapter>();
    private final ThreadLocalOutputCache dataOutputQueue;
    private final PortableSerializer portableSerializer;
    private final SerializerAdapter dataSerializerAdapter;
    private final SerializerAdapter portableSerializerAdapter;
    private final ClassLoader classLoader;
    private final int outputBufferSize;

    private volatile boolean active = true;

    SerializationServiceImpl(InputOutputFactory inputOutputFactory, int version, ClassLoader classLoader,
                             Map<Integer, ? extends DataSerializableFactory> dataSerializableFactories,
                             Map<Integer, ? extends PortableFactory> portableFactories,
                             Collection<ClassDefinition> classDefinitions, boolean checkClassDefErrors,
                             ManagedContext managedContext, PartitioningStrategy partitionStrategy,
                             int initialOutputBufferSize, boolean enableCompression, boolean enableSharedObject) {

        this.inputOutputFactory = inputOutputFactory;
        this.classLoader = classLoader;
        this.managedContext = managedContext;
        this.globalPartitioningStrategy = partitionStrategy;
        this.outputBufferSize = initialOutputBufferSize;

        dataOutputQueue = new ThreadLocalOutputCache(this);

        PortableHookLoader loader = new PortableHookLoader(portableFactories, classLoader);
        portableContext = new PortableContextImpl(this, version);
        for (ClassDefinition cd : loader.getDefinitions()) {
            portableContext.registerClassDefinition(cd);
        }

        dataSerializerAdapter = createSerializerAdapter(new DataSerializer(dataSerializableFactories, classLoader));
        portableSerializer = new PortableSerializer(portableContext, loader.getFactories());
        portableSerializerAdapter = createSerializerAdapter(portableSerializer);

        registerConstantSerializers();
        registerJvmTypeSerializers(enableCompression, enableSharedObject);
        registerClassDefinitions(classDefinitions, checkClassDefErrors);
    }

    private void registerJvmTypeSerializers(boolean enableCompression, boolean enableSharedObject) {
        safeRegister(Date.class, new DateSerializer());
        safeRegister(BigInteger.class, new BigIntegerSerializer());
        safeRegister(BigDecimal.class, new BigDecimalSerializer());
        safeRegister(Externalizable.class, new Externalizer(enableCompression));
        safeRegister(Serializable.class, new ObjectSerializer(enableSharedObject, enableCompression));
        safeRegister(Class.class, new ClassSerializer());
        safeRegister(Enum.class, new EnumSerializer());
    }

    private void registerConstantSerializers() {
        registerConstant(DataSerializable.class, dataSerializerAdapter);
        registerConstant(Portable.class, portableSerializerAdapter);
        registerConstant(Byte.class, new ByteSerializer());
        registerConstant(Boolean.class, new BooleanSerializer());
        registerConstant(Character.class, new CharSerializer());
        registerConstant(Short.class, new ShortSerializer());
        registerConstant(Integer.class, new IntegerSerializer());
        registerConstant(Long.class, new LongSerializer());
        registerConstant(Float.class, new FloatSerializer());
        registerConstant(Double.class, new DoubleSerializer());
        registerConstant(byte[].class, new TheByteArraySerializer());
        registerConstant(char[].class, new CharArraySerializer());
        registerConstant(short[].class, new ShortArraySerializer());
        registerConstant(int[].class, new IntegerArraySerializer());
        registerConstant(long[].class, new LongArraySerializer());
        registerConstant(float[].class, new FloatArraySerializer());
        registerConstant(double[].class, new DoubleArraySerializer());
        registerConstant(String.class, new StringSerializer());
    }

    private void registerClassDefinitions(Collection<ClassDefinition> classDefinitions, boolean checkClassDefErrors) {
        final Map<Integer, ClassDefinition> classDefMap = new HashMap<Integer, ClassDefinition>(classDefinitions.size());
        for (ClassDefinition cd : classDefinitions) {
            if (classDefMap.containsKey(cd.getClassId())) {
                throw new HazelcastSerializationException("Duplicate registration found for class-id["
                        + cd.getClassId() + "]!");
            }
            classDefMap.put(cd.getClassId(), cd);
        }
        for (ClassDefinition classDefinition : classDefinitions) {
            registerClassDefinition(classDefinition, classDefMap, checkClassDefErrors);
        }
    }

    private void registerClassDefinition(ClassDefinition cd, Map<Integer, ClassDefinition> classDefMap,
            boolean checkClassDefErrors) {
        for (int i = 0; i < cd.getFieldCount(); i++) {
            FieldDefinition fd = cd.getField(i);
            if (fd.getType() == FieldType.PORTABLE || fd.getType() == FieldType.PORTABLE_ARRAY) {
                int classId = fd.getClassId();
                ClassDefinition nestedCd = classDefMap.get(classId);
                if (nestedCd != null) {
                    registerClassDefinition(nestedCd, classDefMap, checkClassDefErrors);
                    portableContext.registerClassDefinition(nestedCd);
                } else if (checkClassDefErrors) {
                    throw new HazelcastSerializationException("Could not find registered ClassDefinition for class-id: "
                            + classId);
                }
            }
        }
        portableContext.registerClassDefinition(cd);
    }

    public final Data toData(final Object obj) {
        return toData(obj, globalPartitioningStrategy);
    }

    public final Data toData(Object obj, PartitioningStrategy strategy) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Data) {
            return (Data) obj;
        }
        int partitionHash = calculatePartitionHash(obj, strategy);
        try {
            final SerializerAdapter serializer = serializerFor(obj.getClass());
            if (serializer == null) {
                if (active) {
                    throw new HazelcastSerializationException("There is no suitable serializer for " + obj.getClass());
                }
                throw new HazelcastInstanceNotActiveException();
            }
            return serializer.toData(obj, partitionHash);
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    @SuppressWarnings("unchecked")
    protected final int calculatePartitionHash(Object obj, PartitioningStrategy strategy) {
        int partitionHash = 0;
        PartitioningStrategy partitioningStrategy = strategy == null ? globalPartitioningStrategy : strategy;
        if (partitioningStrategy != null) {
            Object pk = partitioningStrategy.getPartitionKey(obj);
            if (pk != null && pk != obj) {
                final Data partitionKey = toData(pk, EMPTY_PARTITIONING_STRATEGY);
                partitionHash = partitionKey == null ? 0 : partitionKey.getPartitionHash();
            }
        }
        return partitionHash;
    }

    public final <T> T toObject(final Object object) {
        if (!(object instanceof Data)) {
            return (T) object;
        }

        Data data = (Data) object;
        if (data.dataSize() == 0 && data.getType() == SerializationConstants.CONSTANT_TYPE_NULL) {
            return null;
        }
        try {
            final int typeId = data.getType();
            final SerializerAdapter serializer = serializerFor(typeId);
            if (serializer == null) {
                if (active) {
                    throw new HazelcastSerializationException("There is no suitable de-serializer for type " + typeId);
                }
                throw new HazelcastInstanceNotActiveException();
            }
            Object obj = serializer.toObject(data);
            if (managedContext != null) {
                obj = managedContext.initialize(obj);
            }
            return (T) obj;
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    public final void writeObject(final ObjectDataOutput out, final Object obj) {
        if (obj instanceof Data) {
            throw new HazelcastSerializationException("Cannot write a Data instance! "
                    + "Use #writeData(ObjectDataOutput out, Data data) instead.");
        }
        final boolean isNull = obj == null;
        try {
            out.writeBoolean(isNull);
            if (isNull) {
                return;
            }
            final SerializerAdapter serializer = serializerFor(obj.getClass());
            if (serializer == null) {
                if (active) {
                    throw new HazelcastSerializationException("There is no suitable serializer for " + obj.getClass());
                }
                throw new HazelcastInstanceNotActiveException();
            }
            out.writeInt(serializer.getTypeId());
            serializer.write(out, obj);
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    public final <T> T readObject(final ObjectDataInput in) {
        try {
            final boolean isNull = in.readBoolean();
            if (isNull) {
                return null;
            }
            final int typeId = in.readInt();
            final SerializerAdapter serializer = serializerFor(typeId);
            if (serializer == null) {
                if (active) {
                    throw new HazelcastSerializationException("There is no suitable de-serializer for type " + typeId);
                }
                throw new HazelcastInstanceNotActiveException();
            }
            Object obj = serializer.read(in);
            if (managedContext != null) {
                obj = managedContext.initialize(obj);
            }
            return (T) obj;
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    @Override
    public final void writeData(ObjectDataOutput out, Data data) {
        try {
            boolean isNull = data == null;
            out.writeBoolean(isNull);
            if (isNull) {
                return;
            }
            out.writeInt(data.getType());
            out.writeInt(data.hasPartitionHash() ? data.getPartitionHash() : 0);
            writePortableHeader(out, data);

            int size = data.dataSize();
            out.writeInt(size);
            if (size > 0) {
                writeDataInternal(out, data);
            }
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    protected final void writePortableHeader(ObjectDataOutput out, Data data) throws IOException {
        if (data.headerSize() == 0) {
            out.writeInt(0);
        } else {
            if (!(out instanceof PortableDataOutput)) {
                throw new HazelcastSerializationException("PortableDataOutput is required to be able "
                        + "to write Portable header.");
            }

            byte[] header = data.getHeader();
            PortableDataOutput output = (PortableDataOutput) out;
            DynamicByteBuffer headerBuffer = output.getHeaderBuffer();
            out.writeInt(header.length);
            out.writeInt(headerBuffer.position());
            headerBuffer.put(header);
        }
    }

    protected void writeDataInternal(ObjectDataOutput out, Data data) throws IOException {
        out.write(data.getData());
    }

    @Override
    public final Data readData(ObjectDataInput in) {
        try {
            boolean isNull = in.readBoolean();
            if (isNull) {
                return null;
            }

            int typeId = in.readInt();
            int partitionHash = in.readInt();
            byte[] header = readPortableHeader(in);

            int dataSize = in.readInt();
            byte[] data = null;
            if (dataSize > 0) {
                data = new byte[dataSize];
                in.readFully(data);
            }
            return new DefaultData(typeId, data, partitionHash, header);
        } catch (Throwable e) {
            throw handleException(e);
        }
    }

    protected final byte[] readPortableHeader(ObjectDataInput in) throws IOException {
        byte[] header = null;
        int len = in.readInt();
        if (len > 0) {
            if (!(in instanceof PortableDataInput)) {
                throw new HazelcastSerializationException("PortableDataInput is required to be able "
                        + "to read Portable header.");
            }
            PortableDataInput input = (PortableDataInput) in;
            ByteBuffer headerBuffer = input.getHeaderBuffer();
            int pos = in.readInt();
            headerBuffer.position(pos);
            header = new byte[len];
            headerBuffer.get(header);
        }
        return header;
    }

    public void disposeData(Data data) {
    }

    protected RuntimeException handleException(Throwable e) {
        if (e instanceof OutOfMemoryError) {
            OutOfMemoryErrorDispatcher.onOutOfMemory((OutOfMemoryError) e);
            throw (Error) e;
        }
        if (e instanceof Error) {
            throw (Error) e;
        }
        if (e instanceof HazelcastSerializationException) {
            throw (HazelcastSerializationException) e;
        }
        throw new HazelcastSerializationException(e);
    }


    public final BufferObjectDataOutput pop() {
        return dataOutputQueue.pop();
    }

    public final void push(BufferObjectDataOutput out) {
        dataOutputQueue.push(out);
    }

    public final BufferObjectDataInput createObjectDataInput(byte[] data) {
        return inputOutputFactory.createInput(data, this);
    }

    public final BufferObjectDataInput createObjectDataInput(Data data) {
        return inputOutputFactory.createInput(data, this);
    }

    public final BufferObjectDataOutput createObjectDataOutput(int size) {
        return inputOutputFactory.createOutput(size, this);
    }

    public final ObjectDataOutputStream createObjectDataOutputStream(OutputStream out) {
        return new ObjectDataOutputStream(out, this);
    }

    public final ObjectDataInputStream createObjectDataInputStream(InputStream in) {
        return new ObjectDataInputStream(in, this);
    }

    public final void register(Class type, Serializer serializer) {
        if (type == null) {
            throw new IllegalArgumentException("Class type information is required!");
        }
        if (serializer.getTypeId() <= 0) {
            throw new IllegalArgumentException("Type id must be positive! Current: "
                    + serializer.getTypeId() + ", Serializer: " + serializer);
        }
        safeRegister(type, createSerializerAdapter(serializer));
    }

    public final void registerGlobal(final Serializer serializer) {
        SerializerAdapter adapter = createSerializerAdapter(serializer);
        if (!global.compareAndSet(null, adapter)) {
            throw new IllegalStateException("Global serializer is already registered!");
        }
        SerializerAdapter current = idMap.putIfAbsent(serializer.getTypeId(), adapter);
        if (current != null && current.getImpl().getClass() != adapter.getImpl().getClass()) {
            global.compareAndSet(adapter, null);
            throw new IllegalStateException("Serializer [" + current.getImpl()
                    + "] has been already registered for type-id: " + serializer.getTypeId());
        }
    }

    protected SerializerAdapter createSerializerAdapter(Serializer serializer) {
        final SerializerAdapter s;
        if (serializer instanceof StreamSerializer) {
            s = new StreamSerializerAdapter(this, (StreamSerializer) serializer);
        } else if (serializer instanceof ByteArraySerializer) {
            s = new ByteArraySerializerAdapter((ByteArraySerializer) serializer);
        } else {
            throw new IllegalArgumentException("Serializer must be instance of either "
                    + "StreamSerializer or ByteArraySerializer!");
        }
        return s;
    }

    protected final SerializerAdapter serializerFor(final Class type) {
        if (DataSerializable.class.isAssignableFrom(type)) {
            return dataSerializerAdapter;
        } else if (Portable.class.isAssignableFrom(type)) {
            return portableSerializerAdapter;
        } else {
            final SerializerAdapter serializer = constantTypesMap.get(type);
            if (serializer != null) {
                return serializer;
            }
        }
        SerializerAdapter serializer = lookupSerializer(type);
        return serializer;
    }

    protected final SerializerAdapter lookupSerializer(Class type) {
        SerializerAdapter serializer = typeMap.get(type);
        if (serializer == null) {
            // look for super classes
            Class typeSuperclass = type.getSuperclass();
            final Set<Class> interfaces = new LinkedHashSet<Class>(5);
            getInterfaces(type, interfaces);
            while (typeSuperclass != null) {
                serializer = registerFromSuperType(type, typeSuperclass);
                if (serializer != null) {
                    break;
                }
                getInterfaces(typeSuperclass, interfaces);
                typeSuperclass = typeSuperclass.getSuperclass();
            }
            if (serializer == null) {
                // look for interfaces
                for (Class typeInterface : interfaces) {
                    serializer = registerFromSuperType(type, typeInterface);
                    if (serializer != null) {
                        break;
                    }
                }
            }

            if (serializer == null) {
                serializer = global.get();
                if (serializer != null) {
                    safeRegister(type, serializer);
                }
            }
        }
        return serializer;
    }

    private static void getInterfaces(Class clazz, Set<Class> interfaces) {
        final Class[] classes = clazz.getInterfaces();
        if (classes.length > 0) {
            Collections.addAll(interfaces, classes);
            for (Class cl : classes) {
                getInterfaces(cl, interfaces);
            }
        }
    }

    private SerializerAdapter registerFromSuperType(final Class type, final Class superType) {
        final SerializerAdapter serializer = typeMap.get(superType);
        if (serializer != null) {
            safeRegister(type, serializer);
        }
        return serializer;
    }

    private void registerConstant(Class type, Serializer serializer) {
        registerConstant(type, createSerializerAdapter(serializer));
    }

    private void registerConstant(Class type, SerializerAdapter serializer) {
        constantTypesMap.put(type, serializer);
        constantTypeIds[indexForDefaultType(serializer.getTypeId())] = serializer;
    }

    void safeRegister(final Class type, final Serializer serializer) {
        safeRegister(type, createSerializerAdapter(serializer));
    }

    private void safeRegister(final Class type, final SerializerAdapter serializer) {
        if (constantTypesMap.containsKey(type)) {
            throw new IllegalArgumentException("[" + type + "] serializer cannot be overridden!");
        }
        SerializerAdapter current = typeMap.putIfAbsent(type, serializer);
        if (current != null && current.getImpl().getClass() != serializer.getImpl().getClass()) {
            throw new IllegalStateException("Serializer[" + current.getImpl()
                    + "] has been already registered for type: " + type);
        }
        current = idMap.putIfAbsent(serializer.getTypeId(), serializer);
        if (current != null && current.getImpl().getClass() != serializer.getImpl().getClass()) {
            throw new IllegalStateException("Serializer [" + current.getImpl() + "] has been already registered for type-id: "
                    + serializer.getTypeId());
        }
    }

    protected final SerializerAdapter serializerFor(final int typeId) {
        if (typeId < 0) {
            final int index = indexForDefaultType(typeId);
            if (index < CONSTANT_SERIALIZERS_SIZE) {
                return constantTypeIds[index];
            }
        }
        return idMap.get(typeId);
    }

    private int indexForDefaultType(final int typeId) {
        return -typeId - 1;
    }

    public PortableContext getPortableContext() {
        return portableContext;
    }

    public final PortableReader createPortableReader(Data data) throws IOException {
        if (!data.isPortable()) {
            throw new IllegalArgumentException();
        }
        BufferObjectDataInput in = createObjectDataInput(data);
        return portableSerializer.createReader(in);

    }

    public void destroy() {
        active = false;
        for (SerializerAdapter serializer : typeMap.values()) {
            serializer.destroy();
        }
        typeMap.clear();
        idMap.clear();
        global.set(null);
        constantTypesMap.clear();
        dataOutputQueue.clear();
    }

    public final ClassLoader getClassLoader() {
        return classLoader;
    }

    public final ManagedContext getManagedContext() {
        return managedContext;
    }

    @Override
    public ByteOrder getByteOrder() {
        return inputOutputFactory.getByteOrder();
    }

    public boolean isActive() {
        return active;
    }

    private static final class ThreadLocalOutputCache {
        static final float LOAD_FACTOR = 0.91f;
        final ConcurrentMap<Thread, Queue<BufferObjectDataOutput>> map;
        final SerializationServiceImpl serializationService;
        final int bufferSize;

        private ThreadLocalOutputCache(SerializationServiceImpl serializationService) {
            this.serializationService = serializationService;
            bufferSize = serializationService.outputBufferSize;
            int initialCapacity = Runtime.getRuntime().availableProcessors();
            map = new ConcurrentReferenceHashMap<Thread, Queue<BufferObjectDataOutput>>(initialCapacity, LOAD_FACTOR, 1);
        }

        BufferObjectDataOutput pop() {
            Thread t = Thread.currentThread();
            Queue<BufferObjectDataOutput> outputQueue = map.get(t);
            if (outputQueue == null) {
                outputQueue = new ArrayDeque<BufferObjectDataOutput>(3);
                map.put(t, outputQueue);
            }
            BufferObjectDataOutput out = outputQueue.poll();
            if (out == null) {
                out = serializationService.createObjectDataOutput(bufferSize);
            }
            return out;
        }

        void push(BufferObjectDataOutput out) {
            if (out != null) {
                out.clear();
                Queue<BufferObjectDataOutput> outputQueue = map.get(Thread.currentThread());
                if (outputQueue == null || !outputQueue.offer(out)) {
                    IOUtil.closeResource(out);
                }
            }
        }

        void clear() {
            map.clear();
        }
    }
}
TOP

Related Classes of com.hazelcast.nio.serialization.SerializationServiceImpl$ThreadLocalOutputCache

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.