在磁盘子串索引上

时间:2008-09-09 23:48:26

标签: indexing substring on-disk

我有一个我想索引的文件(特定的fasta文件),这样我就可以快速找到文件中的任何子字符串,然后找到原始fasta文件中的位置。

在很多情况下,使用Trie或子串数组很容易做到这一点,遗憾的是我需要索引的字符串是800+ MB,这意味着在内存中执行它们是不可接受的,所以我正在寻找一种合理的方法在磁盘上创建此索引,内存使用量最小。

(编辑澄清)

我只对蛋白质的标题感兴趣,所以对于我感兴趣的最大的数据库,这是大约800 MB的文本。

我希望能够根据输入字符串在O(N)时间内找到精确的子字符串。这必须可以在32位计算机上使用,因为它将被发送给随机的人,他们不会有64位计算机。

我希望能够将一行中的任何分词索引到该行的末尾(尽管行可以是几MB长)。

希望这可以澄清所需要的内容以及为什么当前的解决方案并不具有启发性。

我还应该补充说,这需要在java中完成,并且必须在各种操作系统上的客户端计算机上完成,因此我不能使用任何特定于操作系统的解决方案,它必须是一个程序化的解决方案。

4 个答案:

答案 0 :(得分:1)

在某些语言中,程序员可以访问 “直接字节数组” memory maps ,由OS提供。在java中,我们有 java.nio.MappedByteBuffer 。这允许人们使用数据,就像它是内存中的字节数组一样,实际上它在磁盘上。可以使用的文件大小仅受操作系统虚拟内存功能的限制,对于32位计算机通常约为4GB。 64位?理论上16艾字节(172亿GB),但我认为现代CPU仅限于40位(1TB)或48位(128TB)地址空间。

这可以让您轻松使用一个大文件。

答案 1 :(得分:1)

FASTA file format非常稀疏。我要做的第一件事是生成一个紧凑的二进制格式,索引 - 它应该是当前文件大小的20-30%,编码/解码数据的过程应该是足够快(即使有4GB),这不会是一个问题。

此时,即使在32位计算机上,您的文件也应该适合内存。让操作系统对其进行分页,或者如果你想确定它是全部存储在内存中,那么就制作一个ramdisk。

请记住,内存只有每GB约30美元(并且越来越便宜),所以如果你有64位操作系统,那么你甚至可以处理内存中的完整文件,而无需将其编码为更紧凑的格式。

祝你好运!

- 亚当

答案 2 :(得分:0)

我与一些同事交谈,他们只是在需要时使用VIM / Grep进行搜索。大多数时候我不希望有人搜索这样的子字符串。

但我不明白为什么MS桌面搜索或聚光灯或谷歌的等价物无法帮助你。

我的建议是通过基因或物种分割文件,希望输入序列不是交错的。

答案 3 :(得分:0)

我不认为原始海报仍有这个问题,但是任何需要FASTA文件索引和子序列提取的人都应该检查fastahack:http://github.com/ekg/fastahack

它使用索引文件来计算换行符和序列起始偏移量。生成索引后,您可以快速提取子序列;提取由fseek64驱动。

如果您的序列与海报一样长,那么它将非常有效。但是,如果FASTA文件中有数千或数百万个序列(如短读序列或某些 de novo 程序集的输出),您将需要使用其他解决方案,例如作为磁盘支持的键值存储。