Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.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 对1TB文件的读/写缓存-缓冲区上的代理/视图_Java_Caching_Io_Buffer - Fatal编程技术网

Java 对1TB文件的读/写缓存-缓冲区上的代理/视图

Java 对1TB文件的读/写缓存-缓冲区上的代理/视图,java,caching,io,buffer,Java,Caching,Io,Buffer,我希望有一个对象(在纯Java中)模拟大于整个虚拟内存的文件的内存映射(以TB为单位) 我的问题(6)在下面的大标题下,下面是上下文信息 返回的类ByteBufer的每个实例应该彼此保持一致(在重叠的区域中具有相同的内容)。因此,如果其中一个缓冲区发生更改,其他缓冲区应该在重叠时适当更改。此外,如果更改发生在侦听区域,则应通知侦听器(对于缓冲区,同步和侦听应该是一种单一机制。对于代理视图,同步没有问题,但侦听器问题仍然存在)。这种同步不一定是“超高性能”,但它应该是可靠的。我认为会有很多重叠的缓

我希望有一个对象(在纯Java中)模拟大于整个虚拟内存的文件的内存映射(以TB为单位)

我的问题(6)在下面的大标题下,下面是上下文信息

返回的类ByteBufer的每个实例应该彼此保持一致(在重叠的区域中具有相同的内容)。因此,如果其中一个缓冲区发生更改,其他缓冲区应该在重叠时适当更改。此外,如果更改发生在侦听区域,则应通知侦听器(对于缓冲区,同步和侦听应该是一种单一机制。对于代理视图,同步没有问题,但侦听器问题仍然存在)。这种同步不一定是“超高性能”,但它应该是可靠的。我认为会有很多重叠的缓冲区,但不会有太多的修改。 我假设在大多数情况下,我会从“文件视图”中获得很少的缓冲区(比如2kb)

每次写入都应以某种方式存储在内存中(除了写入缓冲区)。在用户单击“保存”之前,不允许直接写入文件。当然,它不会持续很长时间——我假设不需要在内存中缓存超过200MB的内存(巨大的更改块可以缓存在磁盘上的临时文件中)。这些单独的更改可以分布在整个映射文件中。如果文件中的相邻位置被修改,则可以聚合更改

因此,FileView必须:

  • 缓冲区内存中当前使用的数据
  • 将所有单个更改(写入)存储在缓存中
  • 按需公开类似ByteBuffer的对象(通过从 文件或从内存中获取现有数据),并对其进行适当的应用 缓存的更改(如果存在任何更改)
  • 当类似ByteBuffer的对象 重叠
  • 从内存中丢弃干净数据(当前未使用且未更改) (保存内存)
  • 当前未使用时,安全地从内存中丢弃“脏数据”: 为此,必须确保存储更改,然后丢弃数据 好像他们是干净的
  • 监控当前使用的内存量与最大内存量的比较 内存不足-尝试丢弃尽可能多的内存
  • 存在两大性能问题:

    1。以视图而不是独立缓冲区的形式获取新数据

    在下列电话之后:

    fileView.getBuffer(0,200000000);
    fileView.getBuffer(0,200000789);
    
    我们有两个200MB数据块的独立副本。连续调用将生成相同数据的下一个副本。 所以也许fileView应该返回现有内部缓冲区的视图,而不是新的缓冲区?但是,如何产生内部缓冲区呢?这将是“拼凑”。fileView将根据需要在内部创建缓冲区,并返回这些内部缓冲区上的视图,这些缓冲区以某种方式粘合和修补在一起。如下所示-在第四次调用中重用(修补)现有内部缓冲区:

    fileView.getBuffer(0,2);  // {0,1,2}
    fileView.getBuffer(4,5);  // {4,5}
    fileView.getBuffer(8,12); // {8,9,10,11,12}
    fileView.getBuffer(0,16); // {0,1,2} {3} {4,5} {6,7} {8,9,10,11,12} {13,14,15,16}
    
    2。在不破坏视图的情况下清除内部数据(GC)

    当内存不足时,我们应该:

    • GC未更改的缓冲区(稍后我们可以从HD再次读取它们)
    • 将更改(写入)也存储在缓存和GC修改的缓冲区中
    这样我们就可以完全消除任何读取数据(但将更改(写入)保留在单独的缓存中)。 但是

    有返回到外部组件的缓冲区视图-这些视图引用了我们的内部缓冲区,因此我们无法GC内部缓冲区。我们不想破坏这些外部视图-它们应该保持原样-我们只想去掉内部数据,然后按需填充它们(如代理)

    我正在寻找一个架构良好的解决方案来解决上述情况。下面是我需要知道的:

  • 如何以视图而不是独立缓冲区的形式获取新数据? 我想:

    • 避免在多个缓冲区中使用同一数据的多个独立副本,因此我需要视图
    • 在fileView.getBuffer之后(长从,长到);返回功能类似于ByteBuffer的内容
    • 与裸奔者相比,不要过分破坏性能 也许我应该返回一个全新类的实例,该类在fileView的内部缓冲区上实现代理视图,并且具有类似于bytebuffer的接口
  • 什么样的数据结构适合跟踪加载的内容和未加载的内容?可能是树映射加链接列表中的叶,其中保留了缓冲区

  • 如何在不破坏外部视图的情况下删除内部数据(GC)

  • 如何在重叠区域中同步(=保证相等)返回缓冲区/视图的内容? 对于视图,这个问题会消失,因为每个视图都引用相同的底层结构

  • 如何高效地存储单个更改(写入),然后在从文件重新加载数据时将其重新应用到新返回的缓冲区/视图?每一次更改都可以是一个字节长,但也可以是数兆字节长

  • 如何有效地将选定的字节范围映射到适当的侦听器(单个侦听器侦听定义的字节范围内的更改,而不是整个缓冲区内的更改)

  • 对于那些仍在阅读的读者,我可以提供一些关于我正在做什么的额外细节:) 我对缓存几乎一无所知,对缓冲区知之甚少,但是

    我尝试创建一个内置脚本引擎(DSL)和GUI到数据绑定的十六进制编辑器。其目的是进行数据分析和恢复。 我选择的语言是Java+Groovy。项目的某些部分目前处于高级阶段,它们基于ByteBuffers、CharBuffers等

    对于我的申请,我有以下业务限制:

  • 该应用程序可以打开非常大的文件(高清备份文件)——比如说1-2TB (TB)
  • 用户可以看到打开的文件,
    fileView.getBuffer(0,2);  // {0,1,2}
    fileView.getBuffer(4,5);  // {4,5}
    fileView.getBuffer(8,12); // {8,9,10,11,12}
    fileView.getBuffer(0,16); // {0,1,2} {3} {4,5} {6,7} {8,9,10,11,12} {13,14,15,16}
    
    char[8] - "File system ID"
    uint16 - "Bytes per sector"
    uint8 - "Sectors per cluster"
    uint16 - "Reserved sectors"
    ...