Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.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
事务性、内存中、对象/键/值存储库? 我有一个C++应用程序,内存数据集由一组对象组成,每个对象都有一个键/值集。对象和键由int-id引用,值始终是单个类的实例。键ID在对象中是唯一的,对象ID在宇宙中是唯一的_C++_Database_Key Value - Fatal编程技术网

事务性、内存中、对象/键/值存储库? 我有一个C++应用程序,内存数据集由一组对象组成,每个对象都有一个键/值集。对象和键由int-id引用,值始终是单个类的实例。键ID在对象中是唯一的,对象ID在宇宙中是唯一的

事务性、内存中、对象/键/值存储库? 我有一个C++应用程序,内存数据集由一组对象组成,每个对象都有一个键/值集。对象和键由int-id引用,值始终是单个类的实例。键ID在对象中是唯一的,对象ID在宇宙中是唯一的,c++,database,key-value,C++,Database,Key Value,这几乎是一个映射,除了我需要能够枚举附加到特定对象的键之外。这一切都需要事务性的,所以如果出现问题,我可以回滚更改 这对我来说是一个完全标准的问题,我应该能够得到现成的代码,但我一直找不到任何东西。任何人都可以: (a) 告诉我这个问题到底叫什么,这样我就知道该找什么 (b) 建议我应该看的任何代码 请注意,我只希望它是一个内存中的数据存储,因此像Berkeley DB这样的NoSQL方法不适合——我不希望继续读取和写入值对象(它们相当复杂) 到目前为止,我已经找到了不进行事务处理的简单方法(比

这几乎是一个
映射
,除了我需要能够枚举附加到特定对象的键之外。这一切都需要事务性的,所以如果出现问题,我可以回滚更改

这对我来说是一个完全标准的问题,我应该能够得到现成的代码,但我一直找不到任何东西。任何人都可以:

(a) 告诉我这个问题到底叫什么,这样我就知道该找什么

(b) 建议我应该看的任何代码

请注意,我只希望它是一个内存中的数据存储,因此像Berkeley DB这样的NoSQL方法不适合——我不希望继续读取和写入值对象(它们相当复杂)

到目前为止,我已经找到了不进行事务处理的简单方法(比如boost_multi_index,甚至只是嵌套的STL映射),或者使用持久存储的复杂方法,但两者之间什么都没有。我可以在基本存储的基础上实现自己的事务层,但老实说,我不愿意

我错过了什么

编辑:嗯,似乎没有人能够提出建议;所以我写了我自己的。它出人意料地复杂,但实际上并没有太多的代码。现在它只是一个使用嵌套映射存储的模板类,但为了简单起见,我正在考虑改用boost::multi_index_容器。它没有抛光,可能有很多虫子,但如果有人认为他们可以使用它,请告诉我

更多编辑:作为参考,我正在寻找的Googleable名称是一个实体/属性/值数据库(EAV)

你考虑过吗?它是一个数据结构服务器,因此您可以使用映射结构并轻松枚举附加到对象的键(请参阅)。它也支持


我想缺点是,我不确定打包为库有多容易。

您真正想要的是一个异常安全的容器

请阅读以下内容: http://lmzr.perso.neuf.fr/attic/Exception_Safe_Generic_Containers.pdf

您的问题很快就归结为确保存储对象的构造函数、复制构造函数、赋值运算符等中有特定的异常保证。
如果没有发生这种情况,那么很可能您在设计对象类型时没有足够小心地分离关注点。

LMDB将处理此问题。您可以将它与tmpfs上的一个文件一起使用,以保证所有操作都只在内存中,也可以在一个提交时间非常长的普通ext3/ext4文件系统上使用它,以避免将更改写入磁盘。它是完全事务性的,并使用内存映射文件;如果文件系统缓存写回时间设置得足够长,并且您使用异步提交运行它,那么您的更改将只存在于RAM中,而不会刷新到磁盘。
它可以进行零拷贝读写;您可以使用最小的序列化来编写对象,并使用零反序列化来引用它们。

使用:memory:pseudo-dbs查看SQLite这仍然需要我在访问它们时序列化/反序列化我的值。我想使用本地数据存储,这样我的值只是指向C++对象的指针,避免了I/O开销。我不太明白。在数据库中,您使用事务以避免操作部分成功,或另一个客户机因该操作而看到不一致的状态。因为您的目标是一个纯粹的内存映射,所以您可能不想回滚复杂的多步骤操作。如果将访问权包装在互斥体中,则是线程安全的。您还想做些什么,这样一个受互斥保护的std::map是不够的?我希望能够在数据库发生变异的过程中,找到一个错误条件,然后退出到目前为止发生的所有更改,使数据库保持一致。如果用户要求我的程序以不允许的方式更改对象,则会出现错误情况。我真的不想在每次变异之前都要经历一个单独的验证阶段。@David:它应该是多线程的吗?我确实看过Redis——不幸的是,它不是内存中的数据库,所以我在序列化/反序列化我的值时仍然会有I/O开销。@David-我为某个项目深入研究过Redis(毕竟没有选择它),据我记忆所及,它是一个内存中的数据库。它有一个记录更新的选项,以便在重新启动后恢复数据库的状态。此记录是可配置的(例如,每1分钟或每N次更新)是的,但是ReDIS仍然把它的所有数据存储在一个外部服务器进程中——所以从我的应用程序的角度来看,我仍然有所有的I/O开销,这些数据从数据存储区中序列化和反序列化,我想避免。理想地,我只希望直接指向C++对象的指针。您寻求的“回滚”概念是强有力的保证。◦基本保证:组件的不变量被保留,并且没有资源泄漏。◦强有力的保证:操作已成功完成或引发异常,使程序状态与操作开始前完全相同。◦不抛出保证:操作不会抛出异常。是的,很好地发现了。听起来OP的“事务”要求实际上更好地表达为强大的异常安全保证。(除非在混合中添加线程安全,否则真正的ACI(D)类事务将更合适)异常安全容器允许跨多个突变回滚吗?我需要能够