Skip to content

Commit

Permalink
fix: add OneByteBitSet
Browse files Browse the repository at this point in the history
  • Loading branch information
ShiKaiWi committed Aug 24, 2023
1 parent 1485b4e commit 18e85c6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
40 changes: 23 additions & 17 deletions common_types/src/row/bitset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -185,6 +190,7 @@ mod tests {
use std::assert_eq;

use super::BitSet;
use crate::row::bitset::OneByteBitSet;

#[test]
fn test_set_op() {
Expand Down Expand Up @@ -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);
}
}
10 changes: 5 additions & 5 deletions components/codec/src/columnar/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit 18e85c6

Please sign in to comment.