public class UnpooledDirectByteBuf extends AbstractReferenceCountedByteBuf {

    private final ByteBufAllocator alloc;
//jdk ByteBuffer管理直接内存
private ByteBuffer buffer;
private int capacity;
@Override
public boolean hasArray() {
return false;
}
@Override
public int nioBufferCount() {
return 1;
} //设置ByteBuffer,替换的话释放ByteBuffer
private void setByteBuffer(ByteBuffer buffer) {
ByteBuffer oldBuffer = this.buffer;
if (oldBuffer != null) {
if (doNotFree) {
doNotFree = false;
} else {
//freeDirect(oldBuffer);
//调用PlatformDependent工具处理
PlatformDependent.freeDirectBuffer(buffer);
}
} this.buffer = buffer;
tmpNioBuf = null;
capacity = buffer.remaining();
}
@Override
public ByteBuf capacity(int newCapacity) {
ensureAccessible();
if (newCapacity < 0 || newCapacity > maxCapacity()) {
throw new IllegalArgumentException("newCapacity: " + newCapacity);
} int readerIndex = readerIndex();
int writerIndex = writerIndex(); int oldCapacity = capacity;
//扩容处理
if (newCapacity > oldCapacity) {
ByteBuffer oldBuffer = buffer;
ByteBuffer newBuffer = allocateDirect(newCapacity);
//将整个oldBuffer复制到newBuffer
oldBuffer.position(0).limit(oldBuffer.capacity());
newBuffer.position(0).limit(oldBuffer.capacity());
newBuffer.put(oldBuffer);
//clear是重置容器坐标,不是清理数据
newBuffer.clear();
setByteBuffer(newBuffer);
} else if (newCapacity < oldCapacity) {
//缩容处理跟heap一样
ByteBuffer oldBuffer = buffer;
ByteBuffer newBuffer = allocateDirect(newCapacity);
if (readerIndex < newCapacity) {
if (writerIndex > newCapacity) {
writerIndex(writerIndex = newCapacity);
}
oldBuffer.position(readerIndex).limit(writerIndex);
newBuffer.position(readerIndex).limit(writerIndex);
newBuffer.put(oldBuffer);
newBuffer.clear();
} else {
setIndex(newCapacity, newCapacity);
}
setByteBuffer(newBuffer);
}
return this;
} @Override
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
checkSrcIndex(index, length, srcIndex, src.capacity());
if (src.nioBufferCount() > 0) {
for (ByteBuffer bb: src.nioBuffers(srcIndex, length)) {
int bbLen = bb.remaining();
setBytes(index, bb);
index += bbLen;
}
} else {
src.getBytes(srcIndex, this, index, length);
}
return this;
} @Override
public ByteBuf setBytes(int index, ByteBuffer src) {
ensureAccessible();
ByteBuffer tmpBuf = internalNioBuffer();
if (src == tmpBuf) {
src = src.duplicate();
}
//tmpBuf 是指向 this.buffer 通过put(src)api指加src里的内容
//指加之前要设置position开始坐标同结束边界limit
tmpBuf.clear().position(index).limit(index + src.remaining());
tmpBuf.put(src);
return this;
} @Override
public ByteBuffer nioBuffer(int index, int length) {
checkIndex(index, length);
//duplicate 是创建一个共享的ByteBuffer,slice也是创建共享,只不过是bufferr其中一部分
//创建新的ByteBuffer区别是内部坐标记录指向新的ByteBuffer对象,内容是共享的
return ((ByteBuffer) buffer.duplicate().position(index).limit(index + length)).slice();
} //处理逻辑跟setBytes(int index, ByteBuf src, int srcIndex, int length) 一样,对换src dst即可
@Override
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
checkDstIndex(index, length, dstIndex, dst.capacity());
if (dst.hasArray()) {
getBytes(index, dst.array(), dst.arrayOffset() + dstIndex, length);
} else if (dst.nioBufferCount() > 0) {
for (ByteBuffer bb: dst.nioBuffers(dstIndex, length)) {
int bbLen = bb.remaining();
getBytes(index, bb);
index += bbLen;
}
} else {
dst.setBytes(dstIndex, this, index, length);
}
return this;
}
@Override
public ByteBuf getBytes(int index, ByteBuffer dst) {
getBytes(index, dst, false);
return this;
}
//处理逻辑跟setBytes(int index, ByteBuffer src) 一样,对换src dst即可
private void getBytes(int index, ByteBuffer dst, boolean internal) {
checkIndex(index, dst.remaining()); ByteBuffer tmpBuf;
if (internal) {
tmpBuf = internalNioBuffer();
} else {
tmpBuf = buffer.duplicate();
} tmpBuf.clear().position(index).limit(index + dst.remaining());
dst.put(tmpBuf);
}
}

小结:

  1.setBytes getBtyes逻辑基本是相同,只需要对换src dst

  2.当判断是否src.nioBufferCount() 分支时其实写死也行,只不过为以后兼容其它类型ByteBuf

