实现:一个字符串到字符串的数据库



就像std::unordered_map<std::string, std::string>一样,但是所有的数据都应该存储在磁盘上而不是存储在内存中

在我的理解中,应该完成两个部分:索引和存储。我已经学习了一些关于索引的数据结构,如线性哈希或B-Tree,并且编写磁盘上的int->int数据库并不太难。问题是存储

对于整数,所有记录的大小相同。一旦我们通过索引找到要记录的位置,我们就可以很容易地提取、修改或延迟删除。但是对于字符串,记录的大小是灵活的。它应该(至少)有以下问题:

  1. put()更长的字符串:我们不能简单地覆盖旧记录,我们不得不做del()和put(),浪费了旧记录的空间。

  2. del():旧记录的空间也会被浪费,不能再使用。(也许我们可以使用垃圾收集器收集已删除的空间,但这会消耗额外的空间并产生碎片)

  3. 对于int->int数据库,浪费几个整数的空间不是一个大问题。但是字符串越长,浪费的空间就越多。

我需要一些建议/提示来解决这些问题。

您可以以文件系统如何管理可变大小的文件为例。

它们将文件空间分配为固定大小的块,每个块大约几千字节,并将这些块链接在一起形成任意长度的完整文件。

如果你需要扩大你的文件,你分配和链接更多的块。如果您需要收缩或删除它,您可以取消链接并释放一个或多个块。

这里唯一值得注意的碎片是内部的,每个文件的最后块中浪费的空间。

如果你使用文件实现这个,其中每个块要么是一个潜在的大文件的一部分,要么是一个自己的文件,你不需要立即删除/释放它。您可以在控件/元数据中将其标记为空闲,然后稍后再使用。您可以实现压缩(删除所有空闲块)作为一个单独的操作,不经常执行。

首先实现一个映射器。每当您获得新的字符串时,按顺序将它们存储在一个文件中,并将它们的位置存储在地图上。

对我来说,这听起来像是键/值存储的定义。你可以使用任何你喜欢的系统。从Oracle的Berkeley DB到Cassandra或Riak.

最新更新