迭代器模式使用很多,但是被我们经常忽略它居然也是一种模式。
1、有一个迭代器接口。
2、对容器里面各个对象进行访问。
netty里面的CompositeByteBuf这个零拷贝的实现,就使用了迭代器模式。首先看一段代码:
public static void main(String[] args) {
ByteBuf header = Unpooled.wrappedBuffer(new byte[]{1, 2, 3});
ByteBuf body = Unpooled.wrappedBuffer(new byte[]{4, 5, 6});
ByteBuf merge = merge(header, body);
merge.forEachByte(value -> {
System.out.println(value);
return true;
});
}
public static ByteBuf merge(ByteBuf header, ByteBuf body) {
CompositeByteBuf byteBuf = ByteBufAllocator.DEFAULT.compositeBuffer(2);
byteBuf.addComponent(true, header);
byteBuf.addComponent(true, body);
return byteBuf;
}
这段代码是把两个ByteBuf添加到一起,forEachByte就是实现了迭代器模式。那么怎么说它是零拷贝呢?
找forEachByte的实现,在AbstractByteBuf里面。
有这样一段代码:
@Override
public int forEachByte(ByteProcessor processor) {
ensureAccessible();
try {
return forEachByteAsc0(readerIndex, writerIndex, processor);
} catch (Exception e) {
PlatformDependent.throwException(e);
return -1;
}
}
从readerIndex开始读,读到writeIndex。继续点进去查看:
private int forEachByteAsc0(int start, int end, ByteProcessor processor) throws Exception {
for (; start < end; ++start) {
if (!processor.process(_getByte(start))) {
return start;
}
}
return -1;
}
查看_getByte的实现,当然是找CompositeByteBuf的实现了:
@Override
protected byte _getByte(int index) {
Component c = findComponent(index);
return c.buf.getByte(index - c.offset);
}
先找出是哪个componet,然后迭代的时候其实是直接返回这个componet的byte内容就可以,这样就实现了零拷贝。别的类迭代的话,可能会把所有的数据都复制一遍。