[编织消息框架][netty源码分析]12 ByteBuf 实现类UnpooledDirectByteBuf职责与实现的更多相关文章

  1. [编织消息框架][netty源码分析]11 ByteBuf 实现类UnpooledHeapByteBuf职责与实现

    每种ByteBuf都有相应的分配器ByteBufAllocator,类似工厂模式.我们先学习UnpooledHeapByteBuf与其对应的分配器UnpooledByteBufAllocator 如何 ...

  2. [编织消息框架][netty源码分析]13 ByteBuf 实现类CompositeByteBuf职责与实现

    public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable<ByteBuf ...

  3. [编织消息框架][netty源码分析]6 ChannelPipeline 实现类DefaultChannelPipeline职责与实现

    ChannelPipeline 负责channel数据进出处理,如数据编解码等.采用拦截思想设计,经过A handler处理后接着交给next handler ChannelPipeline 并不是直 ...

  4. [编织消息框架][netty源码分析]4 eventLoop 实现类NioEventLoop职责与实现

    NioEventLoop 是jdk nio多路处理实现同修复jdk nio的bug 1.NioEventLoop继承SingleThreadEventLoop 重用单线程处理 2.NioEventLo ...

  5. [编织消息框架][netty源码分析]5 eventLoop 实现类NioEventLoopGroup职责与实现

    分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...

  6. [编织消息框架][netty源码分析]8 Channel 实现类NioSocketChannel职责与实现

    Unsafe是托委访问socket,那么Channel是直接提供给开发者使用的 Channel 主要有两个实现 NioServerSocketChannel同NioSocketChannel 致于其它 ...

  7. [编织消息框架][netty源码分析]9 Promise 实现类DefaultPromise职责与实现

    netty Future是基于jdk Future扩展,以监听完成任务触发执行Promise是对Future修改任务数据DefaultPromise是重要的模板类,其它不同类型实现基本是一层简单的包装 ...

  8. [编织消息框架][netty源码分析]5 EventLoopGroup 实现类NioEventLoopGroup职责与实现

    分析NioEventLoopGroup最主有两个疑问 1.next work如何分配NioEventLoop 2.boss group 与child group 是如何协作运行的 从EventLoop ...

  9. [编织消息框架][netty源码分析]7 Unsafe 实现类NioSocketChannelUnsafe职责与实现

    Unsafe 是channel的内部接口,从书写跟命名上看是不公开给开发者使用的,直到最后实现NioSocketChannelUnsafe也没有公开出去 public interface Channe ...

随机推荐

  1. 自己动手实现mybatis动态sql

    发现要坚持写博客真的是一件很困难的事情,各种原因都会导致顾不上博客.本来打算写自己动手实现orm,看看时间,还是先实现一个动态sql,下次有时间再补上orm完整的实现吧. 用过mybatis的人,估计 ...

  2. UWP 五星好评

    var pfn = Package.Current.Id.FamilyName; await Launcher.LaunchUriAsync(new Uri("ms-windows-stor ...

  3. PHP获取一周的日期

    /** * 获取一周日期 * @param $time 时间戳 * @param $format 转换格式 */ function get_week($time, $format = "Y- ...

  4. 直播一:H.264编码基础知识详解

    一.编码基础概念 1.为什么要进行视频编码? 视频是由一帧帧图像组成,就如常见的gif图片,如果打开一张gif图片,可以发现里面是由很多张图片组成.一般视频为了不让观众感觉到卡顿,一秒钟至少需要16帧 ...

  5. Foxmail 7.0破解版,拷贝到新机器后,发送邮件乱码问题

    申请了新机器,挺开心,键盘和鼠标也好用了,但是新机器也随之而来一些不便,以前存储的数据需要重新拷贝.还有一些邮件,有些邮件标记了*号. Foxmail7.0绿色版本还挺好用,直接拷贝到新机器上就能直接 ...

  6. Nginx 反向代理 负载均衡 虚拟主机配置

    Nginx 反向代理 负载均衡 虚拟主机配置 通过本章你将学会利用Nginx配置多台虚拟主机,清楚代理服务器的作用,区分正向代理和反向代理的区别,搭建使用Nginx反向搭理和负载均衡,了解Nginx常 ...

  7. java 可变參数

    我们在某些特定的需求环境下,可能要对某一个方法中的參数进行一些操作,并且这些方法中的參数是不规定的,那么问题来了,我们该怎么办呢? java事实上就为我们考虑了这样的情况,那就是使用可变參数 可变參数 ...

  8. iWeb峰会(HTML5峰会)2015年7月19日上海站会后感想

         上周日专门从南京跑到上海參加了iWeb峰会(HTML5峰会),感觉这一天去的挺值的.几个演讲都挺精彩,干货不少啊.       总体感觉随着2014年HTML5标准的终于定稿,最近HTML5 ...

  9. Android的init过程:init.rc解析流程

    这几天打算看下安卓的代码,看优秀的源代码也是一种学习过程,看源代码的过程就感觉到,安卓确实是深受linux内核的影响,不少数据结构的使用方法全然一致.花了一中午时间,研究了下init.rc解析过程,做 ...

  10. Java Annotation认知(包括框架图、详细介绍、示例说明)(转)

    本文转自:http://www.cnblogs.com/skywang12345/p/3344137.html 网上很多关于Java Annotation的文章,看得人眼花缭乱.Java Annota ...