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 = 26outlen == 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?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的redis源码之字符串压缩的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逻辑运算符''取某值
- 下一篇: linux可读可写为啥设置421