Serialization Google协议缓冲区中的引用语义

Serialization Google协议缓冲区中的引用语义,serialization,protocol-buffers,Serialization,Protocol Buffers,我有一个稍微特殊的程序,它处理与此非常相似的案例 (在类似C#的伪代码中): 成员m_refData和m_refParent初始化为null,并按如下方式使用: m_refData->添加新数据集时使用 m_refParent->用于指向现有数据集。 仅当字段m_nID与现有数据集不匹配时,才会添加新数据集 目前,这段代码管理大约500个对象,每个对象大约有21个字段,目前选择的格式是XML,它的行数为100k+行,容量为5MB+非常笨拙 我计划修改整个shebang以使用ProtoBuf,但目

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

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

目前,这段代码管理大约500个对象,每个对象大约有21个字段,目前选择的格式是XML,它的行数为100k+行,容量为5MB+非常笨拙


我计划修改整个shebang以使用ProtoBuf,但目前我不确定如何处理引用语义。如果您有任何想法,我们将不胜感激。

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


然而,这是一个非常常见的场景-因此,作为一个实现特定的功能,我在我的实现(protobuf net)中添加了可选(opt-in)引用跟踪,它本质上是在幕后自动执行上述操作(因此您不需要更改对象或将密钥暴露在二进制流之外)。

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

然而,这是一个非常常见的场景——因此,作为一个特定于实现的功能,我在我的实现(protobuf net)中添加了可选(opt-in)引用跟踪,它本质上是在幕后自动执行上述操作(因此您不需要更改对象或将密钥暴露在二进制流之外)

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();
       }
  }
};