Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Last active February 2, 2024 10:41
Show Gist options
  • Save jweinst1/280433f8bc9cbc9d0379d44b8befbb51 to your computer and use it in GitHub Desktop.
Save jweinst1/280433f8bc9cbc9d0379d44b8befbb51 to your computer and use it in GitHub Desktop.
sample graph object in rust
use std::rc::Rc;
use std::sync::{RwLock, Arc};
use std::thread;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fmt;
use std::clone::Clone;
#[derive(Debug)]
#[derive(Eq, Hash, PartialEq)]
struct Relation(String);
impl Clone for Relation {
fn clone(&self) -> Self {
Relation(self.0.clone())
}
}
#[derive(Debug)]
#[derive(Eq, Hash, PartialEq)]
struct Pairing(String, String);
impl Clone for Pairing {
fn clone(&self) -> Self {
Pairing(self.0.clone(), self.1.clone())
}
}
#[derive(Debug)]
#[derive(Eq, Hash, PartialEq)]
struct Relationship {
objects:Pairing,
relation:Relation
}
impl Relationship {
fn from_strs(obj1:&str, rel:&str, obj2:&str) -> Self {
Relationship{relation:Relation(rel.to_string()), objects:Pairing(obj1.to_string(), obj2.to_string())}
}
fn cmp_relation(&self, rel:&Relation) -> bool {
self.relation == *rel
}
}
impl Clone for Relationship {
fn clone(&self) -> Self {
Relationship{objects:self.objects.clone(), relation:self.relation.clone()}
}
}
impl fmt::Display for Relationship {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} <-{}-> {}", self.objects.0, self.relation.0, self.objects.1)
}
}
fn remove_relationship(r:Rc<Relationship>, vec:&mut Vec<Rc<Relationship>>) -> bool {
// trick to have linear complexity with swap_remove
let mut neg = 0;
for i in 0..vec.len() {
if vec[i - neg] == r {
vec.swap_remove(i);
neg += 1;
}
}
vec.len() > 0
}
#[derive(Debug)]
struct Graph {
irelations:HashMap<Relation, Vec<Rc<Relationship>>>,
ipairings:HashMap<String, Vec<Rc<Relationship>>>,
global:HashSet<Rc<Relationship>>
}
impl Graph {
fn new() -> Self {
Graph{irelations:HashMap::new(), ipairings:HashMap::new(), global:HashSet::new()}
}
fn size(&self) -> usize {
self.global.len()
}
fn get_relation(&self, rel:&Relation, vec:&mut Vec<Rc<Relationship>>) {
match self.irelations.get(rel) {
Some(v) => for elem in v.iter() {
if elem.cmp_relation(rel) {
vec.push(Rc::clone(elem))
}
}
None => ()
}
}
fn insert(&mut self, r:Relationship) {
match self.global.get(&r) {
Some(_) => return,
None => ()
}
let relation = r.relation.clone();
let pair = r.objects.clone();
let obj = Rc::new(r);
match self.irelations.get_mut(&relation) {
Some(v) => {v.push(Rc::clone(&obj));},
None => { self.irelations.insert(relation, vec![Rc::clone(&obj)]); }
}
match self.ipairings.get_mut(&pair.0) {
Some(v) => {v.push(Rc::clone(&obj));},
None => { self.ipairings.insert(pair.0, vec![Rc::clone(&obj)]); }
}
match self.ipairings.get_mut(&pair.1) {
Some(v) => {v.push(Rc::clone(&obj));},
None => { self.ipairings.insert(pair.1, vec![Rc::clone(&obj)]); }
}
self.global.insert(Rc::clone(&obj));
}
fn remove(&mut self, r:Relationship) {
let relation = r.relation.clone();
let pair = r.objects.clone();
let obj = Rc::new(r);
match self.irelations.get_mut(&relation) {
Some(v) => { if !remove_relationship(Rc::clone(&obj), v) { self.irelations.remove(&relation); }},
None => { }
}
match self.ipairings.get_mut(&pair.0) {
Some(v) => {if !remove_relationship(Rc::clone(&obj), v) { self.ipairings.remove(&pair.0); }},
None => { }
}
match self.ipairings.get_mut(&pair.1) {
Some(v) => {if !remove_relationship(Rc::clone(&obj), v) { self.ipairings.remove(&pair.1); }},
None => { }
}
self.global.remove(&obj);
}
}
fn main() {
let mut test = vec![1, 2, 3];
test.swap_remove(1);
for i in 0..test.len() {
println!("{:?}, {:?}", i, test[i]);
}
let r = Relationship::from_strs("amy", "bought", "pie");
let gg = Relationship::from_strs("george", "bought", "fruit");
let r2 = r.clone();
let mut g = Graph::new();
g.insert(r);
g.insert(r2);
g.insert(gg);
println!("{:?}", g);
let m = Relationship::from_strs("amy", "bought", "pie");
g.remove(m);
println!("{:?}", g);
let gg_rel = Relation("bought".to_string());
let mut lst = Vec::new();
g.get_relation(&gg_rel, &mut lst);
println!("{:?}", lst);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment