【发布时间】:2016-05-11 10:13:25
【问题描述】:
首先:我不是 protobuf 方面的专家。
假设我有这样的消息结构:
package msg_RepAndOpt;
message RepAndOpt
{
repeated string name = 1;
optional string surname = 2;
...
// there are lots of others.
}
我有两个组件包含此消息的副本:
// component1:
RepAndOpt A;
A.add_name("Name");
A.set_surname("Surname");
// component2:
RepAndOpt B;
在我的例子中,组件通过事务机制修改这些消息。这意味着如果一个组件更改了某个字段,它也会将其发送到另一个组件以传播这些更改。组件接收器正在合并:
// Component2 modifies B and sends it to component1.
// Component1 perfoms merge:
A.MergeFrom(B);
现在,比如说,component2 想要删除字段“name”。 如果它将发送清除 B 消息(默认构造),则:
- MergeFrom() 不会修改 A;
- CopyFrom() 也会删除其他字段。
另一种方法是用 A 的内容填充 B,清除名称字段,组件 1 将使用 CopyFrom()。 但这是不可接受的,因为系统负载非常高,可能还有很多其他领域。 因此,清理名称字段所需的解决方案是:
- Component2 创建 B 消息。
- 明确存储它只想擦除名称字段的信息。
- Component1 执行 A.MergeFrom(B)。
- 结果:A::name 已清除,但其他字段保持不变。
据我测试,这适用于重复和可选字段。 是否有任何现成的解决方案或者我应该修改 protobuf 实现?
【问题讨论】:
-
如何将
B.name设置为某个特殊值(“DELETE_ME”),进行正常合并,然后扫描所有字段并删除那些值为特殊值的字段? -
是的。这是一个可能的解决方案。好消息是它不需要更改 protobuf 实现。但我也应该为其他类型选择这样的特殊值,例如 int32。这里更难。这将是一个大开关,检测字段的类型,然后与特殊值进行比较。
-
是的,对于您希望支持的每种类型,您都需要一个这样的值。重载应该提供一种简单的编程方式。
标签: c++ protocol-buffers