diff --git a/common_types/src/row/bitset.rs b/common_types/src/row/bitset.rs index 1bae75504a..044b0d6a48 100644 --- a/common_types/src/row/bitset.rs +++ b/common_types/src/row/bitset.rs @@ -28,6 +28,24 @@ const UNSET_BIT_MASK: [u8; 8] = [ 255 - 128, ]; +/// A bit set representing at most 8 bits with a underlying u8. +pub struct OneByteBitSet(pub u8); + +impl OneByteBitSet { + /// Create from a given boolean slice. + /// + /// The values in the `bits` whose index is greater than 8 will be ignored. + pub fn from_slice(bits: &[bool]) -> Self { + let mut v = 0u8; + for (idx, set) in bits.iter().take(8).map(|v| *v as u8).enumerate() { + let (_, bit_idx) = RoBitSet::compute_byte_bit_index(idx); + v |= set << bit_idx + } + + Self(v) + } +} + /// A basic implementation supporting read/write. #[derive(Debug, Default, Clone)] pub struct BitSet { @@ -46,19 +64,6 @@ impl BitSet { } } - /// Create a u8 according to a given 8bits array. - /// - /// The values in the `bits` whose index is greater than 8 will be ignored. - pub fn one_byte(bits: &[bool]) -> u8 { - let mut v = 0u8; - for (idx, set) in bits.iter().take(8).map(|v| *v as u8).enumerate() { - let (_, bit_idx) = RoBitSet::compute_byte_bit_index(idx); - v |= set << bit_idx - } - - v - } - /// Initialize a [`BitSet`] with all bits set. pub fn all_set(num_bits: usize) -> Self { Self { @@ -185,6 +190,7 @@ mod tests { use std::assert_eq; use super::BitSet; + use crate::row::bitset::OneByteBitSet; #[test] fn test_set_op() { @@ -245,17 +251,17 @@ mod tests { #[test] fn test_one_byte() { let bits = [false, false, false, false, false, false]; - assert_eq!(0, BitSet::one_byte(&bits)); + assert_eq!(0, OneByteBitSet::from_slice(&bits).0); let bits = [true, false, false, false, false, false]; - assert_eq!(1, BitSet::one_byte(&bits)); + assert_eq!(1, OneByteBitSet::from_slice(&bits).0); let bits = [false, false, false, true, false, false, true, true]; - assert_eq!(128 + 64 + 8, BitSet::one_byte(&bits)); + assert_eq!(128 + 64 + 8, OneByteBitSet::from_slice(&bits).0); let bits = [ false, false, false, false, false, false, true, true, true, true, ]; - assert_eq!(128 + 64, BitSet::one_byte(&bits)); + assert_eq!(128 + 64, OneByteBitSet::from_slice(&bits).0); } } diff --git a/components/codec/src/columnar/bool.rs b/components/codec/src/columnar/bool.rs index 30550a9aef..77aa93f368 100644 --- a/components/codec/src/columnar/bool.rs +++ b/components/codec/src/columnar/bool.rs @@ -13,7 +13,7 @@ // limitations under the License. use bytes_ext::{Buf, BufMut}; -use common_types::row::bitset::{BitSet, RoBitSet}; +use common_types::row::bitset::{BitSet, OneByteBitSet, RoBitSet}; use snafu::{ensure, OptionExt}; use super::{ @@ -48,7 +48,7 @@ enum Compression { impl Encoding { const COMPRESSION_SIZE: usize = 1; - /// The overhead for compression is 5B, so it is not good to always enable + /// The overhead for compression is 4B, so it is not good to always enable /// the compression. const COMPRESS_THRESHOLD: usize = 10; const NUM_VALUES_SIZE: usize = 4; @@ -169,8 +169,8 @@ impl Encoding { one_byte_bits[offset] = v; offset += 1; if offset == 8 { - let bit_set = BitSet::one_byte(&one_byte_bits); - buf.put_u8(bit_set); + let bit_set = OneByteBitSet::from_slice(&one_byte_bits); + buf.put_u8(bit_set.0); // Reset the offset and the bits buf. offset = 0; @@ -180,8 +180,8 @@ impl Encoding { // Put the remaining bits. if offset > 0 { - let bit_set = BitSet::one_byte(&one_byte_bits); - buf.put_u8(bit_set); + let bit_set = OneByteBitSet::from_slice(&one_byte_bits); + buf.put_u8(bit_set.0); } buf.put_u8(Compression::BitSet as u8);