问题 :

  • compositeByteBuf 是干什么和其他 compositeByteBuf 有何区别
  • 内部实现

概述

compositeByteBuf 就像数据库中的视图,把几个表的字段组合在一起,它的应用场景比如一个自定义协议有消息头和消息体,而两者是分开到两个 ByteBuf 的,那么这时候要怎么把两个ByteBuf 放到一起管理呢?compositeByteBuf就可以解决这个问题。

源码

 compositeByteBuf 内部放着一个 Components 的数组,这个 Components 是什么呢?
    private final class Component {
final ByteBuf buf;
final int length;
int offset;
int endOffset; Component(ByteBuf buf) {
this.buf = buf;
length = buf.readableBytes();
} void freeIfNecessary() {
// Unwrap so that we can free slices, too.
buf.release(); // We should not get a NPE here. If so, it must be a bug.
}
}
可以看到实际就是 ByteBuf 的包装类,我们看一下它的使用
addComponent 方法
    /**
* Add the given {@link ByteBuf} on the specific index.
*
* Be aware that this method does not increase the {@code writerIndex} of the {@link CompositeByteBuf}.
* If you need to have it increased you need to handle it by your own.
*
* @param cIndex the index on which the {@link ByteBuf} will be added
* @param buffer the {@link ByteBuf} to add
*/
public CompositeByteBuf addComponent(int cIndex, ByteBuf buffer) {
addComponent0(cIndex, buffer);
consolidateIfNeeded();
return this;
} private int addComponent0(int cIndex, ByteBuf buffer) {
checkComponentIndex(cIndex); if (buffer == null) {
throw new NullPointerException("buffer");
} int readableBytes = buffer.readableBytes();
if (readableBytes == 0) {
return cIndex;
} // No need to consolidate - just add a component to the list.
Component c = new Component(buffer.order(ByteOrder.BIG_ENDIAN).slice());
if (cIndex == components.size()) {
components.add(c);
if (cIndex == 0) {
c.endOffset = readableBytes;
} else {
Component prev = components.get(cIndex - 1);
c.offset = prev.endOffset;
c.endOffset = c.offset + readableBytes;
}
} else {
components.add(cIndex, c);
updateComponentOffsets(cIndex);
}
return cIndex;
}
removeComponent 方法同理

补充

 ByteBufUtil 这个类是可以对 ByteBuf进行操作。

##参考资料

  • 《netty权威指南》

netty(八)buffer源码学习3的更多相关文章

  1. netty(七)buffer源码学习2

    概述 文章主要介绍的是PoolArena,PoolChunk,PoolSubpage 三个类的源码 PoolArena PoolArena 是netty 的内存池实现类,通过预先申请一块大的空间,然后 ...

  2. netty(六) buffer 源码分析

    问题 : netty的 ByteBuff 和传统的ByteBuff的区别是什么? HeapByteBuf 和 DirectByteBuf 的区别 ? HeapByteBuf : 使用堆内存,缺点 ,s ...

  3. 【Netty源码学习】DefaultChannelPipeline(三)

    上一篇博客中[Netty源码学习]ChannelPipeline(二)我们介绍了接口ChannelPipeline的提供的方法,接下来我们分析一下其实现类DefaultChannelPipeline具 ...

  4. 【Netty源码学习】ChannelPipeline(一)

    ChannelPipeline类似于一个管道,管道中存放的是一系列对读取数据进行业务操作的ChannelHandler. 1.ChannelPipeline的结构图: 在之前的博客[Netty源码学习 ...

  5. 【Netty源码学习】ServerBootStrap

    上一篇博客[Netty源码学习]BootStrap中我们介绍了客户端使用的启动服务,接下来我们介绍一下服务端使用的启动服务. 总体来说ServerBootStrap有两个主要功能: (1)调用父类Ab ...

  6. Netty 源码学习——EventLoop

    Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...

  7. Netty 源码学习——客户端流程分析

    Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...

  8. Netty源码学习系列之4-ServerBootstrap的bind方法

    前言 今天研究ServerBootstrap的bind方法,该方法可以说是netty的重中之重.核心中的核心.前两节的NioEventLoopGroup和ServerBootstrap的初始化就是为b ...

  9. Netty源码学习(零)前言

    本系列文章将介绍Netty的工作机制,以及分析Netty的主要源码. 基于的版本是4.1.15.Final(2017.08.24发布) 水平有限,如有谬误请留言指正 参考资料 the_flash的简书 ...

随机推荐

  1. Linux命令 sleep 延迟

    用途说明 sleep命令常用于在Linux shell脚本中延迟时间 常用方式 注意:以下用法中<n>可以为小数. 格式:sleep <n> 格式:sleep <n> ...

  2. 11g RAC添加用户表空间(数据文件)至文件系统(File System)的修正

    前提:非TEMP.UNDO和SYSTEM表空间,这仨是大爷,您得搂着点.来自博客园AskScuti .客户是添加临时表空间数据文件时,不小心 ADD 到了文件系统中,然后发现,后悔了,还在OS层面 R ...

  3. OERR: ORA-32004 "obsolete or deprecated parameter(s) specified for %s instance"

    Oracle 11gR2通过Memory创建动态参数文件后,通过SPFILE启动,提示 ORA-32004: obsolete or deprecated parameter(s) specified ...

  4. 【转】C# Application.DoEvent()的作用

    Application.DoEvents()的作用:处理所有的当前在消息队列中的Windows消息. private void button1_Click(object sender, EventAr ...

  5. JS高级---总结apply和call方法的使用

    apply和call的使用方法 apply的使用语法   函数名字.apply(对象,[参数1,参数2,...]); 方法名字.apply(对象,[参数1,参数2,...]);   call的使用语法 ...

  6. Ubuntu16.04配置

    一.将源更换为国内的源,这样下载和更新软件的速度会快很多.将/etc/apt/sources.list文件的内容更换为如下: #默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消 ...

  7. 字节流和字符流的read方法

    字节流和字符流的read方法 public class Test { public void fileOutput() throws Exception { File file = new File( ...

  8. can总线中什么是远程帧

    所谓“远程帧”是一个传统翻译上的误区.Remote Frame实际上它的意义是“遥控帧”,发起方发起特定ID的远程帧,并且只发送ID部分,那么与其ID相符的终端设备就有义务在后半段的数据部分接管总线控 ...

  9. spring(三):ApplicationContext

  10. resize2fs: 报错

    报错如下 [root@localhost ~]# resize2fs /dev/mapper/centos-root resize2fs (-Dec-) resize2fs: Bad magic nu ...