use commonware_utils::{
bitmap::{self, Readable as _},
sync::{RwLock, RwLockReadGuard, RwLockWriteGuard},
};
pub(crate) struct Shared<const N: usize> {
inner: RwLock<bitmap::Prunable<N>>,
}
impl<const N: usize> Shared<N> {
pub(crate) const fn new(bitmap: bitmap::Prunable<N>) -> Self {
Self {
inner: RwLock::new(bitmap),
}
}
fn read(&self) -> RwLockReadGuard<'_, bitmap::Prunable<N>> {
self.inner.read()
}
pub(crate) fn write(&self) -> RwLockWriteGuard<'_, bitmap::Prunable<N>> {
self.inner.write()
}
pub(crate) fn next_one_from(&self, from: u64) -> Option<u64> {
self.read().ones_iter_from(from).next()
}
#[cfg(any(test, feature = "test-traits"))]
pub(crate) fn pruned_bits(&self) -> u64 {
self.read().pruned_bits()
}
#[cfg(any(test, feature = "test-traits"))]
pub(crate) fn get_bit(&self, loc: u64) -> bool {
self.read().get_bit(loc)
}
}
impl<const N: usize> std::fmt::Debug for Shared<N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Shared")
.field("bitmap_len", &bitmap::Readable::<N>::len(&*self.read()))
.finish()
}
}
impl<const N: usize> bitmap::Readable<N> for Shared<N> {
fn complete_chunks(&self) -> usize {
self.read().complete_chunks()
}
fn get_chunk(&self, idx: usize) -> [u8; N] {
*self.read().get_chunk(idx)
}
fn last_chunk(&self) -> ([u8; N], u64) {
let guard = self.read();
let (chunk, bits) = guard.last_chunk();
(*chunk, bits)
}
fn pruned_chunks(&self) -> usize {
self.read().pruned_chunks()
}
fn len(&self) -> u64 {
bitmap::Readable::<N>::len(&*self.read())
}
}