您可以使用
managed_mapped_file
来透明地从内存映射文件中分配内存。这意味着在实际操作中,您通常不需要划分内存区域。它们都是虚拟内存,所以换页会在需要时加载正确的位。显然,如果存在大量的碎片或访问“跳跃”,则分页可能会成为性能瓶颈。在这种情况下,请考虑将其细分为池并从中分配。_
编辑刚刚注意到,Boost IPC在隔离存储节点分配器和自适应池节点分配器下提供了支持。此外,还有关于这些存储池实现的说明在这里。
这是一个简单的起点,创建一个50GB的文件并将一些数据放入其中:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
namespace bip = boost::interprocess;
using mutex_type = bip::named_mutex;
struct X
{
char buf[100];
double rate;
uint32_t samples[1024];
};
template <typename T> using shared_alloc = bip::allocator<T,bip::managed_mapped_file::segment_manager>;
template <typename T> using shared_vector = boost::container::vector<T, shared_alloc<T> >;
template <typename K, typename V, typename P = std::pair<K,V>, typename Cmp = std::less<K> >
using shared_map = boost::container::flat_map<K, V, Cmp, shared_alloc<P> >;
using shared_string = bip::basic_string<char,std::char_traits<char>,shared_alloc<char> >;
using dataset_t = shared_map<shared_string, shared_vector<X> >;
struct mutex_remove
{
mutex_remove() { mutex_type::remove("7FD6D7E8-320B-11DC-82CF-39598D556B0E"); }
~mutex_remove(){ mutex_type::remove("7FD6D7E8-320B-11DC-82CF-39598D556B0E"); }
} remover;
static mutex_type mutex(bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-39598D556B0E");
static dataset_t& shared_instance()
{
bip::scoped_lock<mutex_type> lock(mutex);
static bip::managed_mapped_file seg(bip::open_or_create,"./demo.db", 50ul<<30);
static dataset_t* _instance = seg.find_or_construct<dataset_t>
("DATA")
(
std::less<shared_string>(),
dataset_t::allocator_type(seg.get_segment_manager())
);
static auto capacity = seg.get_free_memory();
std::cerr << "Free space: " << (capacity>>30) << "g\n";
return *_instance;
}
int main()
{
auto& db = shared_instance();
bip::scoped_lock<mutex_type> lock(mutex);
auto alloc = db.get_allocator().get_segment_manager();
std::cout << db.size() << '\n';
for (int i = 0; i < 1000; ++i)
{
std::string key_ = "item" + std::to_string(i);
shared_string key(alloc);
key.assign(key_.begin(), key_.end());
auto value = shared_vector<X>(alloc);
value.resize(size_t(rand()%(1ul<<9)));
auto entry = std::make_pair(key, value);
db.insert(std::make_pair(key, value));
}
}
请注意,它写入了一个50G的
稀疏文件。实际提交的大小取决于一些随机因素。我的运行结果大约是1.1G:
$ du -shc --apparent-size demo.db
50G demo.db
$ du -shc demo.db
1,1G demo.db
希望这能帮到您。