【问题标题】:How to implement Map structure using Google Protobuf如何使用 Google Protobuf 实现 Map 结构
【发布时间】:2014-11-14 22:22:55
【问题描述】:

现在我正在使用 Google protobuf,我想使用 Map 结构。但是我发现 Google protobuf 中没有实现这样的数据结构。

我的问题很简单。我有一个带有“页码(uint32_t)”和一个非常简单的内容的结构。我想要的是使用这个页码作为键和内容作为值。这应该同时满足空间和速度要求。但是在 Protobuf 中没有这样的数据结构。

我使用的方法是这样的:

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

message MyTable {
    repeated MyPageContent table= 1;
}

总页数已知。所以在我的程序开始时,我将所有页面内容添加到具有一些特殊值的表中(该值用于通知页面不存在,没有人应该使用内容。)这样,我可以隐式使用页码索引。当一个页面准备好时,我会更改表中的相应值。人们直接使用页码作为索引来访问内容。这种方法占用空间很大(很多页面还没有准备好,我只是放了一些特殊的值让人们知道它还没有准备好。)但是访问时间很快。

另一种方法来做这样的事情:

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

通过这种方式,我可以在表格准备好时将页面添加到表格中。应该以这种方式限制表的大小。但是,人们必须首先进行线性搜索以查找该页面是否在表格中。这会消耗很多时间。

基本上这就是我想在 protobuf 中使用 Map 结构的原因。既节省空间又节省时间。

【问题讨论】:

    标签: c++ map protocol-buffers


    【解决方案1】:

    我不确定此更改何时发生,但目前(2015 年 4 月)ProtoBuf supports maps

    如果您想创建关联映射作为数据定义的一部分,protocol buffers 提供了一种方便的快捷语法:

    map<key_type, value_type> map_field = N;

    ...其中key_type 可以是任何整数或字符串类型(因此,除浮点类型和bytes 之外的任何标量类型)。 value_type 可以是任何类型。

    因此,例如,如果您想创建一个项目地图,其中每个 Project 消息都与一个 string 键相关联,您可以这样定义它:

    map<string, Project> projects = 3;

    【讨论】:

    • 不幸的是,它似乎不起作用,看起来文档是唯一受支持的地方。协议编译器不会接受它。
    • "协议编译器不接受它。"听起来你只是安装了一个旧的协议。你确定你有最新版本,并且那个版本支持 ProtoBufV3?
    • 如何使用 C++ 填充地图?
    • @Marco 这是文档的一个令人困惑的方面。在文档的所有部分中,Proto2 都不是 protobuf v2.x.x。 protobuf v3.x.x 在 proto2/proto3 语法中原生支持映射。
    • “混淆”是这里的关键词 :) 谢谢@PradeepGollakota 的澄清!
    【解决方案2】:

    没办法,(不)幸运。

    Protobuf 不是用于操作数据的库,它是用于序列化的库。因此,您在 std::map 或任何容器中操作数据,并使用 protobuf 中的 repeated 字段对其进行序列化。

    【讨论】:

    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    相关资源
    最近更新 更多