Class SocketBuffer


  • class SocketBuffer
    extends java.lang.Object
    The SocketBuffer represents a buffer that aggregates small fragments in to a single buffer before sending them. This is primarily used as a means to avoid sending many small packets rather than reasonable size ones for performance. This also enables a higher level of concurrency, as it will allow data that can't be sent over the socket to be buffered until it gets the signal that says it can be sent on.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private SocketBufferAppender appender
      This is a small internal buffer to collect fragments.
      private java.nio.channels.SocketChannel channel
      This is the underlying socket to sent to the data over.
      private int chunk
      This is the recommended minimum packet size to send.
      private boolean closed
      This is used to determine if the buffer was closed.
      private java.nio.ByteBuffer reference
      This is a reference to the last buffer to be sent.
      private Trace trace
      This is used to trace various events that occur.
    • Constructor Summary

      Constructors 
      Constructor Description
      SocketBuffer​(Socket socket, int chunk, int limit)
      Constructor for the SocketBuffer object.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void close()
      This is used to close the writer and the underlying socket.
      private void compact()
      To ensure that we can release any references and thus avoid a blocking thread this method will attempt to merge references in to the internal buffer.
      boolean flush()
      This method is used to fully flush the contents of the buffer to the underlying output stream.
      private boolean flush​(java.nio.ByteBuffer segment)
      This write method will write the contents of the buffer to the provided byte channel.
      private boolean merge​(java.nio.ByteBuffer duplicate)
      This method is used to perform a merge of the buffer to be sent with the current buffer.
      boolean ready()
      This is used to determine if the buffer is ready to be written to.
      boolean write​(java.nio.ByteBuffer duplicate)
      This will write the bytes to underlying channel if the data is greater than the minimum buffer size.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • appender

        private SocketBufferAppender appender
        This is a small internal buffer to collect fragments.
      • channel

        private java.nio.channels.SocketChannel channel
        This is the underlying socket to sent to the data over.
      • reference

        private java.nio.ByteBuffer reference
        This is a reference to the last buffer to be sent.
      • trace

        private Trace trace
        This is used to trace various events that occur.
      • chunk

        private int chunk
        This is the recommended minimum packet size to send.
      • closed

        private boolean closed
        This is used to determine if the buffer was closed.
    • Constructor Detail

      • SocketBuffer

        public SocketBuffer​(Socket socket,
                            int chunk,
                            int limit)
        Constructor for the SocketBuffer object. This is used to create a buffer that will collect small fragments sent in to a more reasonably sized packet.
        Parameters:
        socket - this is the socket to write the data to
        chunk - this is the minimum packet size to used
        limit - this is the maximum size of the output buffer
    • Method Detail

      • ready

        public boolean ready()
                      throws java.io.IOException
        This is used to determine if the buffer is ready to be written to. A buffer is ready when it does not hold a reference to any other buffer internally. The the flush method must return true for a buffer to be considered ready.
        Returns:
        returns true if the buffer is ready to write to
        Throws:
        java.io.IOException
      • write

        public boolean write​(java.nio.ByteBuffer duplicate)
                      throws java.io.IOException
        This will write the bytes to underlying channel if the data is greater than the minimum buffer size. If it is less than the minimum size then it will be appended to the internal buffer. If it is larger than the maximum size of the internal buffer a reference is kept to it. This reference can only be cleared with the flush method, which will attempt to write the data to the channel, and buffer any remaining data if the underly connection is busy.
        Parameters:
        data - this is the data to write the the channel.
        Returns:
        this returns true if no reference was held
        Throws:
        java.io.IOException
      • merge

        private boolean merge​(java.nio.ByteBuffer duplicate)
                       throws java.io.IOException
        This method is used to perform a merge of the buffer to be sent with the current buffer. If the internal buffer is large enough to send after the merge then it will be sent. Also, if the remaining bytes in the buffer are large enough for a packet then that too will be sent over the socket.
        Parameters:
        duplicate - this is the buffer to be merged
        Returns:
        this returns true if no reference was held
        Throws:
        java.io.IOException
      • flush

        public boolean flush()
                      throws java.io.IOException
        This method is used to fully flush the contents of the buffer to the underlying output stream. This will only ever return true if there are no references held and no data internally buffered. If before this method is invoked a reference to a byte buffer is held then this will attempt to merge it with the internal buffer so that the ready method can return true. This ensures that the writing thread does not need to block.
        Returns:
        this returns true if all of the bytes are sent
        Throws:
        java.io.IOException
      • flush

        private boolean flush​(java.nio.ByteBuffer segment)
                       throws java.io.IOException
        This write method will write the contents of the buffer to the provided byte channel. If the whole buffer can be be written then this will simply return the number of bytes that have. The number of bytes remaining within the packet after a write can be acquired from the length method. Once all of the bytes are written the packet must be closed.
        Parameters:
        channel - this is the channel to write the packet to
        segment - this is the segment that is to be written
        Returns:
        this returns the number of bytes that were written
        Throws:
        java.io.IOException
      • compact

        private void compact()
                      throws java.io.IOException
        To ensure that we can release any references and thus avoid a blocking thread this method will attempt to merge references in to the internal buffer. Compacting in this manner is done only if the full reference can fit in to the available space.
        Throws:
        java.io.IOException
      • close

        public void close()
                   throws java.io.IOException
        This is used to close the writer and the underlying socket. If a close is performed on the writer then no more bytes can be read from or written to the writer and the client will receive a connection close on their side. This also ensures that the TCP FIN ACK is sent before the actual channel is closed. This is required for a clean shutdown.
        Throws:
        java.io.IOException