Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Map structure using Google Protobuf

Now I'm using Google protobuf and I want to make use of Map structure. However I find out there is no such data structure implemented in Google protobuf.

My problem is very straightforward. I have a structure with a 'Page Number(uint32_t)' and a very simple content. What I want is use this Page Number as key and the content as value. This should satisfy both the space and speed requirement. However there is no such data structure in Protobuf.

The method I use is like this:

message MyPageContent {
    required uint32 contentA = 1;
    required uint32 contentB = 2;
}

message MyTable {
    repeated MyPageContent table= 1;
}

The total number of pages is known. So at the beginning of my program I add all the pagecontent to the table with some special value(This value is used to notify the page is not there, noone should use the content.) In this way, I could implicitly use the page number to index. When a page is ready, I will change the corresponding value in the table. People directly use the page number as index to access the content. This method spends a lot of space(A lot of page is not ready and I just put some special value there to let people know its not ready.) but the accessing time is fast.

An alternative method to do something like this:

message MyTable {
    repeated uint32 pageNum = 1;
    repeated MyPageContent myContent = 2;
}

In this way, I can add a page to the table when it's ready. The size of the table should be limited in this way. However, people have to first do a linear search to find if the page is in the table. This will consume a lot of time.

Basically this is why I want to use the Map structure in protobuf. It saves both space and time.

like image 523
Shanpei Zhou Avatar asked Nov 14 '14 22:11

Shanpei Zhou


2 Answers

I'm not sure when this change happened, but currently (April '15) ProtoBuf supports maps:

If you want to create an associative map as part of your data definition, protocol buffers provides a handy shortcut syntax:

map<key_type, value_type> map_field = N;

...where the key_type can be any integral or string type (so, any scalar type except for floating point types and bytes). The value_type can be any type.

So, for example, if you wanted to create a map of projects where each Project message is associated with a string key, you could define it like this:

map<string, Project> projects = 3;

like image 197
Mike Gebirge Avatar answered Sep 22 '22 05:09

Mike Gebirge


No way, (un)fortunately.

Protobuf is not a library for manipulating data, it's a library for serialization. So you manipulate your data in std::map or whatever container, and serialize it using repeated fields in protobuf.

like image 41
Anton Savin Avatar answered Sep 20 '22 05:09

Anton Savin