Skip to content

Commit

Permalink
start moving global ids to GID
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianmurariu committed Jul 18, 2024
1 parent e5eab5d commit bd9c124
Show file tree
Hide file tree
Showing 34 changed files with 318 additions and 224 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions raphtory-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rayon = { workspace = true }
rand = { workspace = true }
quickcheck = { workspace = true }
quickcheck_macros = { workspace = true }
num-traits = { workspace = true }
twox-hash.workspace = true

[dev-dependencies]
Expand Down
137 changes: 137 additions & 0 deletions raphtory-api/src/core/entities/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
use std::borrow::Cow;

#[cfg(feature = "python")]
use pyo3::FromPyObject;
#[cfg(feature = "python")]
use pyo3::{exceptions::PyTypeError, PyAny, PyResult};
use serde::{Deserialize, Serialize};

use self::edges::edge_ref::EdgeRef;
use num_traits::cast::ToPrimitive;

use super::input::input_node::parse_u64_strict;

pub mod edges;

Expand Down Expand Up @@ -85,3 +94,131 @@ impl EID {
EID(id as usize)
}
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
pub enum GID {
U64(u64),
I64(i64),
Str(String),
}

impl Default for GID {
fn default() -> Self {
GID::U64(0)
}
}

#[cfg(feature = "python")]
impl<'source> FromPyObject<'source> for GID {
fn extract(id: &'source PyAny) -> PyResult<Self> {
id.extract::<String>()
.map(GID::Str)
.or_else(|_| {
id.extract::<i64>()
.map(GID::I64)
.or_else(|_| id.extract::<u64>().map(GID::U64))
})
.map_err(|err| {
let msg = "IDs need to be strings or an unsigned integers";
PyTypeError::new_err(msg)
})
}
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum GidRef<'a> {
U64(u64),
I64(i64),
Str(&'a str),
}

impl GID {
pub fn into_str(self) -> Option<String> {
match self {
GID::Str(v) => Some(v),
_ => None,
}
}

pub fn into_i64(self) -> Option<i64> {
match self {
GID::I64(v) => Some(v),
_ => None,
}
}

pub fn into_u64(self) -> Option<u64> {
match self {
GID::U64(v) => Some(v),
_ => None,
}
}

pub fn as_str(&self) -> Option<&str> {
match self {
GID::Str(v) => Some(v.as_str()),
_ => None,
}
}

pub fn as_i64(&self) -> Option<i64> {
match self {
GID::I64(v) => Some(*v),
_ => None,
}
}

pub fn as_u64(&self) -> Option<u64> {
match self {
GID::U64(v) => Some(*v),
_ => None,
}
}

pub fn to_str(&self) -> Cow<String> {
match self {
GID::U64(v) => Cow::Owned(v.to_string()),
GID::I64(v) => Cow::Owned(v.to_string()),
GID::Str(v) => Cow::Borrowed(v),
}
}

pub fn to_i64(&self) -> Option<i64> {
match self {
GID::U64(v) => v.to_i64(),
GID::I64(v) => Some(*v),
GID::Str(v) => parse_u64_strict(v)?.to_i64(),
}
}

pub fn to_u64(&self) -> Option<u64> {
match self {
GID::U64(v) => Some(*v),
GID::I64(v) => v.to_u64(),
GID::Str(v) => parse_u64_strict(v),
}
}
}

impl From<u64> for GID {
fn from(id: u64) -> Self {
Self::U64(id)
}
}

impl From<i64> for GID {
fn from(id: i64) -> Self {
Self::I64(id)
}
}

impl From<String> for GID {
fn from(id: String) -> Self {
Self::Str(id)
}
}

impl From<&str> for GID {
fn from(id: &str) -> Self {
Self::Str(id.to_string())
}
}
16 changes: 9 additions & 7 deletions raphtory/src/algorithms/community_detection/label_propagation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ pub fn label_propagation<G>(
where
G: StaticGraphViewOps,
{
let mut labels: HashMap<NodeView<G>, u64> = HashMap::new();
for node in graph.nodes() {
labels.insert(node.clone(), node.id());
let mut labels: HashMap<NodeView<&G>, u64> = HashMap::new();
let nodes = graph.nodes();
for node in nodes.iter() {
let id = node.id();
labels.insert(node, id);
}

let nodes = graph.nodes();
let mut shuffled_nodes: Vec<NodeView<G>> = nodes.iter().collect();
let mut shuffled_nodes: Vec<NodeView<_>> = nodes.iter().collect();
if let Some(seed_value) = seed {
let mut rng = StdRng::from_seed(seed_value);
shuffled_nodes.shuffle(&mut rng);
Expand All @@ -46,12 +48,12 @@ where
let mut label_count: BTreeMap<u64, f64> = BTreeMap::new();

for neighbour in neighbors {
*label_count.entry(labels[&neighbour.clone()]).or_insert(0.0) += 1.0;
*label_count.entry(labels[&neighbour]).or_insert(0.0) += 1.0;
}

if let Some(max_label) = find_max_label(&label_count) {
if max_label != labels[node] {
labels.insert(node.clone(), max_label);
labels.insert(*node, max_label);
changed = true;
}
}
Expand All @@ -61,7 +63,7 @@ where
// Group nodes by their labels to form communities
let mut communities: HashMap<u64, HashSet<NodeView<G>>> = HashMap::new();
for (node, label) in labels {
communities.entry(label).or_default().insert(node.clone());
communities.entry(label).or_default().insert(node.cloned());
}

Ok(communities.values().cloned().collect())
Expand Down
12 changes: 4 additions & 8 deletions raphtory/src/algorithms/community_detection/modularity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,10 @@ impl ModularityFunction for ModularityUnDir {
tol: f64,
) -> Self {
let _n = graph.count_nodes();
let local_id_map: HashMap<_, _> = graph
.nodes()
.iter()
.enumerate()
.map(|(i, n)| (n, VID(i)))
.collect();
let adj: Vec<_> = graph
.nodes()
let nodes = graph.nodes();
let local_id_map: HashMap<_, _> =
nodes.iter().enumerate().map(|(i, n)| (n, VID(i))).collect();
let adj: Vec<_> = nodes
.iter()
.map(|node| {
node.edges()
Expand Down
2 changes: 1 addition & 1 deletion raphtory/src/algorithms/components/connected_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ where
let min_neighbour_id = vv.neighbours().id().min();
let id = vv.id();
let state: &mut WccState = vv.get_mut();
state.component = cmp::min(min_neighbour_id.unwrap_or(id), id);
state.component = min_neighbour_id.unwrap_or(id).min(id);
Step::Continue
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ pub fn cohesive_fruchterman_reingold<'graph, G: GraphViewOps<'graph>>(
.max()
.unwrap_or(0); // Default to 0 if there are no nodes

let nodes_with_max_degree: Vec<_> = virtual_graph
.nodes()
let nodes = &virtual_graph.nodes();
let nodes_with_max_degree: Vec<_> = nodes
.iter()
.filter(|node| node.degree() == max_degree)
.collect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub fn temporal_bipartite_projection<G: StaticGraphViewOps>(
pivot_type: String,
) -> Graph {
let new_graph = Graph::new();
let nodes = graph
.nodes()
let nodes = graph.nodes();
let nodes = nodes
.iter()
.filter(|v| v.node_type().unwrap() == pivot_type);
for v in nodes {
Expand Down
11 changes: 4 additions & 7 deletions raphtory/src/core/entities/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ pub(crate) mod timer;
#[cfg(test)]
mod test {
use crate::{
core::{
entities::{graph::tgraph::TemporalGraph, LayerIds},
Direction, PropType,
},
core::PropType,
db::api::{mutation::internal::InternalAdditionOps, storage::storage_ops::GraphStorage},
prelude::*,
};
Expand All @@ -19,8 +16,8 @@ mod test {
let l_btc = g.resolve_layer(Some("btc"));
let l_eth = g.resolve_layer(Some("eth"));
let l_tether = g.resolve_layer(Some("tether"));
let v1 = g.resolve_node(1, None);
let v2 = g.resolve_node(2, None);
let v1 = g.resolve_node(1).unwrap();
let v2 = g.resolve_node(2).unwrap();
let tx_sent_id = g
.resolve_edge_property("tx_sent", PropType::I32, false)
.unwrap();
Expand Down Expand Up @@ -74,7 +71,7 @@ mod test {
let ns = v
.neighbours()
.into_iter()
.map(|n| n.id())
.filter_map(|n| n.id().as_u64())
.collect::<Vec<_>>();
assert_eq!(ns, [v2, v3]);
}
Expand Down
Loading

0 comments on commit bd9c124

Please sign in to comment.