Versioned writeahead log - 这个数据结构是否存在?

时间:2013-06-17 20:29:25

标签: data-structures database

背景

我已经读过许多DBMS使用预写日志记录来通过将更新存储为一组写操作来保持事务的原子性和持久性。我想要完成的是创建一个由allowing reads to proceed on 'old' data while writes are pending改进并发性的dbms模型。

问题:

是否存在允许我有效(理想情况下为O(1)摊销,最多为O(log(n))查找数组元素(或内存位置,如果您愿意)的数据结构,在某些时间点可能会或可能没有被写入操作覆盖?这将是大约1TB的数据总量。

这是一些ascii艺术,使这一点更清晰。破折号是数据,版本0是最旧的版本。箭头表示写操作。

 ^   ___________________________________Snapshot 2
 |   V         |  |     V                         
 |  --    ---  |  |  --------           Version 2 
 |             |  |   __________________Snapshot 1
 |             V  |   |      V                    
T|      --------  |   |   ---------     Version 1 
I|                |   |      ___________Snapshot 0
M|                V   V      V  V                 
E|------------------------------------- Version 0 
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
  SPACE/ADDRESS

尝试解决方案:

设N为数据大小,M为版本数,P为每个版本的平均更新次数。

  • 天真算法(搜索每个更新)是O(M * P)。
  • 将数据划分为存储桶,仅更新整个存储桶,以及搜索存储桶的位掩码将是O(N / B * M),其中B是存储桶大小,这不是更好。
  • Bloom过滤器乍一看似乎是一个很好的候选者,除了它需要的数据多于每个内存位置的简单位掩码(无论如何都要糟糕,因为它需要存储M * N / 8个字节。)< / LI>
  • 还会想到一个标准哈希表,但关键是什么呢?

实际上,既然我已经解决了写这一切的麻烦,我想到了一个使用二叉搜索树的解决方案。 我会稍微提交它作为答案,但它在空间和时间上仍然是O(M * log2(P))并不理想。见下文。

1 个答案:

答案 0 :(得分:0)

以下是我能想到的最佳解决方案,尽管它仍然不是最理想的。

我们的想法是将每个区域放入一个二叉搜索树,每个版本一个树,其中每个内部节点包含一个内存位置,每个叶节点都是HitMiss(可能查找信息),取决于是否存在更新的数据。这是为每个版本构造的O(P * log(P)),以及要查找的O(M * log(P))。

这是次优的,原因有两个:

  • 树是平衡的,但Miss es在实践中比Hit更可能,因此将Miss个节点放在树中较高或排列节点是有意义的按他们的大小。我想到了某种霍夫曼编码,但霍夫曼的算法并没有保留搜索树不变量。
  • 它需要M树(因此O(M * log(P))查找)。也许有一些方法来组合树木。