【问题标题】:using a disk allocator for std::deque为 std::deque 使用磁盘分配器
【发布时间】:2021-09-12 17:25:59
【问题描述】:

如何将 std::deque 的内容存储到磁盘上?我发现你可以指定一个分配器,即

std::deque<std::unique_ptr<my_struct>>, disk_allocator<std::unique_ptr<my_struct>>> q;

如何编写自定义分配器“disk_allocator”以存储在磁盘上?标准库中是否已经存在一个?

【问题讨论】:

  • 你的问题范围很大。答案部分可能不足以解释编写虚拟内存映射分配器所涉及的所有内容。最好问一个更具体的问题。
  • 例如,您在编写分配器的哪个部分遇到了问题?您是否查阅过任何解释分配器如何工作的文档?
  • 不,标准库中没有这样的分配器。
  • 您是否考虑过对数据进行序列化?如果你只想要内容,那应该容易得多。但仍然是一个很大的话题。
  • 你可以试试 STXXL 库 (stxxl.org) - 它不支持双端队列,但你可能会找到另一个合适的容器。

标签: c++ memory std


【解决方案1】:

你可以选择metal。明确地建议一个库有点尴尬,因为这是一个巨大的话题,为了确保解决方案能满足您的需求,深入研究分配器、内存映射、持久性、序列化和朋友们(我在问题 cmets 中链接了有关这些主题的资源)。

也就是说,金属会这样使用:

// Example for deque<int>
using namespace metall;
namespace mc = metall::container;
using deque_t = deque<int, metall::allocator<int>>;

void create_data()
{
  manager mg(create_only, "/tmp/dir");
  // storage location      ^^^^^^^^ 

  deque_t* p = mg.construct<deque_t>("deque")(mg.get_allocator());
  p->push_back(10); // Can use it normally
}

void reattach_data()
{
  manager mg(create_only, "/tmp/dir");
  // storage location      ^^^^^^^^ 

  deque_t* p = mg.find<deque_t>("deque").first;
  p->push_back(10); // Can resume work
}

您可以查看相关的examples 以了解标准库的互操作性。

如果您愿意使用序列化,cereal 可以绑定大多数标准库容器,包括 deque

【讨论】:

    【解决方案2】:

    您不能从磁盘分配以便与std::deque 一起使用。至少这不是我们将 STL Container 数据存储到磁盘中的方式。 STL Allocators' 的工作是封装对象的访问/寻址、分配/释放以及构造/销毁的策略。

    为了在磁盘中存储简单的容器数据,我们可以这样做:
    用于复制/粘贴和测试:serialize_deserialize_example

    template<typename Container>
    void save_to_disk(Container const& container, std::filesystem::path const& path)
    {
        std::ofstream output(path);
        if(!output.is_open())
        {
            throw std::runtime_error("Couldn't open file: " + path.string());
        }
    
        for(auto const& item : container)
        {
            output << item << std::endl;
        }
    }
    

    但显然,我们并不总是必须简单的数据结构才能简单地转换为字符串并返回。对于 STL 容器的序列化,我建议使用 Boost.Serialization:
    进行复制/粘贴和测试:boost_serialize_deserialize

    struct my_structure final
    {
        friend class boost::serialization::access;
    
        std::deque<std::string> data;
    
        template<class Archive>
        void serialize(Archive& ar, unsigned int const)
        {
            ar& data;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2015-01-05
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多