From c5dca04ade7b285d01fe304f6ed7a1f88cc4d885 Mon Sep 17 00:00:00 2001 From: Herbert Wolverson Date: Wed, 8 Mar 2023 18:01:10 +0000 Subject: [PATCH] Update tree tracker RTT store to use a DashSet for lock-free access. --- src/rust/Cargo.lock | 1 + src/rust/lqos_config/Cargo.toml | 1 + src/rust/lqos_config/src/network_json/mod.rs | 19 ++++++++----------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index cb7294b0..61984859 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -1343,6 +1343,7 @@ name = "lqos_config" version = "0.1.0" dependencies = [ "csv", + "dashmap", "ip_network", "ip_network_table", "log", diff --git a/src/rust/lqos_config/Cargo.toml b/src/rust/lqos_config/Cargo.toml index 3a4d942c..96ea3779 100644 --- a/src/rust/lqos_config/Cargo.toml +++ b/src/rust/lqos_config/Cargo.toml @@ -14,3 +14,4 @@ ip_network = "0" sha2 = "0" uuid = { version = "1", features = ["v4", "fast-rng" ] } log = "0" +dashmap = "5" diff --git a/src/rust/lqos_config/src/network_json/mod.rs b/src/rust/lqos_config/src/network_json/mod.rs index 7ca5f805..d4fadb0b 100644 --- a/src/rust/lqos_config/src/network_json/mod.rs +++ b/src/rust/lqos_config/src/network_json/mod.rs @@ -1,10 +1,11 @@ use crate::etc; +use dashmap::DashSet; use log::{error, info, warn}; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use std::{ fs, - path::{Path, PathBuf}, sync::{atomic::AtomicU64, RwLock}, + path::{Path, PathBuf}, sync::atomic::AtomicU64, }; use thiserror::Error; @@ -23,7 +24,7 @@ pub struct NetworkJsonNode { /// Approximate RTTs reported for this level of the tree. /// It's never going to be as statistically accurate as the actual /// numbers, being based on medians. - pub rtts: RwLock>, + pub rtts: DashSet, /// A list of indices in the `NetworkJson` vector of nodes /// linking to parent nodes @@ -44,7 +45,7 @@ impl NetworkJsonNode { self.current_throughput.0.load(std::sync::atomic::Ordering::Relaxed), self.current_throughput.1.load(std::sync::atomic::Ordering::Relaxed), ), - rtts: self.rtts.read().unwrap().clone(), + rtts: self.rtts.iter().map(|n| *n as f32 / 100.0).collect(), parents: self.parents.clone(), immediate_parent: self.immediate_parent, } @@ -119,7 +120,7 @@ impl NetworkJson { current_throughput: (AtomicU64::new(0), AtomicU64::new(0)), parents: Vec::new(), immediate_parent: None, - rtts: RwLock::new(Vec::new()), + rtts: DashSet::new(), }]; if !Self::exists() { return Err(NetworkJsonError::FileNotFound); @@ -192,11 +193,7 @@ impl NetworkJson { self.nodes.iter().for_each(|n| { n.current_throughput.0.store(0, std::sync::atomic::Ordering::Relaxed); n.current_throughput.1.store(0, std::sync::atomic::Ordering::Relaxed); - let mut size = n.rtts.read().unwrap().len(); - while size > 5 { - n.rtts.write().unwrap().remove(0); - size = n.rtts.read().unwrap().len(); - } + n.rtts.clear(); }); } @@ -225,7 +222,7 @@ impl NetworkJson { for idx in targets { // Safety first: use "get" to ensure that the node exists if let Some(node) = self.nodes.get(*idx) { - node.rtts.write().unwrap().push(rtt); + node.rtts.insert((rtt * 100.0) as u16); } else { warn!("No network tree entry for index {idx}"); } @@ -269,7 +266,7 @@ fn recurse_node( current_throughput: (AtomicU64::new(0), AtomicU64::new(0)), name: name.to_string(), immediate_parent: Some(immediate_parent), - rtts: RwLock::new(Vec::new()), + rtts: DashSet::new(), }; if node.name != "children" {