graph - 拥有的arena数据结构

标签 graph rust lifetime ownership

<分区>

我想对一个非常大(节点数)的图建模,该图由许多非常大(内存方面)的节点组成。由于节点如此之大,我只想将它们存储一次并将借用传递给它们,所以在概念上是这样的:

struct Graph<'a> {
    nodes: Vec<Node<'a>>,
}

struct Node<'a> {
    edges: HashMap<String, &'a Node>,
    // ...lots of other data...
}

当然没有办法像这样构造一个Graph因为(a)Vec不允许我在元素借用时添加新节点, (b) 我不能告诉 rustc nodes 向量将在 'a 的生命周期内存在。我也不能使用像 Rc 这样的东西,因为图形有循环。

我希望能够表达的是某种竞技场,它让我可以分配很多 Node,只要竞技场存在,就向它们进行不可变借用,并使用生命周期检查以确保在取消分配竞技场时我没有剩余的 Node 引用。像这样的东西:

struct Graph<'a> {
    nodes: Arena<'a, Node<'a>>,
}

struct Node<'a> {
    edges: HashMap<String, &'a Node>,
}

impl<'a, A> Arena<'a, A> {
    fn own(&self, a: A) -> &'a A {
        // magic
    }
}

impl<'a, A> Drop for Arena<'a, A> {
    fn drop(&'a mut self) {
        // magic
    }
}

这在语义上可以用 Rust 表达吗?

最佳答案

一个简单的首选解决方案是使用 typed-arena箱。它包含一个 Arena 类型和一个 fn alloc(&self, T) -> &mut T 方法。

另一个简单的解决方案是使用索引而不是引用(永远不要从 Vec 中删除,因为这会使索引无效)。在 64 位平台上,使用 32 位索引可以减少一些字节。

但是,这两种解决方案都无法删除 节点。您可以停止引用它们,但它们仍将存在于内存中,因此将它们用于动态图(节点来来去去)需要更多的工作。在这种情况下,我的建议是定期从一个新的领域创建一个新的图形克隆(而不是复制未使用的节点),这类似于使用移动垃圾收集器,如果不那么自动的话。

关于graph - 拥有的arena数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35734306/

相关文章:

python - Django 模型图 (pydot) 错误

rust - 如何统一结构和特征之间的生命周期?

java - 为什么小程序不能正确绘制三角函数的图形?

mysql - 获取数据子集到 qplot

pointers - 如何使用指针算法获取向量中元素的索引?

list - 如何在这个简单的双向链表实现中修复 SIGSEGV?

rust - 如何使用功能标志运行 cargo

c++ - 在 lambda 中通过引用捕获的对象的生命周期

rust - 为什么不能在同一结构中存储值和对该值的引用?

java - 如何创建Mind42.com的树形图?