自从我做了任何C ++以来已经有一段时间了,而且我对实现以下内容的最佳方式有点生疏:
我们有一个存储大量“对象”的数据库。我试图想办法将这些对象的整个列表加载到内存中,但由于这些对象的大小和数量,将它们全部存储在内存中是不切实际的。相反,我希望有一个“内存映射文件”系统,在访问它们时按需加载对象。换句话说,让OS或类似的东西管理哪些对象应该在内存中,类似于操作系统决定应该将文件的哪些段分页到内存中。谁能给.me暗示如何做到这一点?
答案 0 :(得分:1)
如果你在C ++上生气,你可能会采取一种简单的方法。
你提到“物体”;我把它当作“用户数据”而不是实际的序列化c ++类。
无论如何,内存映射文件只是一个文件。你将要从文件中读取,操作系统不会为你解决问题。
我的建议是保持简单。将“对象”实现为普通文件I / O.然后,一旦你有了这个工作,你可以通过使用内存映射文件来提高性能。
至于设计模式, 我将设计一个由CDataBase类创建的CObject类。 CDataBase会知道文件(Database)中每个Object的位置,然后根据需要创建CObject(从文件中读取它们)。
祝你好运。答案 1 :(得分:1)
只是一个警告 - 如果你有大量的对象存储在SQL表中,你想任意加载到内存中,它可能会以多种方式变慢:许多命中数据库(尝试使用最少数量的查询),太多的构造函数调用(使用内存池)等...
...但是您需要一步一步 - 看看您是否可以先将SQL记录读入实例化对象。最佳速度优化将在于如何组织数据以最小化对数据库的命中并最小化构造函数调用。
请注意,内存映射解决方案将代替SQL表 - 它将更快,但不如SQL灵活,您将遇到双重维护的麻烦:SQL中的数据必须保持同步你的内存映射文件。
答案 2 :(得分:0)
答案 3 :(得分:0)
因此,根据对象的大小,您可以将它们存储在哈希映射中,该映射保留LRU列表并开始将对象驱逐到文件,同时保持键和文件在地图中的偏移量。这样,当你确实需要从磁盘中取回它时,它是一个搜索和读取以获取对象。如果你想要预先分配固定大小的文件,你可以mmap它们,你的偏移将成为另一个指针。
这简化了Riak数据库初始存储的工作方式,他们在网站上有一些设计文档[1] [2]。这只有在你的对象比键大时才能很好地工作,这样所有的键都很容易适合内存,但对象则不然。
Cassandra数据库使用类似的技术及其“密钥缓存”[3]。
您还可以为本地商店寻找类似Berkly DB的内容
[1]:http://wiki.basho.com/Concepts.html#Data-Storage
[2]:http://downloads.basho.com/papers/bitcask-intro.pdf
[3]:http://www.datastax.com/dev/blog/maximizing-cache-benefit-with-cassandra