mangos中大量使用了64位的ID,优化之一对ID的压缩,以减少消息发送量。
ID中存储了各种OBJECT的信息,分别存储在64位的固定位上。
因此在各个字节上大部分的情况都含有0,由此来压缩0的位置,压缩后的数据分为两部分,一个字节表示哪些位,另外部分表示非0数据。
压缩和解压实现如下:
#include <stdio.h>
typedef unsigned char uint8;
typedef unsigned long long uint64;
int deflate(uint64 id, uint8* stream )
{
uint8& mask = stream[0]; //第一个字节mask表示后续哪些字节后内容
mask = 0;
int length = 1;
for (uint8 i = 0; id != 0; ++i)
{
if (id & 0xFF)
{
mask |= uint8(1 << i);
stream[length++] = uint8(id & 0xFF); //取出uint64中非0字节依次存储
}
id >>= 8;
}
return length;//压缩后的长度
}
uint64 inflate( uint8* stream )
{
uint64 id = 0;
uint8 mask = stream[0]; //数据mask
uint8 next = 1;
for ( int i = 0; i < 8; ++i )
{
if ( mask & (1 << i) )
{
id |= ( uint64(stream[next++]) << (i*8));
}
}
return id;
}
从这种实现来看,在最坏的情况下压缩后反而会增加一个字节,变成9字节,最好的情况下只会占用1个字节。
在实际项目中的情况中,ID中一般都会有2-3个0的情况,所以在大部分情况下,能够有压缩作用。
所以这种压缩并不适用于所有的情况,在特定条件下,也许会适得其反。
P.S.
在网上看到另外一篇文章页是关于GUID压缩的。
http://www.cnblogs.com/zjfree/archive/2011/11/28/2266242.html
这里的压缩方式是针对字符串化来压缩的,一个GUID拆分为两个uint64,采用36进制来表示该数字,表示出来的字符串会大大减少,但是对于内存压缩来说没有作用,
严格来说,这种不是压缩,只是一个数字用不同的进制来表示,更准确的说法应该如何用更短的字符串来表示一个数字。如果使用更高的进位将或得到更短的字符串。