Data structures 在Rust中实现图形化数据结构

Data structures 在Rust中实现图形化数据结构,data-structures,rust,ownership,Data Structures,Rust,Ownership,我有一个数据结构,它可以表示为一些与链接对象链接的结构之间的单向图,因为链接包含元数据 它看起来像这样: struct StateMachine { resources: Vec<Resource>, links: Vec<Link>, } struct Resource { kind: ResourceType, // ... } enum LinkTarget { ResourceList(Vec<&Reso

我有一个数据结构,它可以表示为一些与链接对象链接的结构之间的单向图,因为链接包含元数据

它看起来像这样:

struct StateMachine {
    resources: Vec<Resource>,
    links: Vec<Link>,
}
struct Resource {
    kind: ResourceType,
      // ...
}

enum LinkTarget {
    ResourceList(Vec<&Resource>),
    LabelSelector(HashMap<String, String>),
}

struct Link {
    from: LinkTarget,
    to: LinkTarget,
    metadata: SomeMetadataStruct,
}
struct状态机{
资源:Vec,
链接:Vec,
}
结构资源{
种类:资源类型,
// ...
}
枚举链接目标{
资源列表(Vec),
标签选择器(HashMap),
}
结构链接{
发件人:LinkTarget,
致:LinkTarget,
元数据:SomeMetadataStruct,
}
整个结构需要是可变的,因为我需要能够在运行时添加和删除链接和资源。因此,我无法使用正常的生存期模型,并将资源绑定到父结构的生存期


我知道我需要选择合适的类型,但我不确定解决这个问题的最佳方法是什么。

实际上,对于类似图形的结构,最简单的解决方案是使用一个竞技场,例如

然后,节点的生存期将仅取决于创建它们的类型化竞技场实例的生存期,这将大大简化资源管理

警告:避免在图形中动态添加/删除节点的情况,因为在删除所述竞技场之前,节点不会从竞技场中删除,因此竞技场的大小将无限增长


如果要在运行时添加/删除节点,另一种解决方案是:

  • 收集
    资源
  • 边缘仅间接引用
    资源
    (不是所有者,也不是借款人)
两个例子:

  • HashMap
  • type R=RefCell
    Vec
    Vec
在这两种情况下,您都有责任在删除资源时清理边缘,遗忘可能会导致内存泄漏和恐慌(在取消引用时),但在其他情况下是安全的


上面可能有无限的变化。

在Rust中建模类似图形的结构不是一个简单的问题。 这里有两个来自Nick Cameron和Niko Matsakis(Mozilla的两个主要Rust开发人员)的宝贵讨论


对于类似图形的结构,最简单的解决方案是使用一个为图形建模的库。是一个不错的选择:

使用petgraph::Graph;//0.5.1
使用std::{collections::HashMap,rc::rc};
结构资源;
枚举链接目标{
资源列表(Vec),
标签选择器(HashMap),
}
struct SomeMetadataStruct;
fn main(){
让mut-graph=graph::new();
设n1=graph.add_节点(LinkTarget::LabelSelector(Default::Default());
设n2=graph.add_节点(LinkTarget::LabelSelector(Default::Default());
设_l2=图。添加_边(n1,n2,SomeMetadataStruct);
}
您必须在此处选择的保证以
资源列表的成员为中心。我假设您希望拥有单线程共享的不可变
资源
s

  • 如果需要跨线程共享它们,请使用
    Vec
  • 如果它们不共享,您可以拥有它们-
    Vec
  • 如果它们需要可变,请使用
    Vec
    (或
    互斥锁
    RwLock
    ,如果也是多线程的)

我添加和删除了许多节点,而应用程序是一个服务器进程,因此内存泄漏是一个问题。你知道另一个解决办法吗?同时,我将看一看另一个答案。@Aragon0:我添加了另一个设计思想,将资源和对其他资源的引用分离(不使用直接指针),这需要更多的簿记,但很安全。这看起来是个好主意!我可以处理更多的簿记,只要整个事情是安全和合理的快速。