prefer btreemap over hashmap

This commit is contained in:
Aiden McClelland
2021-09-28 14:00:45 -06:00
parent 79db44e34f
commit 08df3dc65d
16 changed files with 103 additions and 83 deletions

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::time::Duration; use std::time::Duration;
use anyhow::anyhow; use anyhow::anyhow;
@@ -37,7 +37,7 @@ fn err_to_500(e: Error) -> Response<Body> {
async fn inner_main( async fn inner_main(
cfg_path: Option<&str>, cfg_path: Option<&str>,
log_level: LevelFilter, log_level: LevelFilter,
module_logging: HashMap<String, LevelFilter>, module_logging: BTreeMap<String, LevelFilter>,
) -> Result<Option<Shutdown>, Error> { ) -> Result<Option<Shutdown>, Error> {
let rpc_ctx = RpcContext::init(cfg_path, log_level, module_logging).await?; let rpc_ctx = RpcContext::init(cfg_path, log_level, module_logging).await?;
let mut shutdown_recv = rpc_ctx.shutdown.subscribe(); let mut shutdown_recv = rpc_ctx.shutdown.subscribe();
@@ -282,7 +282,7 @@ fn main() {
.expect(&format!("Invalid 'log-module' argument: {}", l)), .expect(&format!("Invalid 'log-module' argument: {}", l)),
) )
}) })
.collect::<HashMap<_, LevelFilter>>(); .collect::<BTreeMap<_, LevelFilter>>();
let cfg_path = matches.value_of("config"); let cfg_path = matches.value_of("config");
let res = { let res = {

View File

@@ -1,5 +1,5 @@
use std::borrow::{Borrow, Cow}; use std::borrow::{Borrow, Cow};
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, BTreeSet};
use std::fmt; use std::fmt;
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@@ -46,7 +46,7 @@ pub trait ValueSpec {
value: &mut Value, value: &mut Value,
) -> Result<(), ConfigurationError>; ) -> Result<(), ConfigurationError>;
// returns all pointers that are live in the provided config // returns all pointers that are live in the provided config
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath>; fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath>;
// requires returns whether the app id is the target of a pointer within it // requires returns whether the app id is the target of a pointer within it
fn requires(&self, id: &PackageId, value: &Value) -> bool; fn requires(&self, id: &PackageId, value: &Value) -> bool;
// defines if 2 values of this type are equal for the purpose of uniqueness // defines if 2 values of this type are equal for the purpose of uniqueness
@@ -165,7 +165,7 @@ where
.update(ctx, db, manifest, config_overrides, value) .update(ctx, db, manifest, config_overrides, value)
.await .await
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
self.inner.pointers(value) self.inner.pointers(value)
} }
fn requires(&self, id: &PackageId, value: &Value) -> bool { fn requires(&self, id: &PackageId, value: &Value) -> bool {
@@ -209,7 +209,7 @@ where
.update(ctx, db, manifest, config_overrides, value) .update(ctx, db, manifest, config_overrides, value)
.await .await
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
self.inner.pointers(value) self.inner.pointers(value)
} }
fn requires(&self, id: &PackageId, value: &Value) -> bool { fn requires(&self, id: &PackageId, value: &Value) -> bool {
@@ -286,7 +286,7 @@ where
.update(ctx, db, manifest, config_overrides, value) .update(ctx, db, manifest, config_overrides, value)
.await .await
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
self.inner.pointers(value) self.inner.pointers(value)
} }
fn requires(&self, id: &PackageId, value: &Value) -> bool { fn requires(&self, id: &PackageId, value: &Value) -> bool {
@@ -407,7 +407,7 @@ impl ValueSpec for ValueSpecAny {
ValueSpecAny::Pointer(a) => a.update(ctx, db, manifest, config_overrides, value).await, ValueSpecAny::Pointer(a) => a.update(ctx, db, manifest, config_overrides, value).await,
} }
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
match self { match self {
ValueSpecAny::Boolean(a) => a.pointers(value), ValueSpecAny::Boolean(a) => a.pointers(value),
ValueSpecAny::Enum(a) => a.pointers(value), ValueSpecAny::Enum(a) => a.pointers(value),
@@ -492,8 +492,8 @@ impl ValueSpec for ValueSpecBoolean {
) -> Result<(), ConfigurationError> { ) -> Result<(), ConfigurationError> {
Ok(()) Ok(())
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
Ok(HashSet::new()) Ok(BTreeSet::new())
} }
fn requires(&self, _id: &PackageId, _value: &Value) -> bool { fn requires(&self, _id: &PackageId, _value: &Value) -> bool {
false false
@@ -581,8 +581,8 @@ impl ValueSpec for ValueSpecEnum {
) -> Result<(), ConfigurationError> { ) -> Result<(), ConfigurationError> {
Ok(()) Ok(())
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
Ok(HashSet::new()) Ok(BTreeSet::new())
} }
fn requires(&self, _id: &PackageId, _value: &Value) -> bool { fn requires(&self, _id: &PackageId, _value: &Value) -> bool {
false false
@@ -685,8 +685,8 @@ where
))) )))
} }
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
Ok(HashSet::new()) Ok(BTreeSet::new())
} }
fn requires(&self, id: &PackageId, value: &Value) -> bool { fn requires(&self, id: &PackageId, value: &Value) -> bool {
if let Value::Array(ref ls) = value { if let Value::Array(ref ls) = value {
@@ -780,7 +780,7 @@ impl ValueSpec for ValueSpecList {
ValueSpecList::Union(a) => a.update(ctx, db, manifest, config_overrides, value).await, ValueSpecList::Union(a) => a.update(ctx, db, manifest, config_overrides, value).await,
} }
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
match self { match self {
ValueSpecList::Enum(a) => a.pointers(value), ValueSpecList::Enum(a) => a.pointers(value),
ValueSpecList::Number(a) => a.pointers(value), ValueSpecList::Number(a) => a.pointers(value),
@@ -898,8 +898,8 @@ impl ValueSpec for ValueSpecNumber {
) -> Result<(), ConfigurationError> { ) -> Result<(), ConfigurationError> {
Ok(()) Ok(())
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
Ok(HashSet::new()) Ok(BTreeSet::new())
} }
fn requires(&self, _id: &PackageId, _value: &Value) -> bool { fn requires(&self, _id: &PackageId, _value: &Value) -> bool {
false false
@@ -969,7 +969,7 @@ impl ValueSpec for ValueSpecObject {
))) )))
} }
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
if let Value::Object(o) = value { if let Value::Object(o) = value {
self.spec.pointers(o) self.spec.pointers(o)
} else { } else {
@@ -1080,17 +1080,17 @@ impl ConfigSpec {
Ok(()) Ok(())
} }
pub fn pointers(&self, cfg: &Config) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { pub fn pointers(&self, cfg: &Config) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
cfg.iter() cfg.iter()
.filter_map(|(k, v)| self.0.get(k).map(|vs| (k, vs.pointers(v)))) .filter_map(|(k, v)| self.0.get(k).map(|vs| (k, vs.pointers(v))))
.fold(Ok(HashSet::<ValueSpecPointer>::new()), |acc, v| { .fold(Ok(BTreeSet::<ValueSpecPointer>::new()), |acc, v| {
match (acc, v) { match (acc, v) {
// propagate existing errors // propagate existing errors
(Err(e), _) => Err(e), (Err(e), _) => Err(e),
// create new error case // create new error case
(Ok(_), (k, Err(e))) => Err(e.prepend(k.clone())), (Ok(_), (k, Err(e))) => Err(e.prepend(k.clone())),
// combine sets // combine sets
(Ok(s0), (_, Ok(s1))) => Ok(HashSet::from_iter(s0.union(&s1).cloned())), (Ok(s0), (_, Ok(s1))) => Ok(BTreeSet::from_iter(s0.union(&s1).cloned())),
} }
}) })
} }
@@ -1157,8 +1157,8 @@ impl ValueSpec for ValueSpecString {
) -> Result<(), ConfigurationError> { ) -> Result<(), ConfigurationError> {
Ok(()) Ok(())
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
Ok(HashSet::new()) Ok(BTreeSet::new())
} }
fn requires(&self, _id: &PackageId, _value: &Value) -> bool { fn requires(&self, _id: &PackageId, _value: &Value) -> bool {
false false
@@ -1388,7 +1388,7 @@ impl ValueSpec for ValueSpecUnion {
))) )))
} }
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
if let Value::Object(o) = value { if let Value::Object(o) = value {
match o.get(&self.tag.id) { match o.get(&self.tag.id) {
None => Err(NoMatchWithPath::new(MatchError::MissingTag( None => Err(NoMatchWithPath::new(MatchError::MissingTag(
@@ -1461,7 +1461,7 @@ impl DefaultableWith for ValueSpecUnion {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(tag = "subtype")] #[serde(tag = "subtype")]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub enum ValueSpecPointer { pub enum ValueSpecPointer {
@@ -1517,8 +1517,8 @@ impl ValueSpec for ValueSpecPointer {
} }
} }
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
let mut pointers = HashSet::new(); let mut pointers = BTreeSet::new();
pointers.insert(self.clone()); pointers.insert(self.clone());
Ok(pointers) Ok(pointers)
} }
@@ -1533,7 +1533,7 @@ impl ValueSpec for ValueSpecPointer {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(tag = "target")] #[serde(tag = "target")]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub enum PackagePointerSpec { pub enum PackagePointerSpec {
@@ -1614,8 +1614,8 @@ impl ValueSpec for PackagePointerSpec {
*value = self.deref(ctx, db, manifest, config_overrides).await?; *value = self.deref(ctx, db, manifest, config_overrides).await?;
Ok(()) Ok(())
} }
fn pointers(&self, _value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, _value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
let mut pointers = HashSet::new(); let mut pointers = BTreeSet::new();
pointers.insert(ValueSpecPointer::Package(self.clone())); pointers.insert(ValueSpecPointer::Package(self.clone()));
Ok(pointers) Ok(pointers)
} }
@@ -1627,7 +1627,7 @@ impl ValueSpec for PackagePointerSpec {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct TorAddressPointer { pub struct TorAddressPointer {
package_id: PackageId, package_id: PackageId,
@@ -1658,7 +1658,7 @@ impl fmt::Display for TorAddressPointer {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct LanAddressPointer { pub struct LanAddressPointer {
package_id: PackageId, package_id: PackageId,
@@ -1688,7 +1688,7 @@ impl LanAddressPointer {
Ok(addr.to_owned().map(Value::String).unwrap_or(Value::Null)) Ok(addr.to_owned().map(Value::String).unwrap_or(Value::Null))
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub struct ConfigPointer { pub struct ConfigPointer {
package_id: PackageId, package_id: PackageId,
@@ -1805,13 +1805,23 @@ impl PartialEq for ConfigSelector {
} }
} }
impl Eq for ConfigSelector {} impl Eq for ConfigSelector {}
impl PartialOrd for ConfigSelector {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.src.partial_cmp(&other.src)
}
}
impl Ord for ConfigSelector {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.src.cmp(&other.src)
}
}
impl Hash for ConfigSelector { impl Hash for ConfigSelector {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.src.hash(state) self.src.hash(state)
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[serde(tag = "target")] #[serde(tag = "target")]
pub struct TorKeyPointer { pub struct TorKeyPointer {
@@ -1849,7 +1859,7 @@ impl fmt::Display for TorKeyPointer {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[serde(tag = "target")] #[serde(tag = "target")]
pub enum SystemPointerSpec {} pub enum SystemPointerSpec {}
@@ -1892,8 +1902,8 @@ impl ValueSpec for SystemPointerSpec {
*value = self.deref(db).await?; *value = self.deref(db).await?;
Ok(()) Ok(())
} }
fn pointers(&self, value: &Value) -> Result<HashSet<ValueSpecPointer>, NoMatchWithPath> { fn pointers(&self, value: &Value) -> Result<BTreeSet<ValueSpecPointer>, NoMatchWithPath> {
let mut pointers = HashSet::new(); let mut pointers = BTreeSet::new();
pointers.insert(ValueSpecPointer::System(self.clone())); pointers.insert(ValueSpecPointer::System(self.clone()));
Ok(pointers) Ok(pointers)
} }

View File

@@ -1,5 +1,5 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::{HashMap, VecDeque}; use std::collections::{BTreeMap, VecDeque};
use std::net::{IpAddr, SocketAddr}; use std::net::{IpAddr, SocketAddr};
use std::ops::Deref; use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@@ -130,7 +130,7 @@ impl RpcContext {
pub async fn init<P: AsRef<Path>>( pub async fn init<P: AsRef<Path>>(
cfg_path: Option<P>, cfg_path: Option<P>,
log_level: LevelFilter, log_level: LevelFilter,
module_logging: HashMap<String, LevelFilter>, module_logging: BTreeMap<String, LevelFilter>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let base = RpcContextConfig::load(cfg_path).await?; let base = RpcContextConfig::load(cfg_path).await?;
let log_epoch = Arc::new(AtomicU64::new(rand::random())); let log_epoch = Arc::new(AtomicU64::new(rand::random()));

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use std::path::Path; use std::path::Path;
use anyhow::anyhow; use anyhow::anyhow;

View File

@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, BTreeSet};
use std::io::SeekFrom; use std::io::SeekFrom;
use std::path::Path; use std::path::Path;
use std::process::Stdio; use std::process::Stdio;
@@ -606,7 +606,7 @@ pub async fn install_s9pk<R: AsyncRead + AsyncSeek + Unpin>(
current_dependents current_dependents
.keys() .keys()
.chain(prev.current_dependents.keys()) .chain(prev.current_dependents.keys())
.collect::<HashSet<_>>(), .collect::<BTreeSet<_>>(),
) )
.await?; .await?;
let mut configured = prev.status.configured; let mut configured = prev.status.configured;

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::future::Future; use std::future::Future;
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use std::sync::Arc; use std::sync::Arc;
@@ -21,7 +21,7 @@ use crate::util::{Container, NonDetachingJoinHandle, Version};
use crate::Error; use crate::Error;
#[derive(Default)] #[derive(Default)]
pub struct ManagerMap(RwLock<HashMap<(PackageId, Version), Arc<Manager>>>); pub struct ManagerMap(RwLock<BTreeMap<(PackageId, Version), Arc<Manager>>>);
impl ManagerMap { impl ManagerMap {
pub async fn init<Db: DbHandle, Ex>( pub async fn init<Db: DbHandle, Ex>(
&self, &self,
@@ -32,7 +32,7 @@ impl ManagerMap {
where where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>, for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{ {
let mut res = HashMap::new(); let mut res = BTreeMap::new();
for package in crate::db::DatabaseModel::new() for package in crate::db::DatabaseModel::new()
.package_data() .package_data()
.keys(db, true) .keys(db, true)
@@ -65,7 +65,7 @@ impl ManagerMap {
&self, &self,
ctx: RpcContext, ctx: RpcContext,
manifest: Manifest, manifest: Manifest,
tor_keys: HashMap<InterfaceId, TorSecretKeyV3>, tor_keys: BTreeMap<InterfaceId, TorSecretKeyV3>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut lock = self.0.write().await; let mut lock = self.0.write().await;
let id = (manifest.id.clone(), manifest.version.clone()); let id = (manifest.id.clone(), manifest.version.clone());
@@ -125,7 +125,7 @@ struct ManagerSharedState {
on_stop: Sender<OnStop>, on_stop: Sender<OnStop>,
manifest: Manifest, manifest: Manifest,
container_name: String, container_name: String,
tor_keys: HashMap<InterfaceId, TorSecretKeyV3>, tor_keys: BTreeMap<InterfaceId, TorSecretKeyV3>,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -246,7 +246,7 @@ impl Manager {
async fn create( async fn create(
ctx: RpcContext, ctx: RpcContext,
manifest: Manifest, manifest: Manifest,
tor_keys: HashMap<InterfaceId, TorSecretKeyV3>, tor_keys: BTreeMap<InterfaceId, TorSecretKeyV3>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let (on_stop, mut recv) = channel(OnStop::Sleep); let (on_stop, mut recv) = channel(OnStop::Sleep);
let shared = Arc::new(ManagerSharedState { let shared = Arc::new(ManagerSharedState {

View File

@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap}; use std::collections::BTreeMap;
use std::path::Path; use std::path::Path;
use anyhow::anyhow; use anyhow::anyhow;
@@ -72,7 +72,7 @@ impl Interfaces {
&self, &self,
secrets: &mut Ex, secrets: &mut Ex,
package_id: &PackageId, package_id: &PackageId,
) -> Result<HashMap<InterfaceId, TorSecretKeyV3>, Error> ) -> Result<BTreeMap<InterfaceId, TorSecretKeyV3>, Error>
where where
for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>, for<'a> &'a mut Ex: Executor<'a, Database = Sqlite>,
{ {

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use avahi_sys::{ use avahi_sys::{
self, avahi_entry_group_add_service, avahi_entry_group_commit, avahi_entry_group_free, self, avahi_entry_group_add_service, avahi_entry_group_commit, avahi_entry_group_free,
@@ -35,7 +35,7 @@ impl MdnsController {
pub struct MdnsControllerInner { pub struct MdnsControllerInner {
hostname: Vec<u8>, hostname: Vec<u8>,
entry_group: *mut AvahiEntryGroup, entry_group: *mut AvahiEntryGroup,
services: HashMap<(PackageId, InterfaceId), TorSecretKeyV3>, services: BTreeMap<(PackageId, InterfaceId), TorSecretKeyV3>,
} }
unsafe impl Send for MdnsControllerInner {} unsafe impl Send for MdnsControllerInner {}
unsafe impl Sync for MdnsControllerInner {} unsafe impl Sync for MdnsControllerInner {}
@@ -115,7 +115,7 @@ impl MdnsControllerInner {
MdnsControllerInner { MdnsControllerInner {
hostname: hostname_buf, hostname: hostname_buf,
entry_group: group, entry_group: group,
services: HashMap::new(), services: BTreeMap::new(),
} }
} }
} }

View File

@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap}; use std::collections::BTreeMap;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::path::PathBuf; use std::path::PathBuf;
@@ -35,14 +35,14 @@ impl NginxController {
pub struct NginxControllerInner { pub struct NginxControllerInner {
nginx_root: PathBuf, nginx_root: PathBuf,
interfaces: HashMap<PackageId, PackageNetInfo>, interfaces: BTreeMap<PackageId, PackageNetInfo>,
ssl_manager: SslManager, ssl_manager: SslManager,
} }
impl NginxControllerInner { impl NginxControllerInner {
async fn init(nginx_root: PathBuf, db: SqlitePool) -> Result<Self, Error> { async fn init(nginx_root: PathBuf, db: SqlitePool) -> Result<Self, Error> {
Ok(NginxControllerInner { Ok(NginxControllerInner {
nginx_root, nginx_root,
interfaces: HashMap::new(), interfaces: BTreeMap::new(),
ssl_manager: SslManager::init(db).await?, ssl_manager: SslManager::init(db).await?,
}) })
} }
@@ -60,7 +60,7 @@ impl NginxControllerInner {
// also don't add nginx unless it has at least one exposed port // also don't add nginx unless it has at least one exposed port
&& meta.lan_config.len() > 0 && meta.lan_config.len() > 0
}) })
.collect::<HashMap<InterfaceId, InterfaceMetadata>>(); .collect::<BTreeMap<InterfaceId, InterfaceMetadata>>();
for (id, meta) in interface_map.iter() { for (id, meta) in interface_map.iter() {
for (port, lan_port_config) in meta.lan_config.iter() { for (port, lan_port_config) in meta.lan_config.iter() {
@@ -197,7 +197,7 @@ impl NginxControllerInner {
} }
struct PackageNetInfo { struct PackageNetInfo {
ip: Ipv4Addr, ip: Ipv4Addr,
interfaces: HashMap<InterfaceId, InterfaceMetadata>, interfaces: BTreeMap<InterfaceId, InterfaceMetadata>,
} }
pub struct InterfaceMetadata { pub struct InterfaceMetadata {
pub dns_base: String, pub dns_base: String,

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::net::{Ipv4Addr, SocketAddr}; use std::net::{Ipv4Addr, SocketAddr};
use std::time::Duration; use std::time::Duration;
@@ -137,7 +137,7 @@ pub struct TorControllerInner {
embassyd_tor_key: TorSecretKeyV3, embassyd_tor_key: TorSecretKeyV3,
control_addr: SocketAddr, control_addr: SocketAddr,
connection: Option<AuthenticatedConnection>, connection: Option<AuthenticatedConnection>,
services: HashMap<(PackageId, InterfaceId), (TorSecretKeyV3, TorConfig, Ipv4Addr)>, services: BTreeMap<(PackageId, InterfaceId), (TorSecretKeyV3, TorConfig, Ipv4Addr)>,
} }
impl TorControllerInner { impl TorControllerInner {
async fn add<'a, I: IntoIterator<Item = (InterfaceId, TorConfig, TorSecretKeyV3)>>( async fn add<'a, I: IntoIterator<Item = (InterfaceId, TorConfig, TorSecretKeyV3)>>(
@@ -230,7 +230,7 @@ impl TorControllerInner {
embassyd_tor_key, embassyd_tor_key,
control_addr: tor_control, control_addr: tor_control,
connection: Some(connection), connection: Some(connection),
services: HashMap::new(), services: BTreeMap::new(),
}; };
controller.add_embassyd_onion().await?; controller.add_embassyd_onion().await?;
Ok(controller) Ok(controller)
@@ -314,7 +314,7 @@ impl TorControllerInner {
self.connection.replace(new_connection); self.connection.replace(new_connection);
// swap empty map for owned old service map // swap empty map for owned old service map
let old_services = std::mem::replace(&mut self.services, HashMap::new()); let old_services = std::mem::replace(&mut self.services, BTreeMap::new());
// re add all of the services on the new control socket // re add all of the services on the new control socket
for ((package_id, interface_id), (tor_key, tor_cfg, ipv4)) in old_services { for ((package_id, interface_id), (tor_key, tor_cfg, ipv4)) in old_services {

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::path::Path; use std::path::Path;
use std::time::Duration; use std::time::Duration;
@@ -353,7 +353,7 @@ impl<'a> WpaCli<'a> {
.await?; .await?;
Ok(()) Ok(())
} }
pub async fn list_networks_low(&self) -> Result<HashMap<String, NetworkId>, Error> { pub async fn list_networks_low(&self) -> Result<BTreeMap<String, NetworkId>, Error> {
let r = Command::new("wpa_cli") let r = Command::new("wpa_cli")
.arg("-i") .arg("-i")
.arg(self.interface) .arg(self.interface)
@@ -369,7 +369,7 @@ impl<'a> WpaCli<'a> {
let ssid = cs.next()?.to_owned(); let ssid = cs.next()?.to_owned();
Some((ssid, nid)) Some((ssid, nid))
}) })
.collect::<HashMap<String, NetworkId>>()) .collect::<BTreeMap<String, NetworkId>>())
} }
pub async fn select_network_low(&self, id: &NetworkId) -> Result<(), Error> { pub async fn select_network_low(&self, id: &NetworkId) -> Result<(), Error> {
let _ = Command::new("wpa_cli") let _ = Command::new("wpa_cli")

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
@@ -187,7 +187,7 @@ pub enum NotificationSubtype {
BackupReport { BackupReport {
server_attempted: bool, server_attempted: bool,
server_error: Option<String>, server_error: Option<String>,
packages: HashMap<String, Option<String>>, packages: BTreeMap<String, Option<String>>,
}, },
} }
impl NotificationSubtype { impl NotificationSubtype {

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::io::Write; use std::io::Write;
use anyhow::anyhow; use anyhow::anyhow;
@@ -100,12 +100,12 @@ impl TableOfContents {
reader.read_exact(&mut toc_len).await?; reader.read_exact(&mut toc_len).await?;
let toc_len = u32::from_be_bytes(toc_len); let toc_len = u32::from_be_bytes(toc_len);
let mut reader = reader.take(toc_len as u64); let mut reader = reader.take(toc_len as u64);
let mut table = HashMap::new(); let mut table = BTreeMap::new();
while let Some((label, section)) = FileSection::deserialize_entry(&mut reader).await? { while let Some((label, section)) = FileSection::deserialize_entry(&mut reader).await? {
table.insert(label, section); table.insert(label, section);
} }
fn from_table( fn from_table(
table: &HashMap<Vec<u8>, FileSection>, table: &BTreeMap<Vec<u8>, FileSection>,
label: &str, label: &str,
) -> std::io::Result<FileSection> { ) -> std::io::Result<FileSection> {
table.get(label.as_bytes()).copied().ok_or_else(|| { table.get(label.as_bytes()).copied().ok_or_else(|| {

View File

@@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet};
use std::sync::Arc; use std::sync::Arc;
use anyhow::anyhow; use anyhow::anyhow;
@@ -113,7 +113,7 @@ pub async fn check_all(ctx: &RpcContext) -> Result<(), Error> {
.0 .0
.into_iter() .into_iter()
.map(|x| x.0) .map(|x| x.0)
.collect::<HashSet<PackageId>>(); .collect::<BTreeSet<PackageId>>();
status_manifest.push(( status_manifest.push((
installed.clone().status(), installed.clone().status(),
Arc::new(installed.clone().manifest().get(&mut db, true).await?), Arc::new(installed.clone().manifest().get(&mut db, true).await?),
@@ -151,7 +151,7 @@ pub async fn check_all(ctx: &RpcContext) -> Result<(), Error> {
Ok(res) Ok(res)
} }
let (status_sender, mut statuses_recv) = tokio::sync::mpsc::channel(status_manifest.len() + 1); let (status_sender, mut statuses_recv) = tokio::sync::mpsc::channel(status_manifest.len() + 1);
let mut statuses = HashMap::with_capacity(status_manifest.len()); let mut statuses = BTreeMap::new();
futures::stream::iter( futures::stream::iter(
status_manifest status_manifest
.into_iter() .into_iter()
@@ -179,7 +179,7 @@ pub async fn check_all(ctx: &RpcContext) -> Result<(), Error> {
let statuses = Arc::new(statuses); let statuses = Arc::new(statuses);
async fn dependency_status<Db: DbHandle>( async fn dependency_status<Db: DbHandle>(
id: &PackageId, id: &PackageId,
statuses: Arc<HashMap<PackageId, MainStatus>>, statuses: Arc<BTreeMap<PackageId, MainStatus>>,
model: InstalledPackageDataEntryModel, model: InstalledPackageDataEntryModel,
current_deps: Arc<BTreeMap<PackageId, CurrentDependencyInfo>>, current_deps: Arc<BTreeMap<PackageId, CurrentDependencyInfo>>,
mut db: Db, mut db: Db,

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::Arc; use std::sync::Arc;
@@ -12,7 +12,7 @@ pub struct ModuleMap {
trie: SequenceTrie<String, (LevelFilter, bool)>, trie: SequenceTrie<String, (LevelFilter, bool)>,
} }
impl ModuleMap { impl ModuleMap {
fn new(vals: HashMap<String, LevelFilter>) -> Self { fn new(vals: BTreeMap<String, LevelFilter>) -> Self {
let mut module_trie = SequenceTrie::new(); let mut module_trie = SequenceTrie::new();
for (k, v) in vals { for (k, v) in vals {
let mut include_submodules = false; let mut include_submodules = false;
@@ -97,7 +97,7 @@ impl EmbassyLogger {
log_epoch: Arc<AtomicU64>, log_epoch: Arc<AtomicU64>,
share_dest: Option<Url>, share_dest: Option<Url>,
share_errors: bool, share_errors: bool,
module_map: HashMap<String, LevelFilter>, module_map: BTreeMap<String, LevelFilter>,
) -> Self { ) -> Self {
let share_dest = match share_dest { let share_dest = match share_dest {
None => Url::parse("https://beta-registry-0-3.start9labs.com/error-logs").unwrap(), // TODO None => Url::parse("https://beta-registry-0-3.start9labs.com/error-logs").unwrap(), // TODO
@@ -145,7 +145,7 @@ impl log::Log for EmbassyLogger {
} }
if self.sharing.load(Ordering::SeqCst) { if self.sharing.load(Ordering::SeqCst) {
if record.level() <= log::Level::Warn { if record.level() <= log::Level::Warn {
let mut body = HashMap::new(); let mut body = BTreeMap::new();
body.insert( body.insert(
"log-epoch", "log-epoch",
format!("{}", self.log_epoch.load(Ordering::SeqCst)), format!("{}", self.log_epoch.load(Ordering::SeqCst)),
@@ -180,7 +180,7 @@ proptest::proptest! {
#[test] #[test]
fn submodules_handled_by_parent(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) { fn submodules_handled_by_parent(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) {
proptest::prop_assume!(level > LevelFilter::Off); proptest::prop_assume!(level > LevelFilter::Off);
let mut hm = HashMap::new(); let mut hm = BTreeMap::new();
hm.insert(format!("{}::*", s0.clone()), level); hm.insert(format!("{}::*", s0.clone()), level);
let mod_map = ModuleMap::new(hm); let mod_map = ModuleMap::new(hm);
proptest::prop_assert_eq!(mod_map.level_for(&format!("{}::{}", s0, s1)), &level) proptest::prop_assert_eq!(mod_map.level_for(&format!("{}::{}", s0, s1)), &level)
@@ -188,7 +188,7 @@ proptest::proptest! {
#[test] #[test]
fn submodules_ignored_by_parent(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) { fn submodules_ignored_by_parent(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) {
proptest::prop_assume!(level > LevelFilter::Off); proptest::prop_assume!(level > LevelFilter::Off);
let mut hm = HashMap::new(); let mut hm = BTreeMap::new();
hm.insert(s0.clone(), level); hm.insert(s0.clone(), level);
let mod_map = ModuleMap::new(hm); let mod_map = ModuleMap::new(hm);
proptest::prop_assert_eq!(mod_map.level_for(&format!("{}::{}", s0, s1)), &LevelFilter::Off) proptest::prop_assert_eq!(mod_map.level_for(&format!("{}::{}", s0, s1)), &LevelFilter::Off)
@@ -196,7 +196,7 @@ proptest::proptest! {
#[test] #[test]
fn duplicate_insertion_ignored(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) { fn duplicate_insertion_ignored(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level in filter_strategy()) {
proptest::prop_assume!(level > LevelFilter::Off); proptest::prop_assume!(level > LevelFilter::Off);
let mut hm = HashMap::new(); let mut hm = BTreeMap::new();
hm.insert(format!("{}::*", s0.clone()), level); hm.insert(format!("{}::*", s0.clone()), level);
let sub = format!("{}::{}", s0, s1); let sub = format!("{}::{}", s0, s1);
hm.insert(sub.clone(), level); hm.insert(sub.clone(), level);
@@ -205,7 +205,7 @@ proptest::proptest! {
} }
#[test] #[test]
fn parent_child_simul(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level0 in filter_strategy(), level1 in filter_strategy()) { fn parent_child_simul(s0 in "[a-z][a-z0-9_]+", s1 in "[a-z][a-z0-9_]+", level0 in filter_strategy(), level1 in filter_strategy()) {
let mut hm = HashMap::new(); let mut hm = BTreeMap::new();
hm.insert(s0.clone(), level0); hm.insert(s0.clone(), level0);
let sub = format!("{}::{}", s0, s1); let sub = format!("{}::{}", s0, s1);
hm.insert(sub.clone(), level1); hm.insert(sub.clone(), level1);

View File

@@ -387,6 +387,16 @@ impl PartialEq for Version {
} }
} }
impl Eq for Version {} impl Eq for Version {}
impl PartialOrd for Version {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.version.partial_cmp(&other.version)
}
}
impl Ord for Version {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.version.cmp(&other.version)
}
}
impl Hash for Version { impl Hash for Version {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
self.version.hash(state) self.version.hash(state)