【问题标题】:Add content of a vector into a Capnproto map object将向量的内容添加到 Capnproto 地图对象中
【发布时间】:2019-08-15 21:38:12
【问题描述】:

正如this question 中的回答:

请注意,Cap'n Proto 结构中的单个 List 值限制为 2^29-1 个元素

由于单个列表的限制,我试图将包含超过此数量的项目的列表拆分为列表映射。为此,我使用以下架构:

struct Map64UInt{
    entries @0: List(Entry);
    struct Entry{
        key @0: UInt64;
        value @1: List(UInt64);
    }
}

我一直在研究 Cap'n Proto 的所有示例,但我找不到一个包含有关如何创建并将项目添加到 Capn'Proto 列表中的示例,然后将此列表添加到 Cap' n 原型图。例如,考虑以下代码:

void addVecToCapnprotoMap(std::vector<uint64_t> &v){
    unsigned int key = 0;
    //Here: how do I create a Capn' Proto List of uint64_t
    //and add it to a Capn Proto map that follows the schema
    //described above?
}

【问题讨论】:

    标签: c++ capnproto


    【解决方案1】:

    很遗憾,您不能动态地将新元素添加到列表中;您必须在首次创建列表时指定列表的完整大小。这是 Cap'n Proto 零拷贝特性的副作用。由于列表直接就地分配到最终消息缓冲区中,因此以后无法调整大小。

    您可以做的是单独维护一个地图,然后将最终列表作为最后一步编写,例如:

    // WARNING: Not tested, probably has typos.
    class MapHelper {
    public:
      MapHelper(Map64UInt::Builder finalBuilder)
          : finalBuilder(finalBuilder),
            orphanage(capnp::Orphanage::getForMessageContaining(finalBuilder)) {}
    
      void add(uint64_t key, const std::vector<unit64_t>& v) {
        auto orphan = orphanage.newOrphan<capnp::List<uint64_t>>(v.size());
        auto listBuilder = orphan.get();
        for (size_t i = 0; i < v.size(); i++) {
          listBuilder[i] = v[i];
        }
        contents.insert(std::make_pair(key, kj::mv(orphan)));
      }
    
      void finish() {
        // Write all entries to the final map.
        auto entriesBuilder = finalBuilder.initEntries(contents.size());
        size_t i = 0;
        for (auto& entry: contents) {
          auto entryBuilder = entriesBuilder[i];
          entryBuilder.setKey(entry.first);
          entryBuilder.adoptValue(kj::mv(entry.second));
          ++i;
        }
      }
    
    private:
      Map64UInt::Builder finalBuilder;
      capnp::Orphanage orphanage;
      std::map<uint64_t, capnp::Orphan<capnp::List<uint64_t>>> contents;
    };
    

    【讨论】:

    • 非常感谢肯顿。我更正了您答案中的一些错别字!此外,我使用的大部分内容都与orphan 对象有关。如果在 git 页面上有一些使用它的示例会很好,你不觉得吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多