【问题标题】:C++ - Map-like data structure with structural sharing/immutabilityC++ - 具有结构共享/不变性的类似地图的数据结构
【发布时间】:2013-02-03 18:33:31
【问题描述】:

函数式编程语言通常处理不可变的数据结构,但通过结构共享保持高效。例如。您在一些信息地图上工作,如果您插入一个元素,您将不会修改现有地图,而是创建一个新的更新版本。为避免大量复制和内存使用,地图将在两个实例之间共享(尽可能好)未更改的数据。

如果有一些模板库为 C++ 提供类似地图的数据结构,我会很感兴趣。我搜索了一下,除了 LLVM 中的内部类之外什么也没找到。

【问题讨论】:

  • 不太明白你的最后一行:“为了避免大量复制和内存使用,地图将在两个实例之间共享(尽可能好)未更改的数据。”这意味着结构本身是可变的,它只会随着新的添加/修改而改变,但整个内存占用(包括起始地址)保持不变。可变变量就是这种情况。是不是你想要可变数据结构?
  • @NiravBhatt:不,他的意思是不可变的数据结构。
  • @Cullman:不知道你是否能找到,但这样的结构相对容易构建。给定您现有的任何结构,当提出“更改”时,只需为必须更改的部分构建新结构,并使用指向可以保留的结构的旧部分的指针。
  • 您在 LLVM 中发现的那些内部类有什么问题?在通用库中,我还没有遇到过这样的不可变容器,其他几种有用的容器类型也很少见(例如 trie 很少见,甚至像 ring-buffer 这样普通的东西)。
  • 我不知道 C++ 中的任何现有实现,但如果你没有遇到过这个,Hash Array Mapped Trie 上的维基百科文章提到了几个实现,并链接到 Clojure 实现它是用相当独立的 Java 编写的(不短但易于处理且经过实战测试)。可以作为一个起点。

标签: c++ data-structures


【解决方案1】:

A Copy On Write b+tree 听起来像您要找的东西。它基本上每次被修改时都会创建一个自己的新快照,但它在版本之间共享未修改的叶节点。我见过的大多数实现都倾向于只添加到数据库日志文件中。 CouchDB 有一篇非常好的文章。然而,就地图数据结构而言,它们“相对容易”实现。

【讨论】:

  • 这是一个很好的提示!实际上,即使易于实现,我也会倾向于一些已经经过良好测试和实践证明的变体,以避免大量的自己测试。
  • Copy-On-Write B-Tree 被 Stratified B-Tree slideshare.net/acunu/20110620-stratifiedbtree击败
【解决方案2】:

您可以使用普通地图,但用时间戳或“地图版本号”标记每个元素。如果您也想删除元素,请使用两个标记。如果您可能重新插入已删除的元素,那么您需要一个值列表和每个元素的标记对。

例如,您搜索键“foo”,您发现它在版本 0 到 3(包括)中的值为 5,然后它被“删除”,然后在版本中它的值为 -8 9 到当前。

不过,这会占用大量内存和时间。

【讨论】:

  • 实际上,正如你提到的那样,这对我没有多大帮助,因为它会消除我想要的好处,空间+时间效率。
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
相关资源
最近更新 更多