Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.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_Key Value_Key Value Store - Fatal编程技术网

Java在磁盘上存储和比较巨大的键值对映射

Java在磁盘上存储和比较巨大的键值对映射,java,key-value,key-value-store,Java,Key Value,Key Value Store,我有一个场景,其中我必须比较两张地图。我必须获取源映射的一个键,并在目标映射中迭代寻找equals的键,然后比较它们的值。问题在于,这些映射应该包含非常高(>=10000000)的记录量。所以我无法将这些地图保存在内存中 可能的解决方案: 将两者存储为文本文件作为“key=value” 问题: 我们必须对源代码中的每个键值遍历目标映射文本文件,这既无效又耗时 可能的解决方案: 将两者存储为文本文件作为“key=value”,并为目标创建id=>行号的索引 问题: 没有有效的方法直接从大文本文件中

我有一个场景,其中我必须比较两张地图。我必须获取源映射的一个键,并在目标映射中迭代寻找equals的键,然后比较它们的值。问题在于,这些映射应该包含非常高(>=10000000)的记录量。所以我无法将这些地图保存在内存中

可能的解决方案:

将两者存储为文本文件作为“key=value”

问题:

我们必须对源代码中的每个键值遍历目标映射文本文件,这既无效又耗时

可能的解决方案: 将两者存储为文本文件作为“key=value”,并为目标创建id=>行号的索引

问题:

没有有效的方法直接从大文本文件中读取基于行号的行。有些方法使用Java1.8的api,它们同样需要将文件加载到内存中

可能的解决方案:

将两者存储在数据库中

问题:

在这种情况下,我们必须查询数据库中的每个键值。如果我们在源和目标中有一百万个密钥,我们必须查询一百万次。无效且耗时

可能的解决方案:

使用

问题:

尝试了这个,但是在260000条记录之后失败了。它给出了一个Writer线程失败异常,主要是因为我使用的是32位JVM。因此,我希望自己编写实现,而不是依赖MapDB


如何有效地存储/检索和比较键值映射,以便在进行比较时不会对性能造成太大影响。任何时候我都不能把任何东西带进内存,因为它会出现内存不足的异常。解决方案应该读写磁盘,而不是内存——我没有12GB的RAM。此外,该解决方案应适用于32/64位系统

一个相当简单的选项:

  • 把地图放在磁盘上
  • 对它们进行排序(以多种方式中的任何一种)
  • 为每个地图打开一个读卡器,然后阅读第一行
  • 迭代每个映射的行,根据“当前”键的比较来决定从哪个映射读取
这样,您在任何时候都只需要内存中的两个键/值对

例如,假设我们有一个带有键a、B、H、I的“源”映射和一个带有键B、C、I、J的“目标”映射。该过程如下所示:

  • 读取源=A,目标=B
  • 比较:源在目标之前,因此从源(B)读取另一行
  • 比较:源键和目标键相等,因此处理B的条目,并从每个条目中读取另一行(源=H,目标=C)
  • 比较:目标在源之前,因此从目标(I)读取另一行
  • 比较:源在目标之前,因此从源(I)读取另一行
  • 比较:源键和目标键相等,因此处理I的条目,并从中读取另一行(源=空,目标=J)
  • 由于源代码中的数据已经用完,我们就完成了

    • 一个相当简单的选择:

      • 把地图放在磁盘上
      • 对它们进行排序(以多种方式中的任何一种)
      • 为每个地图打开一个读卡器,然后阅读第一行
      • 迭代每个映射的行,根据“当前”键的比较来决定从哪个映射读取
      这样,您在任何时候都只需要内存中的两个键/值对

      例如,假设我们有一个带有键a、B、H、I的“源”映射和一个带有键B、C、I、J的“目标”映射。该过程如下所示:

      • 读取源=A,目标=B
      • 比较:源在目标之前,因此从源(B)读取另一行
      • 比较:源键和目标键相等,因此处理B的条目,并从每个条目中读取另一行(源=H,目标=C)
      • 比较:目标在源之前,因此从目标(I)读取另一行
      • 比较:源在目标之前,因此从源(I)读取另一行
      • 比较:源键和目标键相等,因此处理I的条目,并从中读取另一行(源=空,目标=J)
      • 由于源代码中的数据已经用完,我们就完成了

        • 感谢@Jon的算法。这就是我的执行问题。如果有任何错误或可以改进,请告诉我

          包装控制器;
          导入java.io.BufferedReader;
          导入java.io.BufferedWriter;
          导入java.io.File;
          导入java.io.FileNotFoundException;
          导入java.io.FileReader;
          导入java.io.FileWriter;
          导入java.io.IOException;
          公共类ReadAndCompareMapOnDisk{
          公共静态void main(字符串参数[]){
          最后一个字符串换行符=“\n”;
          字符串sourceSortedFile=“C:\\TestData\\SourceSorted.txt”;
          字符串targetSortedFile=“C:\\TestData\\TargetSorted.txt”;
          String matchedOutputFile=“C:\\TestData\\OutputMatched.txt”;
          字符串SourceNotPresentTarget=“C:\\TestData\\OutputSourceUnMatched.txt”;
          字符串targetNotPresentSource=“C:\\TestData\\OutputTargetUnMatched.txt”;
          字符串keyValueSeparator=“=”;
          缓冲读取器;
          缓冲读取器目标读取器;
          缓冲写入程序匹配写入程序;
          BufferedWriter sourceUnMatchedWriter;
          BufferedWriter targetUnmatchedWriter;
          试一试{
          sourceReader=new BufferedReader(新文件阅读器(新文件(sourceSortedFile));
          targetReader=new BufferedReader(新文件阅读器(新文件(targetSortedFile));
          matchedWriter=new BufferedWriter(新文件写入程序(新文件(matchedOutputFile)));
          sourceUnMatchedWriter=新的BufferedWriter(新文件编写器(新文件(SourceNotPresentTarget));
          targetUnmatchedWriter=新缓冲写入程序(新文件写入程序(新文件(targetNotPresentSource));
          字符串sourceLine=“”;
          字符串targetLine=“”;
          字符串sourceKey=“”;
          Str