use super::next_id;
use crate::{
db::{
api::{mutation::AdditionOps, view::*},
graph::graph::Graph,
},
prelude::{NodeStateOps, NO_PROPS},
};
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
use raphtory_api::core::storage::timeindex::AsTime;
use tracing::error;
pub fn random_attachment(
graph: &Graph,
nodes_to_add: usize,
edges_per_step: usize,
seed: Option<[u8; 32]>,
) {
let mut rng: StdRng;
if let Some(seed_value) = seed {
rng = StdRng::from_seed(seed_value);
} else {
rng = StdRng::from_entropy();
}
let mut latest_time = graph.latest_time().map_or(0, |t| t.t());
let mut ids = graph.nodes().id().iter_values().collect::<Vec<_>>();
let mut max_id = next_id(graph, ids.iter().max().cloned());
while ids.len() < edges_per_step {
max_id = next_id(graph, Some(max_id));
latest_time += 1;
graph
.add_node(latest_time, &max_id, NO_PROPS, None)
.map_err(|err| error!("{:?}", err))
.ok();
ids.push(max_id.clone());
}
for _ in 0..nodes_to_add {
let edges = ids.choose_multiple(&mut rng, edges_per_step);
max_id = next_id(graph, Some(max_id));
latest_time += 1;
edges.for_each(|neighbour| {
graph
.add_edge(latest_time, &max_id, neighbour, NO_PROPS, None)
.expect("Not able to add edge");
});
ids.push(max_id.clone());
}
}
#[cfg(test)]
mod random_graph_test {
use super::*;
use crate::graphgen::preferential_attachment::ba_preferential_attachment;
use raphtory_api::core::utils::logging::global_info_logger;
#[test]
fn blank_graph() {
let graph = Graph::new();
random_attachment(&graph, 100, 20, None);
assert_eq!(graph.count_edges(), 2000);
assert_eq!(graph.count_nodes(), 120);
}
#[test]
fn only_nodes() {
global_info_logger();
let graph = Graph::new();
for i in 0..10 {
graph
.add_node(i, i as u64, NO_PROPS, None)
.map_err(|err| error!("{:?}", err))
.ok();
}
random_attachment(&graph, 1000, 5, None);
assert_eq!(graph.count_edges(), 5000);
assert_eq!(graph.count_nodes(), 1010);
}
#[test]
fn prior_graph() {
let graph = Graph::new();
ba_preferential_attachment(&graph, 300, 7, None);
random_attachment(&graph, 4000, 12, None);
assert_eq!(graph.count_edges(), 50106);
assert_eq!(graph.count_nodes(), 4307);
}
}