Transmission and storage of data on the network to optimize the performance of the optimization procedure (V)

Ali P7 mobile Internet architect, Advanced Video (Daily update) for free learning, please click: https://space.bilibili.com/474380680

This article will start with google protobuf to introduce network traffic and data storage optimization:

Brief introduction

protobuf also known as protocol buffer is a format for data exchange google, it is language-independent, platform-independent. google provides multiple-language realization: java, c #, c ++, go and python, every implementation contains a compiler and library files for the appropriate language. Because it is a binary format than XML, JSON exchange data much faster. It can be used for data exchange in the data communication between heterogeneous environments or distributed applications. As an excellent efficiency and compatibility are binary data transmission format may be used in many fields such as a network transmission, profile, data storage. protobuf in the realization of various rpc occupy an important role.

advantage

 good performance / high efficiency
 code generation mechanisms
 support "backward compatibility" and "forward compatible"
 support for multiple programming languages

Shortcoming

 application is not wide enough (compared to xml and json)
 binary format results in poor readability
 lack of self-description

installation

 github Address Source Codes: https://github.com/google/protobuf source packet src / README.md, detailed installation instructions, the installation process is as follows: 1, extracting archive: unzip protobuf-master.zip 2, the files are decompressed file folder: cd protobuf-master 3, tools required for installation: sudo apt-get install autoconf automake libtool curl make g ++ unzip 4, generated automatically configure profile: ./ autogen.sh 5, configure the environment: ./configure 6, compiling source code (long time): make 7, installation: sudo make install 8, refreshing dynamic library: sudo ldconfig

Compile .proto file

 protoc: protobuf own compilation tools, .proto file will generate the specified class
 -cpp_out: the generated C ++ code files into the directory specified by the equal sign, which also specify the current directory

Tools Compiler through protoc .proto file, the compiler generates code for the selected language, the code may be operable .proto message types defined in the file, including acquiring, setting the field value of the message sequence to an output stream, and parses a message from the input stream. For C ++, the compiler generates a file and a .h file for each .proto .cc files, file .proto each message has a corresponding class.

Compiled code

