risinglight icon indicating copy to clipboard operation
risinglight copied to clipboard

storage: generic nullable block encoding

Open skyzh opened this issue 2 years ago • 2 comments

Currently, the nullable encoding is done by using a bitmap, and is only implemented for primitive types.

https://github.com/risinglightdb/risinglight/blob/7b5bc7a1a258afd64a483990ca95f4c799482791/src/storage/secondary/block/primitive_nullable_block_builder.rs#L18

Indeed, such logic can be done in a more generic way. We can wrap any BlockIterator to become a nullable encoding.

pub struct NullableBlockBuilder<B: BlockBuilder> {
  inner: B,
  bitmap: BitVec
}

To achieve this, we can:

  • [ ] separate nullable encoding from primitive nullable encoding.
  • [ ] use the generic nullable encoder for char and blob.
  • [ ] to avoid branch prediction for Option::unwrap, we can make a new pair of traits: NonNullableBlockBuilder and Iterator, which accepts &A::Item instead of Option<&A::Item>.

skyzh avatar Feb 26 '22 12:02 skyzh

I'm a beginner and would like to give this a try.

wxmbugu avatar Aug 18 '22 19:08 wxmbugu

Welcome to have a try!

skyzh avatar Aug 18 '22 21:08 skyzh

it seems like?

pub struct NullableBlockBuilder<T: PrimitiveFixedWidthEncode, B: BlockBuilder<T::ArrayType>> {
	inner: B,
	bitmap: BitVec,
	phantom: PhantomData<T>,
}

impl<T: PrimitiveFixedWidthEncode, B: BlockBuilder<T::ArrayType>> BlockBuilder<T::ArrayType>
    for NullableBlockBuilder<T, B>
{
    fn append(&mut self, item: Option<&T>) {
        if item.is_none() {
            self.inner.append(T::DEFAULT_VALUE);
            self.bitmap.push(false);
        } else {
            self.inner.append(item);
            self.bitmap.push(true);
        }
    }

    fn get_target_size(&self) -> usize {
        self.inner.get_target_size()
    }

    fn finish(self) -> Vec<u8> {
        self.inner.finish()
    }
}

impl<T: PrimitiveFixedWidthEncode, B: BlockBuilder<T::ArrayType>> NullableBlockBuilder<T, B> {
    pub fn new(builder: B) -> Self {
        Self {
            bitmap: BitVec::with_capacity(builder.get_target_size()),
            inner: builder,
            phantom: PhantomData,
        }
    }
}

eliasyaoyc avatar Oct 13 '22 09:10 eliasyaoyc

This design looks good!

skyzh avatar Oct 13 '22 12:10 skyzh

@eliasyaoyc Hi, are you working on this issue? I'm trying to work on it a few days ago. So would you like to wait for a while?

unconsolable avatar Oct 13 '22 15:10 unconsolable