use std::ops::ControlFlow;
use crate::bit_queue::BitQueue;
use crate::BitBlock;
use crate::config::Config;
#[inline]
pub fn data_block_start_index<Conf: Config>(level0_index: usize, level1_index: usize) -> usize{
let level0_offset = level0_index << (Conf::DataBitBlock::SIZE_POT_EXPONENT + Conf::Level1BitBlock::SIZE_POT_EXPONENT);
let level1_offset = level1_index << (Conf::DataBitBlock::SIZE_POT_EXPONENT);
level0_offset + level1_offset
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DataBlock<Block>{
pub(crate) start_index: usize,
pub(crate) bit_block: Block
}
impl<Block: BitBlock> DataBlock<Block>{
#[inline]
pub fn new(start_index: usize, bit_block: Block) -> DataBlock<Block> {
assert!(start_index % Block::size() == 0, "start_index does not match Block align!");
DataBlock{start_index, bit_block}
}
#[inline]
pub unsafe fn new_unchecked(start_index: usize, bit_block: Block) -> DataBlock<Block> {
DataBlock{start_index, bit_block}
}
#[inline]
pub fn into_parts(self) -> (usize, Block) {
(self.start_index, self.bit_block)
}
#[inline]
pub fn traverse<F, B>(&self, mut f: F) -> ControlFlow<B>
where
F: FnMut(usize) -> ControlFlow<B>
{
self.bit_block.traverse_bits(|index| f(self.start_index + index))
}
#[inline]
pub fn for_each<F>(&self, mut f: F)
where
F: FnMut(usize)
{
let _ = self.traverse(move |index| -> ControlFlow<()> {
f(index);
ControlFlow::Continue(())
});
}
#[inline]
pub fn iter(&self) -> DataBlockIter<Block>{
DataBlockIter{
start_index: self.start_index,
bit_block_iter: self.bit_block.clone().into_bits_iter()
}
}
#[inline]
pub fn len(&self) -> usize {
self.bit_block.count_ones()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.bit_block.is_zero()
}
}
impl<Block: BitBlock> IntoIterator for DataBlock<Block>{
type Item = usize;
type IntoIter = DataBlockIter<Block>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
DataBlockIter{
start_index: self.start_index,
bit_block_iter: self.bit_block.into_bits_iter()
}
}
}
#[derive(Clone)]
pub struct DataBlockIter<Block: BitBlock>{
pub(crate) start_index: usize,
pub(crate) bit_block_iter: Block::BitsIter
}
impl<Block: BitBlock> DataBlockIter<Block>{
#[inline]
pub fn traverse<F, B>(self, mut f: F) -> ControlFlow<B>
where
F: FnMut(usize) -> ControlFlow<B>
{
self.bit_block_iter.traverse(|index| f(self.start_index + index))
}
}
impl<Block: BitBlock> Iterator for DataBlockIter<Block>{
type Item = usize;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.bit_block_iter.next().map(|index|self.start_index + index)
}
#[inline]
fn for_each<F>(self, mut f: F)
where
F: FnMut(Self::Item)
{
let _ = self.traverse(|index| -> ControlFlow<()> {
f(index);
ControlFlow::Continue(())
});
}
}
#[cfg(feature = "serde")]
#[cfg(test)]
mod serde_test{
use super::*;
#[test]
pub fn test_serde(){
let bitblock = 14965686686284719936u64;
let block = DataBlock::new(512, bitblock);
let json = serde_json::to_string(&block).unwrap();
println!("Serialized JSON: {}", json);
let deserialized_block: DataBlock<_> = serde_json::from_str(&json).unwrap();
println!("Deserialized struct: {:?}", deserialized_block);
assert_eq!(block, deserialized_block);
}
#[cfg(feature = "simd")]
#[test]
pub fn test_serde_simd(){
use wide::u64x4;
let bitblock = u64x4::new([16559505904331192437, 5239095950924718615, 11898057780972316399, 5585922389790652141]);
let block = DataBlock::new(512, bitblock);
let json = serde_json::to_string(&block).unwrap();
println!("Serialized JSON: {}", json);
let deserialized_block: DataBlock<_> = serde_json::from_str(&json).unwrap();
println!("Deserialized struct: {:?}", deserialized_block);
assert_eq!(block, deserialized_block);
}
}