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

net.openhft.chronicle.hash.serialization.internal.DirectBytesBuffer Maven / Gradle / Ivy

/*
 * Copyright 2014 Higher Frequency Trading http://www.higherfrequencytrading.com
 *
 * 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 net.openhft.chronicle.hash.serialization.internal;

import net.openhft.chronicle.hash.serialization.BytesWriter;
import net.openhft.lang.io.BoundsCheckingNativeBytes;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.DirectBytes;
import net.openhft.lang.io.DirectStore;
import net.openhft.lang.io.serialization.BytesMarshaller;
import net.openhft.lang.io.serialization.JDKObjectSerializer;
import net.openhft.lang.threadlocal.StatefulCopyable;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

class DirectBytesBuffer
        implements StatefulCopyable, Serializable {
    private static final long serialVersionUID = 0L;
    private final Serializable identity;
    transient DirectBytes buffer;
    transient BoundsCheckingNativeBytes checkingBuffer;

    transient ForBytesMarshaller forBytesMarshaller;
    transient ForBytesWriter forBytesWriter;
    transient ForDataValueWriter forDataValueWriter;

    DirectBytesBuffer(Serializable identity) {
        this.identity = identity;
        initTransients();
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        initTransients();
    }

    private void initTransients() {
        forBytesMarshaller = new ForBytesMarshaller();
        forBytesWriter = new ForBytesWriter();
        forDataValueWriter = new ForDataValueWriter();
    }

    Bytes obtain(long maxSize, boolean boundsChecking) {
        DirectBytes buf;
        if ((buf = buffer) != null) {
            if (maxSize <= buf.capacity()) {
                if (!boundsChecking)
                    return buf.clear();
                Bytes checkingBuf;
                if ((checkingBuf = checkingBuffer) != null) {
                    return checkingBuf.clear();
                } else {
                    return (checkingBuffer = new BoundsCheckingNativeBytes(buf)).clear();
                }
            } else {
                DirectStore store = (DirectStore) buf.store();
                store.resize(maxSize, true);
                buf = buffer = store.bytes();
                if (!boundsChecking)
                    return buf;
                return (checkingBuffer = new BoundsCheckingNativeBytes(buf));
            }
        } else {
            buf = buffer = new DirectStore(JDKObjectSerializer.INSTANCE,
                    // don't allocate 0 bytes
                    Math.max(1, maxSize), true).bytes();
            if (!boundsChecking)
                return buf;
            return (checkingBuffer = new BoundsCheckingNativeBytes(buf));
        }
    }

    @Override
    public Object stateIdentity() {
        return identity;
    }

    @Override
    public DirectBytesBuffer copy() {
        return new DirectBytesBuffer(identity);
    }

    class ForBytesMarshaller>
            extends CopyingMetaBytesInterop {
        private static final long serialVersionUID = 0L;

        private ForBytesMarshaller() {
            super(DirectBytesBuffer.this);
        }

        void init(M writer, E e, boolean mutable, long maxSize) {
            if (mutable || writer != this.writer || e != cur) {
                this.writer = writer;
                cur = e;
                while (true) {
                    try {
                        Bytes buffer = this.buffer.obtain(maxSize, true);
                        writer.write(buffer, e);
                        buffer.flip();
                        long size = this.size = buffer.remaining();
                        this.buffer.buffer.position(0L);
                        this.buffer.buffer.limit(size);
                        hash = 0L;
                        return;
                    } catch (Exception ex) {
                        checkMaxSizeStillReasonable(maxSize, ex);
                        maxSize *= 2L;
                    }
                }
            }
        }
    }

    class ForBytesWriter>
            extends CopyingMetaBytesInterop {
        private static final long serialVersionUID = 0L;

        private ForBytesWriter() {
            super(DirectBytesBuffer.this);
        }

        void init(W writer, E e, boolean mutable) {
            if (mutable || writer != this.writer || e != cur) {
                this.writer = writer;
                cur = e;
                long size = writer.size(e);
                Bytes buffer = this.buffer.obtain(size, false);
                writer.write(buffer, e);
                buffer.flip();
                this.size = size;
                assert size == buffer.remaining();
                hash = 0L;
            }
        }
    }

    class ForDataValueWriter extends DataValueMetaBytesInterop {

        private ForDataValueWriter() {
            super(DirectBytesBuffer.this);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy