kaspa_consensus_core/
blockhash.rs1use crate::{BlockHashSet, HashMapCustomHasher};
2use kaspa_hashes::{Hash, HASH_SIZE};
3use std::sync::Arc;
4
5pub type BlockHashes = Arc<Vec<Hash>>;
6
7pub const NONE: Hash = Hash::from_bytes([0u8; HASH_SIZE]);
9
10pub const ORIGIN: Hash = Hash::from_bytes([0xfe; HASH_SIZE]);
14
15pub trait BlockHashExtensions {
16 fn is_none(&self) -> bool;
17 fn is_origin(&self) -> bool;
18}
19
20impl BlockHashExtensions for Hash {
21 fn is_none(&self) -> bool {
22 self.eq(&NONE)
23 }
24
25 fn is_origin(&self) -> bool {
26 self.eq(&ORIGIN)
27 }
28}
29
30pub fn new_unique() -> Hash {
33 use std::sync::atomic::{AtomicU64, Ordering};
34 static COUNTER: AtomicU64 = AtomicU64::new(1);
35 let c = COUNTER.fetch_add(1, Ordering::Relaxed);
36 Hash::from_u64_word(c)
37}
38
39pub trait BlockHashIteratorExtensions: Iterator<Item = Hash> {
40 fn block_unique(self) -> BlockUnique<Self>
54 where
55 Self: Sized,
56 {
57 let (lower, _) = self.size_hint();
58 BlockUnique { iter: self, seen: BlockHashSet::with_capacity(lower) }
59 }
60}
61
62impl<T: ?Sized> BlockHashIteratorExtensions for T where T: Iterator<Item = Hash> {}
63
64#[derive(Clone)]
65pub struct BlockUnique<I: Iterator<Item = Hash>> {
66 iter: I,
67 seen: BlockHashSet,
68}
69
70impl<I> Iterator for BlockUnique<I>
71where
72 I: Iterator<Item = Hash>,
73{
74 type Item = I::Item;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 self.iter.by_ref().find(|&hash| self.seen.insert(hash))
78 }
79
80 #[inline]
81 fn size_hint(&self) -> (usize, Option<usize>) {
82 let (low, hi) = self.iter.size_hint();
83 ((low > 0 && self.seen.is_empty()) as usize, hi)
84 }
85}
86
87impl<I> DoubleEndedIterator for BlockUnique<I>
88where
89 I: DoubleEndedIterator<Item = Hash>,
90{
91 fn next_back(&mut self) -> Option<Self::Item> {
92 self.iter.by_ref().rev().find(|&hash| self.seen.insert(hash))
93 }
94}
95
96impl<I> std::iter::FusedIterator for BlockUnique<I> where I: Iterator<Item = Hash> + std::iter::FusedIterator {}