redis源码之字符串压缩

        redis关于字符串压缩的几个文件分别是:lzf.h,lzfP.h,lzf_c.c,lzf_d.c,下面看一个测试用例。

#include <iostream>
#include <string>
#include "lzfP.h"
#include "lzf.h"
using namespace std;

int main() 
{
	string value = "hello world hello world hello world hello world"; 
	size_t len = value.size();  // 字符串未压缩前的长度
	cout << "压缩前:val = " << value << endl;
	cout << "压缩前:len = " << len << endl << endl;

	// -------------------压缩---------------------------------
	size_t comprlen;  // 压缩后的长度
	size_t outlen;    // 输出缓存的最大长度
	unsigned char byte;
	int n, nwritten = 0;
	void *out;
	
	/* We require at least four bytes compression for this to be worth it */
	if (len <= 4) 
	{
		cout << "len <= 4" << endl;
		return 0;
	}
	
	outlen = len-3;
	
	if ((out = malloc(outlen+1)) == NULL) 
	{
		cout << "out = malloc(outlen+1)" << endl;
		return 0;
	}
	
	comprlen = lzf_compress(value.data(), len, out, outlen);  
	
	if (comprlen == 0) 
	{
		cout << "outlen == " << outlen << endl;
		cout << "comprlen == 0" << endl;
        		free(out);
        		return 0;
	}

	cout << "压缩后:val = " << out << endl;
	cout << "压缩后:len = " << comprlen << endl << endl;

	
	// -------------------解压缩---------------------------------
	char  *val = NULL;

   	 // 字符串空间
    	if ((val = (char*)malloc(len)) == NULL) 
	{
		cout << "lzf_decompress" << endl;
		return 0;
	}

   	 // 解压,得出字符串
   	 if (lzf_decompress(out, comprlen, val, len) == 0) 
	{
		cout << "lzf_decompress" << endl;
		return 0;
	}

	cout << "解压后:val = " << val << endl;
	cout << "解压后:len = " << len << endl;

   	 free(out);
	free(val);
	
	getchar();
	getchar();
	getchar();
	getchar();
   	return 0;
}

运行结果:

mapan@mapan-virtual-machine:~/c++/zifuc$ ./a.out 
压缩前:val = hello world hello world hello world hello world
压缩前:len = 47

压缩后:val = 0x55fd0a5322c0
压缩后:len = 20

解压后:val = hello world hello world hello world hello world
解压后:len = 47

压缩之后的长度变为20了,成功压缩。改变被压缩的字符再看。

如:string value = "qwertyuiopasdfghjklzxcvbnm"; 

mapan@mapan-virtual-machine:~/c++/zifuc$ ./a.out 
压缩前:val = qwertyuiopasdfghjklzxcvbnm
压缩前:len = 26

outlen == 23
comprlen == 0

未被压缩成功,表明压缩的结果不符合预期,所以直接返回失败了。压缩时,程序传入的长度时outlen = len-4;现在用同样的字符串,让outlen = len + 5;

mapan@mapan-virtual-machine:~/c++/zifuc$ ./a.out 
压缩前:val = qwertyuiopasdfghjklzxcvbnm
压缩前:len = 26

压缩后:val = 0x563f9561c2b0
压缩后:len = 27

解压后:val = qwertyuiopasdfghjklzxcvbnm
解压后:len = 26

现在压缩成功了,传入outlen,是out_data对应的大小,当压缩后的长度大于outlen,自然返回失败。

说到压缩字符串就会让人想到序列化,序列化也是一种压缩,方便跨平台传输数据,解决了对象引用的问题,如protobuff。下面看一个例子。

为什么要序列化详细见:https://blog.csdn.net/u010178308/article/details/80411848

msg.proto

package demo;
 
message msg
{
    required int32 msgtype=1;
    required string msginfo=2;
    required string msgfrom=3;
    optional string opt=4; //can select 
}

protobuff_demo.cc

代码地址:https://blog.csdn.net/kai8wei/article/details/62230878

#include"msg.pb.h"
#include<iostream>
#include<string>
using namespace std;
 
 
int main(int argc,char *argv[])
{
    demo::msg writer;
    writer.set_msgtype(1);   //设置数据
    writer.set_msginfo("i am weeks");//设置数据
    writer.set_msgfrom("127.0.0.1");//设置数据
 
     //C++string序列化和序列化API   
   
    //客户端格式化信息
    string in_data;
    writer.SerializeToString(&in_data);   //序列化
    //下面用一个临时的string 表示在网络中进行传输的过程
    //真是的过程中你可以借助相应的网络框架对数据进行传输
    //客户端将数据放到网络上   
    string tmp=in_data;
 
 
 
    //服务端从网络上拿数据 
    string out_data=tmp;
    //服务端反格式化信息
    demo::msg reader;
    reader.ParseFromString(out_data); //解序列化
    cout<<"msg_type: "<<reader.msgtype()<<endl;
    cout<<"msg_info: "<<reader.msginfo()<<endl;
    cout<<"msg_from: "<<reader.msgfrom()<<endl;
 
    return 0;
}

执行:protoc --cpp_out=. msg.proto   (会生成msg.pb.h)

           g++ protobuff_demo.cc msg.pb.cc -lprotobuf

运行可执行文件:

mapan@mapan-virtual-machine:~/c++/redis/proto$ ./a.out 
msg_type: 1
msg_info: i am weeks
msg_from: 127.0.0.1

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼盼编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值