HeapChannelBufferHeapChannelBuffer是ChannelBuffer的一种具体的实现,该类是基于字节数组的ChannelBuffer实现,通过byte[]数组来进行数据的存储,setBytes和getBytes通过System.arraycopy来进行对数组的操作 。
//此缓冲区包装的基础堆字节数组 protected final byte[] array; @Override public void getBytes(int index, byte[] dst, int dstIndex, int length) { System.arraycopy(array, index, dst, dstIndex, length); } @Override public void setBytes(int index, byte[] src, int srcIndex, int length) { System.arraycopy(src, srcIndex, array, index, length); }对于HeapChannelBuffer的具体的工厂的实现是HeapChannelBufferFactory,该工厂是一个单例模式,HeapChannelBufferFactory通过ChannelBuffers工具类创建固定容量的HeapChannelBuffer,此外也可以通过拷贝的形式创建HeapChannelBuffer 。
@Override public ChannelBufferFactory factory() { return HeapChannelBufferFactory.getInstance(); }
DynamicChannelBufferDynamicChannelBuffer可以理解为一个扩展类,也就是对装饰者模式,就是对ChannelBuffer的增加强,增加动态扩容的能力,关于该类默认的实现HeapChannelBufferFactory,我可以通过指定HeapChannelBufferFactory为对应的实现添加动态扩容的能力 。
//具体的ChannelBufferFactory的实现 private final ChannelBufferFactory factory; //需要扩容的buffer private ChannelBuffer buffer; public DynamicChannelBuffer(int estimatedLength) { //默认实现 this(estimatedLength, HeapChannelBufferFactory.getInstance()); } //指定具体的实现 public DynamicChannelBuffer(int estimatedLength, ChannelBufferFactory factory) { if (estimatedLength < 0) { throw new IllegalArgumentException("estimatedLength: " + estimatedLength); } if (factory == null) { throw new NullPointerException("factory"); } this.factory = factory; buffer = factory.getBuffer(estimatedLength); }关于如何实现ChannelBuffer的动态扩容,看懂Java ArryList扩容的,我相信一定能理解,也就是我们要控制写入时候的判断写入的空间是否足够就可以了 。DynamicChannelBuffer通过ensureWritableBytes方法来实现扩容,我们来看下他是如何做的:
@Override public void ensureWritableBytes(int minWritableBytes) { //如果写入字节数小于等于可写的字节数 if (minWritableBytes <= writableBytes()) { return; } //新增容量 int newCapacity; //缓存区字节数为0 if (capacity() == 0) { //设置为1 newCapacity = 1; } else { //新增容量为缓冲区字节数 newCapacity = capacity(); } //最小新增容量 = 当前写入字节数的索引+最小写入的字节数 int minNewCapacity = writerIndex() + minWritableBytes; //如果新增容量小于最小新增容量 while (newCapacity < minNewCapacity) { //新增容量左移1位,加倍 newCapacity <<= 1; } //通过工厂类创建该容量 ChannelBuffer newBuffer = factory().getBuffer(newCapacity); //从buffer中读取数据到newBuffer中 newBuffer.writeBytes(buffer, 0, writerIndex()); //替换原来的缓存区 buffer = newBuffer; }
经验总结扩展阅读
- 驱动开发:内核封装WSK网络通信接口
- 二 Linux进程间通信
- 一 Linux进程间通信
- Dubbo-聊聊注册中心的设计
- VS Code For Web 深入浅出 -- 进程间通信篇
- 聊聊Linux中CPU上下文切换
- 聊聊Vim的工作原理
- 驱动开发:通过Async反向与内核通信
- 51单片机下实现软件模拟IIC通信
- 驱动通信:通过PIPE管道与内核层通信