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

com.refinitiv.eta.transport.SocketBuffer Maven / Gradle / Ivy

package com.refinitiv.eta.transport;

import java.nio.ByteBuffer;

class SocketBuffer extends EtaNode
{
    class SlicesPool extends Pool
    {
        SlicesPool(Object o)
        {
            super(o);
        }

        int _available;
        int _totalSliceCount;

        @Override
        EtaNode poll()
        {
            TransportBufferImpl slice;
            if ((slice = (TransportBufferImpl)super.poll()) != null)
            {
                --_available;
                slice._dataStartOffSet = 0;
                slice.headerLength(RIPC_WRITE_POSITION);
            }
            else
            {
                // create a new slice
                slice = new TransportBufferImpl(this);
                slice._data = _dataBuffer.duplicate();
                ++_totalSliceCount;
            }
            return slice;
        }

        @Override
        void add(EtaNode node)
        {
            super.add(node);
            ++_available;

            if (_available == _totalSliceCount)
            {
                // the SocketBuffer may being recycled
                SocketBuffer buffer = (SocketBuffer)_poolOwner;
                Pool sbp = buffer._pool;
                if (!sbp._isSharedPoolBuffer)
                {
                    if (!sbp._isProtocolBuffer)
                    {
                        ((RsslSocketChannel)sbp._poolOwner).socketBufferToRecycle(buffer);
                    }
                    else
                    {
                        buffer.returnToPool();
                    }
                }
                else
                {
                    ((ServerImpl)sbp._poolOwner).socketBufferToRecycle(buffer);
                }
            }
        }

        boolean areAllSlicesBack()
        {
            return (_available == _totalSliceCount);
        }
    }

    static final int PACKED_HDR = 2;
    static final int RIPC_WRITE_POSITION = 3;
    static final byte FRAGMENT_RIPC_FLAGS = 0x04;
    static final byte FRAGMENT_HEADER_RIPC_FLAGS = 0x08;
    static final int COMPRESSION_EXTRA_LEN = 16;

    ByteBuffer _dataBuffer;

    // pool of slices
    final SlicesPool _slicesPool;

    int _bytesUsed = 0;
    boolean _isPacked = false;

    SocketBuffer(Pool pool, int size)
    {
        _dataBuffer = ByteBuffer.allocate(size);
        pool(pool);
        _slicesPool = new SlicesPool(this);
    }

    TransportBufferImpl getBufferSlice(int size, boolean packedBuffer, int headerLength)
    {
        // locked by calling method
        TransportBufferImpl slice = null;

        int _headerLength = headerLength;
        if (!packedBuffer)
        {
            _isPacked = false;
        }
        else
        {
            _headerLength += PACKED_HDR;
            _isPacked = true;
        }

        if ((_dataBuffer.capacity() - _bytesUsed) >= (_headerLength + size))
        {
            slice = (TransportBufferImpl)_slicesPool.poll(); // it returns non null
            slice._data.clear();

            slice._startPosition = _bytesUsed;
            slice._data.limit(_bytesUsed + _headerLength + size);
            slice._data.position(_bytesUsed + _headerLength);
            slice._length = size;
            _bytesUsed = _bytesUsed + _headerLength + size;

            // has to mark the position for the packed message length
            if (_isPacked)
            {
                slice._isPacked = true;
                slice._packedMsgOffSetPosition = slice._startPosition + headerLength;
            }
            else
            {
                slice._isPacked = false;
            }
        }

        return slice;
    }

    TransportBufferImpl getBufferSliceForFragment(int size)
    {
        // locked by calling method
        TransportBufferImpl slice = null;
        _isPacked = false;

        slice = (TransportBufferImpl)_slicesPool.poll();
        slice._startPosition = 0;
        slice._data.limit(size);
        slice._data.position(0);
        _bytesUsed = size;

        return slice;
    }

    void clear()
    {
        _dataBuffer.clear();
        _bytesUsed = 0;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy