Package net.openhft.chronicle.sandbox.queue

Source Code of net.openhft.chronicle.sandbox.queue.ConcurrentBlockingObjectQueueBuilder

/*
* Copyright 2014 Higher Frequency Trading
* <p/>
* http://www.higherfrequencytrading.com
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.sandbox.queue;

import net.openhft.chronicle.sandbox.queue.locators.DataLocator;
import net.openhft.chronicle.sandbox.queue.locators.RingIndex;
import net.openhft.chronicle.sandbox.queue.locators.local.LocalDataLocator;
import net.openhft.chronicle.sandbox.queue.locators.local.LocalRingIndex;
import net.openhft.chronicle.sandbox.queue.locators.shared.BytesDataLocator;
import net.openhft.chronicle.sandbox.queue.locators.shared.SharedLocalDataLocator;
import net.openhft.chronicle.sandbox.queue.locators.shared.SharedRingIndex;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.Consumer;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.Producer;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.SocketWriter;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.channel.provider.ClientSocketChannelProvider;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.channel.provider.ServerSocketChannelProvider;
import net.openhft.chronicle.sandbox.queue.locators.shared.remote.channel.provider.SocketChannelProvider;
import net.openhft.lang.io.ByteBufferBytes;
import net.openhft.lang.io.DirectBytes;
import net.openhft.lang.io.MappedStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.BlockingQueue;

/**
* Created by Rob Austin
*/
public class ConcurrentBlockingObjectQueueBuilder<E> {

    public static final int SIZE_OF_INT = 4;
    public static final int RECEIVE_BUFFER_SIZE = 256 * 1024;
    public static final int LOCK_TIME_OUT_NS = 100;
    private static Logger LOG = LoggerFactory.getLogger(SocketWriter.class);
    int capacity;

    int maxSize = 128;
    Class<E> clazz;
    Type type = Type.LOCAL;
    private int port = 8096;
    private String host;
    private String fileName = "/share-queue-test" + System.nanoTime();
    private boolean deleteOnExit;

    /**
     * returns the value to nearest {@parm powerOf2}
     */
    public static int align(int capacity, int powerOf2) {
        return (capacity + powerOf2 - 1) & ~(powerOf2 - 1);
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    public void setCapacity(int capacity) {
        // the ring buffer works by having 1 item spare, that's why we add one
        this.capacity = capacity + 1;
    }

    public void setClazz(Class<E> clazz) {
        this.clazz = clazz;
    }


    public void setDeleteOnExit(boolean deleteOnExit) {
        this.deleteOnExit = deleteOnExit;
    }

    public BlockingQueue<E> create() throws IOException {

        final DataLocator dataLocator;
        final RingIndex ringIndex;

        if (type == Type.LOCAL) {
            ringIndex = new LocalRingIndex();
            dataLocator = new LocalDataLocator(capacity);

        } else if (type == Type.SHARED) {

            final String tmp = System.getProperty("java.io.tmpdir");
            final File file = new File(tmp + fileName);

            if (deleteOnExit)
                file.deleteOnExit();

            int ringIndexLocationsStart = 0;
            int ringIndexLocationsLen = SIZE_OF_INT * 2;
            int storeLen = capacity * align(maxSize, 4);

            final MappedStore ms = new MappedStore(file, FileChannel.MapMode.READ_WRITE, ringIndexLocationsLen + storeLen);
            final DirectBytes ringIndexSlice = ms.bytes(ringIndexLocationsStart, ringIndexLocationsLen);
            ringIndex = new SharedRingIndex(ringIndexSlice);

            // provides an index to the data in the ring buffer, the size of this index is proportional to the capacity of the ring buffer
            final DirectBytes storeSlice = ms.bytes(ringIndexLocationsLen, storeLen);
            dataLocator = new SharedLocalDataLocator(capacity, maxSize, storeSlice, clazz);

        } else if (type == Type.REMOTE_PRODUCER || type == Type.REMOTE_CONSUMER) {

            final int bufferSize = capacity * align(maxSize, 4);
            final ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
            final ByteBufferBytes byteBufferBytes = new ByteBufferBytes(buffer);

            final BytesDataLocator<E, ByteBufferBytes> bytesDataLocator = new BytesDataLocator<E, ByteBufferBytes>(
                    clazz,
                    capacity,
                    maxSize,
                    byteBufferBytes.slice(),
                    byteBufferBytes.slice());

            if (type == Type.REMOTE_PRODUCER) {
                final Producer producer = new Producer<E, ByteBufferBytes>(new LocalRingIndex(), bytesDataLocator, bytesDataLocator, new ServerSocketChannelProvider(port), bytesDataLocator, buffer);
                ringIndex = producer;
                dataLocator = producer;
            } else {
                ringIndex = new Consumer<ByteBufferBytes>(new LocalRingIndex(), bytesDataLocator, bytesDataLocator, new ClientSocketChannelProvider(port, host), buffer);
                dataLocator = bytesDataLocator;
            }

        } else {
            throw new IllegalArgumentException("Unsupported Type=" + type);
        }

        return new ConcurrentBlockingObjectQueue<E>(ringIndex, dataLocator);

    }

    private SocketChannelProvider getProducerSocketChannelProvider() {


        return new SocketChannelProvider() {

            ServerSocketChannel serverSocket = null;

            @Override
            public SocketChannel getSocketChannel() throws IOException {
                serverSocket = ServerSocketChannel.open();
                serverSocket.socket().setReuseAddress(true);
                serverSocket.socket().bind(new InetSocketAddress(port));
                serverSocket.configureBlocking(true);
                LOG.info("Server waiting for client on port {}", port);
                serverSocket.socket().setReceiveBufferSize(RECEIVE_BUFFER_SIZE);
                return serverSocket.accept();
            }

            @Override
            public void close() throws IOException {
                if (serverSocket != null)
                    serverSocket.close();
            }
        };
    }


    public enum Type {

        LOCAL("running within one JVM"),
        SHARED("one producer JVM, one Consumer JVM, with the Jvm's on the same Host"),
        REMOTE_PRODUCER("One Producer that connects via tcp/ip to single REMOTE_CONSUMER"),
        REMOTE_CONSUMER("One Consumer that connects via tcp/ip to single REMOTE_PRODUCER");

        private final String about;

        Type(String about) {
            this.about = about;
        }

        @Override
        public String toString() {
            return about;
        }
    }

}
TOP

Related Classes of net.openhft.chronicle.sandbox.queue.ConcurrentBlockingObjectQueueBuilder

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.