Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
Java 如何跨数据结构压缩多个字符串?_Java_String_Xpath_Data Structures_Compression - Fatal编程技术网

Java 如何跨数据结构压缩多个字符串?

Java 如何跨数据结构压缩多个字符串?,java,string,xpath,data-structures,compression,Java,String,Xpath,Data Structures,Compression,我有一个500GB的XML文档集合,我正在编制索引。我目前只能用32GB的RAM索引这个集合中的6GB 我的索引结构是一个HashMap,其中第一个字符串表示一个术语,第二个字符串的格式为filepath+XPath,最后一个整数表示出现的次数 我使用了trie来减少共享前缀,因为我需要对数据进行排序。这对压缩有点帮助,但还不够 在此数据结构中,filepath+XPath字符串的总集合介于1TB和4TB之间。我需要能够将这个数据结构完全压缩到内存中。目标机器有256GB RAM和16个CPU核

我有一个500GB的XML文档集合,我正在编制索引。我目前只能用32GB的RAM索引这个集合中的6GB

我的索引结构是一个
HashMap
,其中第一个字符串表示一个术语,第二个字符串的格式为
filepath+XPath
,最后一个整数表示出现的次数

我使用了trie来减少共享前缀,因为我需要对数据进行排序。这对压缩有点帮助,但还不够

在此数据结构中,
filepath+XPath
字符串的总集合介于1TB和4TB之间。我需要能够将这个数据结构完全压缩到内存中。目标机器有256GB RAM和16个CPU核。更少的内存有多个额外的好处(例如减少冷启动时间)。索引时间没什么大不了的

XPath表示总共大约250种节点类型

我目前正在研究的方法将基于接下来可能出现的标记,为每个系列的2个标记构建一个Huffman表。通常,这会将选项减少到大约4或5个,从而允许将XPath编码为更短的位字符串,然后将其编码为字节

字符串通常为40-600字节(UTF-8),我认为这应该可以将文件路径前缀(前40个字符,由trie压缩)之后的所有内容减少到最多12个字节(树上最深的点大约有12个节点深,每个节点最差只能代表1个字符)对于结构,索引为12字节(可变字节编码,只有极少数元素包含256以上的索引),生成的字符串通常在40-64字节范围内

我认为这是一个很好的方法,但我认为我可能遗漏了一些东西

  • 有没有更好的方法来压缩此数据结构或其中的数据
  • 人们通常如何跨同一数据结构压缩多个字符串
  • 是否存在基于整个集合独立压缩多个字符串的现有解决方案
  • 在字符串像这样进入数据结构之后,有没有什么好的技术可以基于它们之间共享的结构来压缩这些尝试

我认为您最大的问题是每个学期存储的数据太多。你不会说你有多少个独特的术语或者有多少个单独的文件,但我会给出一些示例数字

假设您有200个不同文件中的200000个唯一术语。因此,每个唯一的术语都有至少一个文件路径的权重,即40字节。那是在你开始索引任何东西之前

您应该能够将这些数据压缩到一个包含
filepath+Xpath
字符串的表和一个术语列表中,每个术语都包含对该表中条目的引用。例如,您可能有:

路径表:

index   Path
  1   file+xpath1
  2   file+xpath2
  3   file+xpath3
  ...
999   file+xpath999
条件

现在,您的路径表可能仍然太大。您可以做的第一件事是构建一个files表,并将路径的第一部分作为索引输入files表。因此,你最终会:

档案

然后你的道路变成:

  1  1,xpathA
  2  1,xpathB
  3  2,xpathQ
  ...
如果在此之后需要更多的压缩,那么构建一个包含xpath术语的字符串表,您的路径条目将成为该表中的一系列索引。不过,在这里您必须小心,因为数组或列表的分配开销将使短列表非常昂贵。如果你走这条路,那么你会想把路径列表编码成一个大的二进制数组,并索引到其中。比如说

词表

1 the
2 quick
3 brown
4 fox
路径

Paths表只是一个大数组,如下所示:

1,2,4,-1,3,3,-1,...
这可以最大限度地降低数据存储成本,因为没有任何字符串被多次存储。您所拥有的只是字符串表和对这些字符串的引用。它所占用的空间量大致如下:

Combined length of all file names
Combined length of all path segment terms
(number of paths) * (average path length) * (size of integer index)
(number of terms) * (average number of references per term) * (size of integer index)
在内存中构建这个可能是可能的。很难说不知道你有多少个术语。如果使用单词列表,则需要为文件名、路径和各个路径段提供字典。但是如果你有记忆的话,这一切都可以一次完成

如果在构建时没有足够的内存容纳整个树,则可以加载文件名并在内存中维护路径表。当您在文件中找到每个术语时,将其连同路径引用一起写入磁盘。最终得到的磁盘文件如下所示:

term, path reference
term, path reference
...
使用外部排序程序按术语排序,然后遍历并合并重复项。完成后,您将得到一个包含以下内容的文件:

File names table
Path segments table
Paths
terms
查找真的很容易。找到术语,在路径表中查找每个引用,并通过索引到文件名和路径段表中对路径进行解码

几年前我用过类似的东西,效果很好。您应该能够编写一个程序来分析您的数据,以得出数字(唯一路径、文件名数量、每个术语的平均引用数量等)。从这里,您可以轻松确定使用此技术是否适合您。

对于处理无法放入内存的数据结构,可能有一些有用的方法。
Combined length of all file names
Combined length of all path segment terms
(number of paths) * (average path length) * (size of integer index)
(number of terms) * (average number of references per term) * (size of integer index)
term, path reference
term, path reference
...
File names table
Path segments table
Paths
terms