Google Protocol Buffers中的参考语义

时间:2011-05-19 06:32:12

标签: serialization protocol-buffers

我有一个稍微奇怪的程序,处理与此非常相似的案件 (在C#中类似伪代码):

class CDataSet
{
   int m_nID;
   string m_sTag;
   float m_fValue;
   void PrintData()
   {
      //Blah Blah
   }
};

class CDataItem
{
  int m_nID;
  string m_sTag;
  CDataSet m_refData;
  CDataSet m_refParent;
  void Print()
  {
      if(null == m_refData)
       {
         m_refParent.PrintData();
       }
     else
       {
         m_refData.PrintData();
       }
  }
};

成员m_refData和m_refParent初始化为null并按如下方式使用: m_refData - >添加新数据集时使用 m_refParent - >用于指向现有数据集。 仅当字段m_nID与现有字段不匹配时,才会添加新数据集。

目前,此代码管理着大约500个对象,每个对象大约有21个字段,截至目前的选择格式是XML,其中100k +行和5MB +非常难以处理。

我打算修改整个shebang以使用ProtoBuf,但目前我不确定如何处理引用语义。任何想法都将不胜感激

1 个答案:

答案 0 :(得分:1)

开箱即用,协议缓冲区没有任何引用语义。您需要手动交叉引用它们,通常使用人工密钥。基本上在DTO层上你可以获得CDataSet的密钥(你只是发明,也许只是一个增加的整数),在m_refData / m_refParent中存储密钥而不是项目,并在序列化/反序列化期间手动运行fixup。您也可以将索引存储到CDataSet集中,但这可能会使插入等更加困难。由你决定;因为这是序列化,你可能会争辩说你不会在初始种群之外插入(等),因此原始索引是好的和可靠的。

然而,这是一个非常常见的情况 - 因此作为特定于实现的功能,我在我的实现(protobuf-net)中添加了可选(选择加入)参考跟踪,这实际上是自动化上面的内容(所以你不需要改变你的对象或在二进制流之外公开密钥。)