第22篇 rabbitmq MethodArgumentReader(MethodArgumentWriter)源码分析

本文深入探讨AMQP协议中MethodArgumentReader和MethodArgumentWriter的作用,它们是对ValueReader和ValueWriter的封装,分别用于读写AMQP方法指令。文章详细分析了两者之间的异同,特别是在处理boolean属性时的位操作优化,以及在内存和流中的读写操作。此外,还介绍了如何利用位运算高效存储和读取多个boolean值,这一技巧在数据存储和过滤器如布隆过滤器中有广泛应用。

MethodArgumentReader和MethodArgumentWriter也是对于ValueReader和ValueWriter的封装,其实跟ContentHeaderPropertyReader和ContentHeaderPropertyWriter类似的,只是读写内容不同,ContentHeaderProperty是基础属性,而MethArgument读写AMQP的协议指令(Method具体实现),比如说队列声明,发布消息等,我们来具体看一下它与ContentHeaderPropertyWriter/Reader具体有什么异同

1、成员变量

变量名默认值描述
final ValueWriter out构造方法传入对象
boolean needBitFlushfalse写入Method布尔属性就true,否则就false
byte bitAccumulator0存Method的布尔值属性,二进位0或1刚好表示,有点类似flagWord
int bitMask1辅助bitAccumulator的bit设置

2、方法

方法名描述图示
MethodArgumentWriter(ValueWriter out)构造方法,重置成员变量
final void writeShortstr写short字符串
final void writeLongstr(LongString str)写入长的字符串
final void writeLongstr(String str)写入长的字符串
final void writeShort(int s)写入short
final void writeLong(int l)写入int值
final void writeLonglong(long ll)写入long值
final void writeBit(boolean b)写入boolean的位1
final void writeTable(Map<String, Object> table)写入map值
final void writeOctet(int octet)写入byte值
final void writeTimestamp(Date timestamp)写入时间戳
final void flush()这里就写入bit值(如果未写入的话)

2.1、图示

  1. writeBit(boolean b)
    • 一个byte位有8位,一个byte可以表示8个boolean值属性的值,如果大于8位之后就写下一个byte值
    • image-20210620123759365
    • 总结
      1. 判断当然byte的所有8位是否被占有的,如果被占有,当然需要当前bit写到流中,同时需要重置新的byte的需要初始化(从0开始新的byte)
      2. 如果传入值是true,说明需要将对应byte置为1,也通过进行或运算,同时你也会发现,说明提前把对应位置移动好的
      3. 向左移动一位bitMask,为下一次异或做准备
      4. 标记说这个bitAccumulator有意义boolean属性值存着,需要写入流中,同时你会发现,怎么没有写操作呢,如果没有触发1,那么就不会写入到流中吗?其实它的每个方法都有一个bitFlush()调用,同时在重写flush方法中也有bitFlush(),所有个写入值可能是在flush操作写入的, 具体你可以查看Method抽象类的toFrame方法

3、MethodArgumentReader 类

  • 与之MethodArgumentWriter的写类, MethodArgumentReader是读取MethodArgumentWriter写的数据,也就逆过程

3.1、成员变量

变量名默认值描述
final ValueReader in构造方法传入对象
int bits0读取存在boolean属性的byte值
int nextBitMask0x100辅助确定bits某个位置是1还0,二进制表示
1 0000 0000 [前置零省略了]

3.2、方法

方法名描述图示
MethodArgumentReader(ValueReader in)构造方法,重置成员变量
final String readShortstr()读short字符串
final LongString readLongstr()读入长的字符串
final int readShort()读入short值
final long readLonglong()读入long值
final int readLong()读入int值
final boolean readBit()读入boolean的位1
final void Map<String, Object> readTable()读入map值
final int readOctet()读入byte值
final Date readTimestamp()读入时间戳

3.3、图示

  1. boolean readBit()
    • image-20210620131048405
    • 总结
      1. 判断是否大于8位了,如果大于的话表示当前byte已经读取完了,需要读取下一个byte值,同时重置,继续从0开始(第一个位置)
      2. 进行二进制与运算,判断该位置是否为1,为1表示为true,否则为false
      3. 移动下一个位置(向左移动一位)

3、总结

异同点MethodArgumentReader(Writer)ContentHeaderPropertyReader(Writer)
1都是使用ValueWriter(Reader)都是使用ValueWriter(Reader)
2read/writeBit() 为表示boolean值flagWord进制位表示某个属性是否存在
3由于Method实现不同,属性不是固定属性是固定的,14个属性
4对于boolean特殊处理没有boolean值
  • 本质上是就是对于ValueWriter具体应用,也就是定义规则,由于ContentHeaderProperty属性是固定的,所有它是利用flagWord表示某个属性是否存在,

  • MethodArgument实现不是固定的,属性类型和数量都不一样呢,这个时候它只是为节省boolean值存在空间,利用byte值来存在,一个byte值最多可以存储8个boolean值属性。

  • 其实这个也是可以学习的定义,合理利用二进制的位来保存boolean值,其实应用比较广泛就是redis的布隆过滤器呢。

  • 希望能对您有所帮助和启发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值