总体
原始fix消息
字段编码操作
fast消息模版和隐藏tag 消息
- 注意少一个tag为268,因为268表示的是个数
含有操作符的消息模版和字段编码消息
fast消息序列化
二进制连续为编码:
停止位编码实体
presence map(PMAP 存在图)
A presence map enables use of default values;Bit map which indicates the presence or absence of fields in the message. Fields which are null due to having been “copied away” can be represented by a bit in the presence map indicating that the field is absent.presence Map是一组bits位。模版中的各field根据操作符的不同,通过presence Map标识是否出现在fast数据流中。
public void testEncodeMessageWithSignedIntegerFieldTypesAndAllOperators() {
MessageTemplate template = new MessageTemplate("",
new Field[] {
new Scalar("1", Type.I32, Operator.COPY, ScalarValue.UNDEFINED, false),
new Scalar("2", Type.I32, Operator.DELTA, ScalarValue.UNDEFINED, false),
new Scalar("3", Type.I32, Operator.INCREMENT, new IntegerValue(10), false),
new Scalar("4", Type.I32, Operator.INCREMENT, ScalarValue.UNDEFINED, false),
new Scalar("5", Type.I32, Operator.CONSTANT, new IntegerValue(1), false), /* NON-TRANSFERRABLE */
new Scalar("6", Type.I32, Operator.DEFAULT, new IntegerValue(2), false),
new Scalar("7", Type.I32, Operator.CONSTANT, new IntegerValue(1), false),/* NON-TRANSFERRABLE */
new Scalar("8", Type.I32, Operator.CONSTANT, new IntegerValue(1), false),/* NON-TRANSFERRABLE */
new Scalar("9", Type.I32, Operator.COPY, ScalarValue.UNDEFINED, false)
});
Context context = new Context();
context.registerTemplate(113, template);
FastEncoder encoder = new FastEncoder(context);
Message message = new Message(template);
message.setInteger(1, 109);
message.setInteger(2, 29470);
message.setInteger(3, 10);
message.setInteger(4, 3);
message.setInteger(5, 1);
message.setInteger(6, 2);
message.setInteger(7, 1);
message.setInteger(8, 1);
message.setInteger(9, 2);
// --PMAP-- --TID--- --------#1------- ------------#2------------ ---#4--- ---#9----
String msg1 = "11101010 11110001 00000000 11101101 00000001 01100110 10011110 10000011 10000010";
TestUtil.assertBitVectorEquals(msg1, encoder.encode(message));
我们首先分析这9个field一共使用了多少个bit位,
(1)第1个field,强制的COPY,占用位;
(2)第2个field,强制的delta,不用占位;
(3)第3个field,强制的increment,占用位;
(4)第4个field,强制的field,占用1位;
(5)第5个field,强制的constant,不占位;
(6)强制的default,占用位;
(7)第7、8个field,强制的constant,不占位;
(8)第9个field,强制的copy,占用位。一共9个field,4个field不占位,所以用5个bit就可以标识,因此,Presence Map一个byte就足够标识。
分析encoding之后的二进制字符串。“11101010”去掉Stop bit,剩余1101010,1101010为模板存在标记,1101010为第一个field存在标记,1101010,第3个field的值不在fast数据流中,1101010,第4个field的值在数据流中,1101010,第6个field的值不在数据流中,1101010,第9个field的值在数据流中。
再分析PMAP之后的各数据,第一个为模板值,11110001去掉Stop bit为1110001=113;接着为第1个field的值,00000000 11101101 = 1101101 =109;接着为第2个field的值,00000001 01100110 10011110 = 29470,;接着为第4个field的值,10000011 = 3;接着为第9个field的值,10000010 = 2。
例子
在传输的过程:对于消息的压缩处理,主要采用pmap+field segment方式,其中:pmap标记了该消息中包含了那些字段,而field segment则是各自段具体的压缩数据。
压缩算法:
首先生成pmap,然后再加入数据。(pmap之后,通常增加了模版ID字段值,再加入其它定义的数据字段值)。
对于数据的压缩算法,采用了Stop bits encoding方式,每个字节的最高位,标志了消息中该字段是否结束(0标识没有结束,1标识结束,对于数据的存储,按照7bit进行划分)。
样例:
假设我们要对于58=HelloWorld进行FAST压缩,假设该消息对应的模版ID为1.
1.生成PMAP,压缩后的消息包含了两个字段,模版ID和58field对应的消息内容(helloworld);
可以用1个byte标志消息中出现的字段,110 0000,最高为置为1,标志结束;则第一个byte为1110 0000 = 0xE0;
2.下一个field为模版ID, ID为1, 000 0001,最高为置为1,标志结束;则第二个byte为1000 00001 = 0x81;
3.下一个字段为58field对应的消息,hello world,对应的16进制表示为:
H=0x48, e=0x65, l=0x6C, l=0x6C, o=0x6F, W=0x57, o=0x6F, r=0x72, l=0x6C, d=0x64.二进制为:
1001000 1100101 1101100 1101100 1101111 1010111 1101111 1110010 1101100 1100100。
此时,需要通过最高为置1标志字段数据的结束;即:
01001000 01100101 01101100 01101100 01101111 01010111 01101111 01110010 01101100 11100100
以上为基本的压缩方式。