From e8f6a40166eb3084a4bfe1c48939a7bd560c20cc Mon Sep 17 00:00:00 2001 From: Xiliang Chen <xlchen1291@gmail.com> Date: Thu, 14 May 2020 16:43:12 +1200 Subject: [PATCH] ordered set (#160) --- schedule-update/Cargo.toml | 2 + utilities/src/lib.rs | 1 + utilities/src/ordered_set.rs | 131 +++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 utilities/src/ordered_set.rs diff --git a/schedule-update/Cargo.toml b/schedule-update/Cargo.toml index 40523d6..3d9814a 100644 --- a/schedule-update/Cargo.toml +++ b/schedule-update/Cargo.toml @@ -20,6 +20,8 @@ sp-io = { version = "2.0.0-alpha.6", default-features = false } sp-core = { version = "2.0.0-alpha.6", default-features = false } pallet-balances = { version = "2.0.0-alpha.6" } +clear_on_drop = { version = "0.2.3", features = ["no_cc"] } # https://github.com/paritytech/substrate/issues/4179 + [features] default = ["std"] std = [ diff --git a/utilities/src/lib.rs b/utilities/src/lib.rs index a99a484..910f988 100644 --- a/utilities/src/lib.rs +++ b/utilities/src/lib.rs @@ -2,6 +2,7 @@ pub mod fixed_u128; pub mod linked_item; +pub mod ordered_set; pub use fixed_u128::FixedU128; pub use linked_item::{LinkedItem, LinkedList}; diff --git a/utilities/src/ordered_set.rs b/utilities/src/ordered_set.rs new file mode 100644 index 0000000..56ec866 --- /dev/null +++ b/utilities/src/ordered_set.rs @@ -0,0 +1,131 @@ +use codec::{Decode, Encode}; +use sp_runtime::RuntimeDebug; +use sp_std::prelude::*; + +#[derive(RuntimeDebug, PartialEq, Eq, Encode, Decode, Default)] +pub struct OrderedSet<T>(Vec<T>); + +impl<T: Ord> OrderedSet<T> { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn from(mut v: Vec<T>) -> Self { + v.sort(); + v.dedup(); + Self::from_sorted_set(v) + } + + /// Assume v is sorted and contain unique elements + pub fn from_sorted_set(v: Vec<T>) -> Self { + Self(v) + } + + pub fn insert(&mut self, value: T) -> bool { + match self.0.binary_search(&value) { + Ok(_) => false, + Err(loc) => { + self.0.insert(loc, value); + true + } + } + } + + pub fn remove(&mut self, value: &T) -> bool { + match self.0.binary_search(&value) { + Ok(loc) => { + self.0.remove(loc); + true + } + Err(_) => false, + } + } + + pub fn contains(&self, value: &T) -> bool { + self.0.binary_search(&value).is_ok() + } + + pub fn clear(&mut self) { + self.0.clear(); + } +} + +impl<T: Ord> From<Vec<T>> for OrderedSet<T> { + fn from(v: Vec<T>) -> Self { + Self::from(v) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn from() { + let v = vec![4, 2, 3, 4, 3, 1]; + let set: OrderedSet<i32> = v.into(); + assert_eq!(set, OrderedSet::from(vec![1, 2, 3, 4])); + } + + #[test] + fn insert() { + let mut set: OrderedSet<i32> = OrderedSet::new(); + assert_eq!(set, OrderedSet::from(vec![])); + + assert_eq!(set.insert(1), true); + assert_eq!(set, OrderedSet::from(vec![1])); + + assert_eq!(set.insert(5), true); + assert_eq!(set, OrderedSet::from(vec![1, 5])); + + assert_eq!(set.insert(3), true); + assert_eq!(set, OrderedSet::from(vec![1, 3, 5])); + + assert_eq!(set.insert(3), false); + assert_eq!(set, OrderedSet::from(vec![1, 3, 5])); + } + + #[test] + fn remove() { + let mut set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]); + + assert_eq!(set.remove(&5), false); + assert_eq!(set, OrderedSet::from(vec![1, 2, 3, 4])); + + assert_eq!(set.remove(&1), true); + assert_eq!(set, OrderedSet::from(vec![2, 3, 4])); + + assert_eq!(set.remove(&3), true); + assert_eq!(set, OrderedSet::from(vec![2, 4])); + + assert_eq!(set.remove(&3), false); + assert_eq!(set, OrderedSet::from(vec![2, 4])); + + assert_eq!(set.remove(&4), true); + assert_eq!(set, OrderedSet::from(vec![2])); + + assert_eq!(set.remove(&2), true); + assert_eq!(set, OrderedSet::from(vec![])); + + assert_eq!(set.remove(&2), false); + assert_eq!(set, OrderedSet::from(vec![])); + } + + #[test] + fn contains() { + let set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]); + + assert_eq!(set.contains(&5), false); + + assert_eq!(set.contains(&1), true); + + assert_eq!(set.contains(&3), true); + } + + #[test] + fn clear() { + let mut set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]); + set.clear(); + assert_eq!(set, OrderedSet::new()); + } +} -- GitLab