纯粹的功能并发的跳跃表
-
28-09-2019 - |
题
跳过列表 (Pugh,1990)提供排序的字典与对数时操作搜索树木但是 跳过清单更易于更新并发.
是否有可能建立一个有效率的纯粹的功能并发跳过列表吗?如果没有,是否有可能建立的任何种类的高效纯粹的功能并排序的字典?
解决方案
酒店的跳名单,使他们好并更新(即,大多数加法和减法是当地)也使它们对永久性(即,很多前项目列表中点的最终后的项目,以及就必须改变)。
具体地说,跳过表组成的结构看起来像这样:
NODE1 ---------------------> NODE2 ---------...
| |
V V
NODE1a --> NODE1b ---------> NODE2a --> NODE2b --> NODE2c --- ...
现在,如果你有一个更新说,删除 NODE2b
或 NODE1b
, 你能照顾它非常地:你只要点 2a
要 2c
或 1a
要 2a
别和你完成。不幸的是,因为叶节点有点到另一个,它不是一个好结构的功能(不变的)更新。
因此,树形结构更好地为永久性(因为损害总是在本地的限制--只要节点你关心和它的直接的父母通过根的树)。
并发更新不工作以及与不可改变的数据结构。如果你想想看,任何功能的解决方案已更新 A
作为 f(A)
.如果你想要两个更新、一个由 f
和一个由 g
, 你差不多要做的 f(g(A))
或 g(f(A))
, 或者你必须要拦截的请求,并创建一个新的动作 h = f,g
你可以适用于所有在一个去(或者你需要做的各种其他非常聪明的东西).
然而,并发读工作的地理以及与不可改变的数据结构来保证您有没有状态的变化。如果你不要以为你可以有一个读写环解决之前的任何其他写信可以中断,然后你从来没有锁上读取。
因此,注重数据结构可能是更好的实施mutably(和有东西就像一个跳跃表在这里你只需要锁定当地),同时大量读取的数据结构可能更好地实施改(其中一棵树是一个更自然的数据结构)。
其他提示
安德鲁·麦金莱(Andrew McKinlay)的解决方案是真正的跳过列表的真实“真”功能解决方案,但它具有不利的一面。您需要花费对数时间来访问元素,但是现在超出头部元素的突变变得绝望。您想要的答案被埋葬在无数的路径上!
我们可以做得更好吗?
问题的一部分是,有多个途径从 - 物质到您的物品。
但是,如果您考虑搜索船只的算法,则永远不会使用该事实。
我们可以将树中的每个节点视为具有首选链接,这是从左侧到它的最高链接,从某种意义上说,这可以被视为“拥有”该条目。
现在,我们可以将“手指”的概念视为数据结构,这是一种功能技术,使您能够专注于一个特定元素,并提供回到根的路径。
现在我们可以从简单的跳过列表开始
-inf-------------------> 16
-inf ------> 8 --------> 16
-inf -> 4 -> 8 -> 12 --> 16
按级别扩展它:
-inf-------------------> 16
| |
v v
-inf ------> 8 --------> 16
| | |
v v v
-inf -> 4 -> 8 -> 12 --> 16
剥离除优选的指针外的所有人:
-inf-------------------> 16
| |
v v
-inf ------> 8 16
| | |
v v v
-inf -> 4 8 -> 12 16
然后,您可以通过跟踪所有必须翻转才能到达那里的指针来将“手指”移动到位置8。
-inf ------------------> 16
^ |
| v
-inf <------ 8 16
| | |
v v v
-inf -> 4 8 -> 12 16
从那里可以删除8,将手指推到其他地方,您可以继续用手指导航。
从这种方式看,我们可以看到跳过列表中的特权路径形成了一个生成树!
如果您在树上只有特权指针并使用这样的“瘦节点”,则用手指移动1步是O(1)操作。如果您使用脂肪节点,则手指运动可能会更昂贵。
所有操作均保持O(log n),您可以像往常一样使用随机的跳过列表结构或确定性结构。
也就是说,当我们将Skiplist分解为首选路径的概念时,我们会发现Skip-List只是一棵树,有一些冗余的非偏见链接,我们不需要插入/搜索/删除,因此从右上角的每条路径的长度为O(log n)具有很高的概率,或者根据您的更新策略而保证。
即使没有手指,您也可以在带有此表格的树中维护每个插入/删除/更新的预期时间。
现在,问题中没有意义的关键词是“并发”。纯粹的功能数据结构没有地位突变的概念。您总是生产新事物。从某种意义上说,并发功能更新很容易。每个人都有自己的答案!他们只是看不到彼此。
不是跳过列表,但似乎与问题描述相匹配:Clojure的持久红黑树(请参阅 persistenttreemap.java)。来源包含此通知:
/**
* Persistent Red Black Tree
* Note that instances of this class are constant values
* i.e. add/remove etc return new values
* <p/>
* See Okasaki, Kahrs, Larsen et al
*/
这些树保持了元素的顺序,并且在Rich Hickey使用该单词的意义上是“持久的”(不变并能够在构建更新版本时保持其性能保证)。
如果您想和它们一起玩,可以在Clojure代码中构建实例 sorted-map
.
如果您只需要在跳过列表的正面上有缺点,那么应该可以制作一个不变的版本。
这种跳过列表的优点将是“随机”访问。例如,您可以在常规单个链接列表中更快地访问N'TH元素。