我需要存储一个大的哈希集,最多可以包含大约2亿个40位值。将其存储为2亿64位值是可以接受的(尽管有2亿* 16位丢失)。
要求是:
微小的内存占用(磁盘空间不是问题,内存是)
快速contains(long l)
和add(long l)
方法(比SQL快得多)
嵌入式
免费且没有讨厌的许可(没有Berkeley DB)。 LGPL罚款。
没有误报,也没有误报,所以像基于磁盘的布隆过滤器这样的东西不是我追求的
SQL 不是我在此之后的事情。
因为我真的认为我更喜欢 fast 这样的事情(注意解决方案比SQL解决方案快得多):
Google是否有这样的Java API?
基于磁盘的快速键/值对实现我只使用'键'吗?
还是其他什么?
我宁愿不重新发明。
答案 0 :(得分:2)
如果您可以负担128 GB的磁盘,则每40位值可以存储一位。 然后,您可以使用随机访问文件来检查已设置的位或更改它。您不必插入任何值或维护索引。
答案 1 :(得分:2)
尝试sg-cdb(djb的cdb的奇怪的gizmo端口),然后用BufferedRandomAccessFile交换RandomAccessFile(在jai-imageio代码中有一个很好的。)
我正在开心写作表现。通过屋顶(因为它全部缓冲然后一举进行)。 但是,缓冲的RAF的读取性能没有改变。
我可以花时间与H2批量导入进行比较,虽然不确定但可能具有可比性。
数据库很简单:key =>值。查找仅在密钥上受支持。 键是在我的情况下(base32编码随机int + base32编码唯一int)所以该地方不应该真正帮助太多。这些值是120个随机字节的数组。
2011年5月4日11:45:10 PM test.TestH2Simple main :插入执行添加:101625 ms
数据库大小: 大约140 MB
批量大小:2000 :插入执行添加:116875 ms
批量:10000 :insertsperformed添加:70234 ms
: insert without flush:21688 ms,flush:30359 ms,总计:52047 ms 磁盘上文件的大小: 66.1 MB(69,315,632字节)
使用BufferedRandomAccessFile: 约6.5秒
当然,这并不是一个公平的比较,因为H2在插入期间连续刷新数据,而sg-cdb则不然。在进行比较时必须牢记这一点。将sg-cdb插入物与H2大量插入物进行比较可能是公平的
:搜索:490000 完成:1304544550439:17547 ms,计数器:0
:选择执行于:19579 ms
关于内存映射文件: 他们似乎并不是你想要的。 MMap文件的出色表现是当你将大约100MB或更多内容映射到内存时(我的经验)。
答案 2 :(得分:0)
我相信你需要使用B树而不是哈希表。哈希表没有良好的二级存储位置,因此您将丢失太多的磁盘I / O时间。
大多数数据库 - 无论是关系数据库 - 都将它们的索引实现为B树,所以你所说的相当于存储一个没有附加其他数据的索引。
您是否有多个进程同时更新此数据存储?