Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 纯功能(持久)环形缓冲区_Haskell_Data Structures_Clojure_Ocaml_Purely Functional - Fatal编程技术网

Haskell 纯功能(持久)环形缓冲区

Haskell 纯功能(持久)环形缓冲区,haskell,data-structures,clojure,ocaml,purely-functional,Haskell,Data Structures,Clojure,Ocaml,Purely Functional,我想通过以下操作使用纯功能数据结构实现一个环形缓冲区 基于索引的高效随机存取 加在前面 后撤 使用持久数据结构的原因是,我有一个writer线程和几个reader线程,我希望避免readers阻塞writer 通过让读卡器线程在拍摄快照时只持有锁,然后使用快照进行处理,可以很容易地做到这一点 支持这些操作的现有可用数据结构是什么 双链表不能有效地进行索引查找,并且是O(n) Clojure PersistentVector基于Phil Bagwell理想哈希树,支持log32N中的索引访问

我想通过以下操作使用纯功能数据结构实现一个环形缓冲区

  • 基于索引的高效随机存取
  • 加在前面
  • 后撤
使用持久数据结构的原因是,我有一个writer线程和几个reader线程,我希望避免readers阻塞writer

通过让读卡器线程在拍摄快照时只持有锁,然后使用快照进行处理,可以很容易地做到这一点

支持这些操作的现有可用数据结构是什么

  • 双链表不能有效地进行索引查找,并且是O(n)
  • Clojure PersistentVector基于Phil Bagwell理想哈希树,支持log32N中的索引访问,可以使用subvec从一开始就删除元素
  • 哈希数组映射的trie也可以通过将整数存储为键来使用,但可能不是超高效的

在这种情况下,还可以使用哪些纯功能数据结构?

标准库中的(as)是持久随机访问序列的目标。我认为它符合您的标准–随机访问索引是O(logn)(更具体地说,索引到边缘的距离的对数),其他的是O(1)。我不知道有哪种持久化数据结构比这更好。

您能描述一下这个用例吗?听起来你的目标是矛盾的,读者还是要阻止作者;您不能冒写更新在读取期间使索引无效的风险。或者更准确地说,现有的读取会阻止写入程序,但读取请求不能抢占挂起的写入请求,以避免饥饿。切普纳:该对象是不可变的,永远不会就地更新。编写器无法修改它,只能创建与旧版本共享某些对象的新版本。读写器将在更新指向最新版本的指针时锁定。拍摄快照后,不需要锁定即可使用快照。为什么需要随机访问?如果没有它,您可以只使用其中的一个。非常感谢luqui,那么finger tree比clojure PersistentVector好吗?稍微阅读一下,clojure PersistentVector似乎只是32叉树。手指树将更好地推动和弹出在两端;随机访问应该是可比较的。@skyde,
数据中的手指树。序列
具有相当糟糕的常数因子。你最好吃一点(小的)对数成本,以换取从一棵茂密的树上更好的随机访问。当然,这一切都取决于你的使用模式。@D你能澄清一下你说数据是什么意思吗?序列有相当糟糕的常数因子。您的意思是,与32元树相比,随机访问速度会慢吗?Clojure persisten vector不能用作队列,因为subseq维护对整个基础向量的引用,因此从后面“弹出”的任何项都不会被垃圾收集:(