g++ *.cpp *.c *.cc `pkg-config --cflags --libs protobuf`

 backquote ( `): backticks role is to linux command in backtick execution
 pkg-config is to obtain all the necessary information repository through a .pc document library, including version information, compiling and linking needs the parameters.
 pkg-config -cflags protobuf: lists and pre-compile flags specify the shared library
 pkg-config -libs protobuf: Lists the specified shared library link flags

Message format defined in the file .proto

Formed by at least one message field combination, the structure is similar to the C language, each field has a certain format:

Field Name Data Type ID = unique tag values;

syntax = "proto3"; //指定版本信息,不指定会报错

message Person  //message为关键字,作用为定义一种消息类型
{
    string name = 1;    //姓名
    int32 id = 2;       //id
    string email = 3;   //邮件
}

type of data

 
19956127-4ae76d6e929bf33c.png
 

proto prototype file is a message protocol definition file in the file we can use descriptive language, to a well-defined data formats we need to use the program. By looking at the file header, you can be found in the following several functions substantially generated for each field are to name an example. As can be seen, for each field will generate a clear clear function (clear_name), set function (set_name), get function (name and mutable_name).

void clear_name();
void set_name(const ::std::string& value);
void set_name(const char* value);
void set_name(const char* value, size_t size);
const ::std::string& name() const;
::std::string* mutable_name();

Serialization and de-serialization of an array C

#include <iostream>
#include "person.pb.h"

using namespace std;

int main()
{
    char buf[1024];
    int len;

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    Person obj;
    obj.set_name("gongluck");
    obj.set_id(1);
    *obj.mutable_email() = "http://blog.csdn.net/gongluck93";
    len = obj.ByteSize();
    cout << "len = " << len << endl;
    obj.SerializeToArray(buf, len);

    Person obj2;
    obj2.ParseFromArray(buf, len);
    cout << "name = " << obj2.name() << endl;
    cout << "id = " << obj2.id() << endl;
    cout << "email = " << obj2.email() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

C ++ String serialization and de-serialization

#include <iostream>
#include "person.pb.h"

using namespace std;

int main()
{
    string str;

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    Person obj;
    obj.set_name("gongluck");
    obj.set_id(1);
    *obj.mutable_email() = "http://blog.csdn.net/gongluck93";
    obj.SerializeToString(&str);

    Person obj2;
    obj2.ParseFromString(str);
    cout << "name = " << obj2.name() << endl;
    cout << "id = " << obj2.id() << endl;
    cout << "email = " << obj2.email() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

File descriptor serialization and de-serialization

#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "person.pb.h"

using namespace std;

int main()
{
    int fd = open("./testFileDesc.xxx", O_CREAT|O_TRUNC|O_RDWR, 0664);

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    Person obj;
    obj.set_name("gongluck");
    obj.set_id(1);
    *obj.mutable_email() = "http://blog.csdn.net/gongluck93";
    obj.SerializeToFileDescriptor(fd);
    fsync(fd);
    lseek(fd, 0, SEEK_SET);

    Person obj2;
    obj2.ParseFromFileDescriptor(fd);
    cout << "name = " << obj2.name() << endl;
    cout << "id = " << obj2.id() << endl;
    cout << "email = " << obj2.email() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    return 0;
}

C ++ stream serialization and deserialization

#include <iostream>
#include <fstream>
#include "person.pb.h"

using namespace std;

int main()
{
    fstream file("testStream.xxx", ios::in|ios::out|ios::trunc|ios::binary);

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    Person obj;
    obj.set_name("gongluck");
    obj.set_id(1);
    *obj.mutable_email() = "http://blog.csdn.net/gongluck93";
    obj.SerializeToOstream(&file);
    file.flush();
    file.seekg(0, ios::beg);

    Person obj2;
    obj2.ParseFromIstream(&file);
    cout << "name = " << obj2.name() << endl;
    cout << "id = " << obj2.id() << endl;
    cout << "email = " << obj2.email() << endl;

    google::protobuf::ShutdownProtobufLibrary();

    file.close();

    return 0;
}

defining repeated modifier

repeated representative may be repeated, we can be understood as an array.

syntax = "proto3";

message Person
{
    string name = 1;
    int32 id = 2;
    string email = 3;
}

message AddressBook
{
    repeated Person people = 1;
}

For field generated field as a function of modifier repeated, the number of different slightly, such as people field, the compiler will generate the following code for:

int people_size() const;
void clear_people();
const ::Person& people(int index) const;
::Person* mutable_people(int index);
::Person* add_people();
::google::protobuf::RepeatedPtrField< ::Person >* mutable_people();
const ::google::protobuf::RepeatedPtrField< ::Person >& people() const;

example

#include <iostream>
#include <fstream>
#include "person.pb.h"

using namespace std;

int main()
{
    fstream file("testStream.xxx", ios::in|ios::out|ios::trunc|ios::binary);

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    AddressBook obj;

    Person* p1 = obj.add_people();
    p1->set_name("gongluck");
    p1->set_id(1);
    *(p1->mutable_email()) = "http://blog.csdn.net/gongluck93";

    Person* p2 = obj.add_people();
    p2->set_name("panzhikun");
    p2->set_id(2);
    *(p2->mutable_email()) = "[email protected]";

    obj.SerializeToOstream(&file);
    file.flush();
    file.seekg(0, ios::beg);

    AddressBook obj2;
    obj2.ParseFromIstream(&file);
    for(int i= 0; i< obj.people_size(); ++i)
    {
        Person per = obj2.people(i);
        cout << "name = " << per.name() << endl;
        cout << "id = " << per.id() << endl;
        cout << "email = " << per.email() << endl;
    }

    google::protobuf::ShutdownProtobufLibrary();

    file.close();

    return 0;
}

enumerate

syntax = "proto3";

message Person
{
    string name = 1;
    int32 id = 2;
    string email = 3;

    enum PhoneType
    {
        MOBLIE = 0;//首成员必须为0
        HOME = 1;
        WORK = 2;
    }
    message PhoneNumber
    {
        string number = 1;
        PhoneType type = 2;
    }
    repeated PhoneNumber phones = 4;
}

message AddressBook
{
    repeated Person people = 1;
}

·example

#include <iostream>
#include <fstream>
#include "person.pb.h"

using namespace std;

int main()
{
    fstream file("testStream.xxx", ios::in|ios::out|ios::trunc|ios::binary);

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    AddressBook obj;

    Person* p1 = obj.add_people();
    p1->set_name("gongluck");
    p1->set_id(1);
    *(p1->mutable_email()) = "http://blog.csdn.net/gongluck93";

    Person::PhoneNumber* phone1 = p1->add_phones();
    phone1->set_number("110");
    phone1->set_type(Person::MOBLIE);
    Person::PhoneNumber* phone2 = p1->add_phones();
    phone2->set_number("120");
    phone2->set_type(Person::WORK);

    obj.SerializeToOstream(&file);
    file.flush();
    file.seekg(0, ios::beg);

    AddressBook obj2;
    obj2.ParseFromIstream(&file);
    for(int i= 0; i< obj.people_size(); ++i)
    {
        Person per = obj2.people(i);
        cout << "name = " << per.name() << endl;
        cout << "id = " << per.id() << endl;
        cout << "email = " << per.email() << endl;
        for(int j=0; j< per.phones_size(); ++j)
        {
            Person::PhoneNumber phonenum= per.phones(j);
            switch(phonenum.type())
            {
            case Person::MOBLIE:
                cout << "mobile : " ;
                break;
            case Person::WORK:
                cout << "work : ";
                break;
            case Person::HOME:
                cout << "home : ";
                break;
            default:
                cout << "Not Know : ";
                break;
            }
            cout << phonenum.number() << endl;
        }
    }

    google::protobuf::ShutdownProtobufLibrary();

    file.close();

    return 0;
}

package

 .proto file to add an optional package declarator, to prevent different message types have naming conflicts. Packet specifier will affect the generated code in accordance with different use of language. For C ++, the class will be generated in the namespace packed in C ++.

syntax = "proto3";

package Test;//package

message Person
{
    string name = 1;
    int32 id = 2;
    string email = 3;

    enum PhoneType
    {
        MOBLIE = 0;//首成员必须为0
        HOME = 1;
        WORK = 2;
    }
    message PhoneNumber
    {
        string number = 1;
        PhoneType type = 2;
    }
    repeated PhoneNumber phones = 4;
}

message AddressBook
{
    repeated Person people = 1;
}

example

using namespace Test;
#include <iostream>
#include <fstream>
#include "person.pb.h"

using namespace std;
using namespace Test;

int main()
{
    fstream file("testStream.xxx", ios::in|ios::out|ios::trunc|ios::binary);

    GOOGLE_PROTOBUF_VERIFY_VERSION;

    AddressBook obj;

    Person* p1 = obj.add_people();
    p1->set_name("gongluck");
    p1->set_id(1);
    *(p1->mutable_email()) = "http://blog.csdn.net/gongluck93";

    Person::PhoneNumber* phone1 = p1->add_phones();
    phone1->set_number("110");
    phone1->set_type(Person::MOBLIE);
    Person::PhoneNumber* phone2 = p1->add_phones();
    phone2->set_number("120");
    phone2->set_type(Person::WORK);

    obj.SerializeToOstream(&file);
    file.flush();
    file.seekg(0, ios::beg);

    AddressBook obj2;
    obj2.ParseFromIstream(&file);
    for(int i= 0; i< obj.people_size(); ++i)
    {
        Person per = obj2.people(i);
        cout << "name = " << per.name() << endl;
        cout << "id = " << per.id() << endl;
        cout << "email = " << per.email() << endl;
        for(int j=0; j< per.phones_size(); ++j)
        {
            Person::PhoneNumber phonenum= per.phones(j);
            switch(phonenum.type())
            {
            case Person::MOBLIE:
                cout << "mobile : " ;
                break;
            case Person::WORK:
                cout << "work : ";
                break;
            case Person::HOME:
                cout << "home : ";
                break;
            default:
                cout << "Not Know : ";
                break;
            }
            cout << phonenum.number() << endl;
        }
    }

    google::protobuf::ShutdownProtobufLibrary();

    file.close();

    return 0;
}

Import Definitions

syntax = "proto3";//指定版本信息,不指定会报错

import "info.proto"; //导入定义

package tutorial; //package声明符

message Person //message为关键字,作用为定义一种消息类型
{
    string name = 1;    //姓名
    int32 id = 2;       //id
    string email = 3; //邮件

    enum PhoneType //枚举消息类型
    {
        MOBILE = 0; //proto3版本中,首成员必须为0,成员不应有相同的值
        HOME = 1;
        WORK = 2;
    }

    message PhoneNumber
    {
        string number = 1;
        PhoneType type = 2;
    }

    repeated PhoneNumber phones = 4; //phones为数组

    //info定义在"info.proto"
    //类型格式:包名.信息名
    infopack.info tmp = 5;
}

message AddressBook
{
    repeated Person people = 1;
}

Original link https://cloud.tencent.com/developer/article/1056432
Ali P7 mobile Internet architect, Advanced Video (Daily update) for free learning, please click: https://space.bilibili.com/474380680

Guess you like

Origin www.cnblogs.com/Android-Alvin/p/11958865.html