# Buffer

Netty通过allocator创建buffer。

  • Buffer不是线程安全的。
  • 字节按照大端标识。

Buffer有读写各一个指针。读指针永远小于写。从0开始。

      +-------------------+------------------+------------------+
      | discardable bytes |  readable bytes  |  writable bytes  |
      |                   |     (CONTENT)    |                  |
      +-------------------+------------------+------------------+
      |                   |                  |                  |
      0      <=     readerOffset  <=   writerOffset    <=    capacity

buffer可以通过split()方法来拆分,底层共享内存。

# CompositeBuffer

合并多个Buffer,对外当做一个Buffer使用。

合并的buffer包含三部分独立区域:

  1. 已读内存。
  2. 可读内存。
  3. 可写内存。

复合缓冲区的问题在于每个Buffer可能都有独立的读写偏移,这造成了buffer之间存在内存空隙。解决方案是复合缓冲区对外隐藏这些空隙信息。

如下图,两个buffer拼接之后,读偏移按照第一个buffer+第二个buffer读的位置来确定,而写按照最后一个非0的写buffer偏移进行确定,第一个buffer的写偏移被隐藏掉。即可以认为,因为buffer要求readerOffset必须在writerOffset前面,所以非最后一个buffer的写偏移到下一个buffer的读前偏移会被隐藏。

  • 可读区域为所有buffer非0的可读区域拼接。
  • 可写区域为最后一个非0的可写buffer,前面所有小于最后一个可读区域的可写区域都会被隐藏。
   First buffer                Second buffer
       +----------------------+    +--------------------+
      0|    |r/o      |w/o    |   0|    |r/o     |w/o   |
       +----+---------+-------+    +----+--------+------+
        \    \         \  ,____________/   ,___________/
         \    \         \/                /
          +----+---------+--------+------+
         0|    |r/o      :        |w/o   |  Composite buffer
          +------------------------------+
  

组成复合缓冲区的所有buffer要么都是只读的,要么都是可写的。不要求统一大小。 对于不同的buffer,allocator没有要求,但是创建当前复合缓冲区的allocator会在扩容的时候用到。