Skip to content

Commit

Permalink
feat(chain,core)!: move Merge to bdk_core
Browse files Browse the repository at this point in the history
  • Loading branch information
evanlinjin committed Sep 26, 2024
1 parent 2cf46a2 commit 993c4c0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 82 deletions.
82 changes: 0 additions & 82 deletions crates/chain/src/tx_data_traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::collections::{BTreeMap, BTreeSet};
use crate::{BlockId, ConfirmationBlockTime};
use alloc::vec::Vec;

/// Trait that "anchors" blockchain data to a specific block of height and hash.
///
Expand Down Expand Up @@ -121,83 +119,3 @@ impl AnchorFromBlockPosition for ConfirmationBlockTime {
}
}
}

/// Trait that makes an object mergeable.
pub trait Merge: Default {
/// Merge another object of the same type onto `self`.
fn merge(&mut self, other: Self);

/// Returns whether the structure is considered empty.
fn is_empty(&self) -> bool;

/// Take the value, replacing it with the default value.
fn take(&mut self) -> Option<Self> {
if self.is_empty() {
None
} else {
Some(core::mem::take(self))
}
}
}

impl<K: Ord, V> Merge for BTreeMap<K, V> {
fn merge(&mut self, other: Self) {
// We use `extend` instead of `BTreeMap::append` due to performance issues with `append`.
// Refer to https://github.com/rust-lang/rust/issues/34666#issuecomment-675658420
BTreeMap::extend(self, other)
}

fn is_empty(&self) -> bool {
BTreeMap::is_empty(self)
}
}

impl<T: Ord> Merge for BTreeSet<T> {
fn merge(&mut self, other: Self) {
// We use `extend` instead of `BTreeMap::append` due to performance issues with `append`.
// Refer to https://github.com/rust-lang/rust/issues/34666#issuecomment-675658420
BTreeSet::extend(self, other)
}

fn is_empty(&self) -> bool {
BTreeSet::is_empty(self)
}
}

impl<T> Merge for Vec<T> {
fn merge(&mut self, mut other: Self) {
Vec::append(self, &mut other)
}

fn is_empty(&self) -> bool {
Vec::is_empty(self)
}
}

macro_rules! impl_merge_for_tuple {
($($a:ident $b:tt)*) => {
impl<$($a),*> Merge for ($($a,)*) where $($a: Merge),* {

fn merge(&mut self, _other: Self) {
$(Merge::merge(&mut self.$b, _other.$b) );*
}

fn is_empty(&self) -> bool {
$(Merge::is_empty(&self.$b) && )* true
}
}
}
}

impl_merge_for_tuple!();
impl_merge_for_tuple!(T0 0);
impl_merge_for_tuple!(T0 0 T1 1);
impl_merge_for_tuple!(T0 0 T1 1 T2 2);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10);
3 changes: 3 additions & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@ pub use checkpoint::*;
mod tx_update;
pub use tx_update::*;

mod merge;
pub use merge::*;

pub mod spk_client;
82 changes: 82 additions & 0 deletions crates/core/src/merge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::alloc::vec::Vec;
use crate::collections::{BTreeMap, BTreeSet};

/// Trait that makes an object mergeable.
pub trait Merge: Default {
/// Merge another object of the same type onto `self`.
fn merge(&mut self, other: Self);

/// Returns whether the structure is considered empty.
fn is_empty(&self) -> bool;

/// Take the value, replacing it with the default value.
fn take(&mut self) -> Option<Self> {
if self.is_empty() {
None
} else {
Some(core::mem::take(self))
}
}
}

impl<K: Ord, V> Merge for BTreeMap<K, V> {
fn merge(&mut self, other: Self) {
// We use `extend` instead of `BTreeMap::append` due to performance issues with `append`.
// Refer to https://github.com/rust-lang/rust/issues/34666#issuecomment-675658420
BTreeMap::extend(self, other)
}

fn is_empty(&self) -> bool {
BTreeMap::is_empty(self)
}
}

impl<T: Ord> Merge for BTreeSet<T> {
fn merge(&mut self, other: Self) {
// We use `extend` instead of `BTreeMap::append` due to performance issues with `append`.
// Refer to https://github.com/rust-lang/rust/issues/34666#issuecomment-675658420
BTreeSet::extend(self, other)
}

fn is_empty(&self) -> bool {
BTreeSet::is_empty(self)
}
}

impl<T> Merge for Vec<T> {
fn merge(&mut self, mut other: Self) {
Vec::append(self, &mut other)
}

fn is_empty(&self) -> bool {
Vec::is_empty(self)
}
}

macro_rules! impl_merge_for_tuple {
($($a:ident $b:tt)*) => {
impl<$($a),*> Merge for ($($a,)*) where $($a: Merge),* {

fn merge(&mut self, _other: Self) {
$(Merge::merge(&mut self.$b, _other.$b) );*
}

fn is_empty(&self) -> bool {
$(Merge::is_empty(&self.$b) && )* true
}
}
}
}

impl_merge_for_tuple!();
impl_merge_for_tuple!(T0 0);
impl_merge_for_tuple!(T0 0 T1 1);
impl_merge_for_tuple!(T0 0 T1 1 T2 2);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9);
impl_merge_for_tuple!(T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10);

0 comments on commit 993c4c0

Please sign in to comment.