Skip to main content

SbbfPushDecoder

Struct SbbfPushDecoder 

Source
pub struct SbbfPushDecoder {
    state: DecodeState,
    offset: u64,
    length: Option<usize>,
    buffers: PushBuffers,
}
Expand description

Decodes a Bloom filter from caller-provided file ranges, without performing I/O.

The metadata and pushed bytes must refer to the same file. Ranges use absolute file offsets. Call Self::try_decode to discover which ranges are needed, then supply them using Self::push_range or Self::push_ranges. Bytes may also be pushed in advance to avoid requests for already-buffered data.

Each requested range must be contained in a single pushed buffer; adjacent buffers are not coalesced. After an error from Self::try_decode, discard the decoder.

§Example

use bytes::Bytes;
use parquet::DecodeResult;
use parquet::bloom_filter::{Sbbf, SbbfPushDecoder};
use parquet::errors::Result;
use parquet::file::metadata::ColumnChunkMetaData;

fn decode_filter(metadata: &ColumnChunkMetaData, file_bytes: Bytes) -> Result<Option<Sbbf>> {
    let Some(mut decoder) = SbbfPushDecoder::try_new(metadata)? else {
        return Ok(None);
    };
    loop {
        match decoder.try_decode()? {
            DecodeResult::NeedsData(ranges) => {
                let buffers = ranges.iter().map(|range| {
                    file_bytes.slice(range.start as usize..range.end as usize)
                }).collect();
                decoder.push_ranges(ranges, buffers)?;
            }
            DecodeResult::Data(filter) => return Ok(Some(filter)),
            DecodeResult::Finished => unreachable!("filter was returned above"),
        }
    }
}

let filter = decode_filter(&metadata, file_bytes)?.unwrap();
assert!(filter.check("present"));

Fields§

§state: DecodeState

Decoding state

§offset: u64

Offset of the Bloom filter in the file

§length: Option<usize>

Length of the Bloom filter

§buffers: PushBuffers

Underlying buffers

Implementations§

Source§

impl SbbfPushDecoder

Source

pub fn try_new(column_metadata: &ColumnChunkMetaData) -> Result<Option<Self>>

Create a new Bloom filter decoder for the given column chunk.

Returns None if the column chunk has no Bloom filter offset. Invalid offsets and nonpositive advertised lengths return an error.

Source

pub fn push_range(&mut self, range: Range<u64>, buffer: Bytes) -> Result<()>

Pushes a file range into the decoder’s buffer.

Returns an error if the buffer length differs from the range length or decoding has finished.

Source

pub fn push_ranges( &mut self, ranges: Vec<Range<u64>>, buffers: Vec<Bytes>, ) -> Result<()>

Pushes multiple file ranges into the decoder’s buffer.

The number of ranges must match the number of buffers, and each buffer must have the same length as its range. Pushing after decoding has finished returns an error.

Source

fn get_bytes(&self, range: &Range<u64>) -> Result<Bytes>

Returns the bytes for the given range from the internal buffer

Source

pub fn try_decode(&mut self) -> Result<DecodeResult<Sbbf>>

Attempts to decode the filter, returning the file ranges needed if data is missing. Repeated calls before supplying data return the same ranges.

Without prefetched data, requests one range when bloom_filter_length is known, or two otherwise (a 20-byte header estimate, then the bitset). Headers larger than the estimate require an advertised length. After returning DecodeResult::Data, subsequent calls return DecodeResult::Finished.

The state transitions can be visualized as:

                ┌──────────────┐
                │ FindingRange │
                └──────────────┘
                       │
              choose initial range
                       │
                       ▼
             ┌───────────────────┐ ───┐ bytes missing:
             │ ReadingSbbfHeader │    │ return NeedsData(range),
             └───────────────────┘ ◀──┘ wait for push_range(s)
                │               │
           length known   length unknown
                │               │
                │               ▼
                │     ┌───────────────────┐ ───┐ bytes missing:
                │     │ ReadingSbbfBitset │    │ return NeedsData(range),
                │     └───────────────────┘ ◀──┘ wait for push_range(s)
                │               │
                └───────┬───────┘
                        │
                 return Data(Sbbf)
                        │
                        ▼
                  ┌──────────┐ ───┐
                  │ Finished │    │ return Finished
                  └──────────┘ ◀──┘

In the above:

  • The initial range is the whole filter when its length is known, otherwise a 20-byte header prefix.
  • Transitions proceed within the same try_decode() call while the required bytes are buffered; push_range(s) supplies bytes without changing state.
  • Header parsing/validation must succeed before advancing. Any decoding error leaves the decoder unusable.

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Ungil for T
where T: Send,