Skip to main content

StreamIndex2D

Struct StreamIndex2D 

Source
pub struct StreamIndex2D<R> { /* private fields */ }
Available on crate feature stream only.
Expand description

Streaming reader for a 2D f64 packed spatial index.

Open one over any RangeReader — a local FileReader, an in-memory SliceReader, or a custom remote source — and query it by fetching only the byte ranges a traversal needs, instead of loading the whole serialized index. open validates the header and level bounds and prefetches the upper levels of the tree.

Queries are fallible (a backing read can fail; a corrupt index is reported as StreamError::Format) and otherwise mirror Index2D range search. Results are item insertion indices, in traversal order.

§Example

use packed_spatial_index::{Box2D, Index2DBuilder, SliceReader, StreamIndex2D};

// Serialize an index once...
let mut builder = Index2DBuilder::new(2);
builder.add(Box2D::new(0.0, 0.0, 1.0, 1.0));
builder.add(Box2D::new(5.0, 5.0, 6.0, 6.0));
let bytes = builder.finish().unwrap().to_bytes();

// ...then query it through a RangeReader without rebuilding it in memory.
let index = StreamIndex2D::open(SliceReader::new(bytes))?;
assert_eq!(index.search(Box2D::new(0.0, 0.0, 2.0, 2.0))?, vec![0]);

Implementations§

Source§

impl<R: AsyncRangeReader> StreamIndex2D<R>

Streaming reader for a 2D f64 index over async I/O. Mirrors StreamIndex2D; use it when reads return futures (e.g. browser / edge worker). Behind the async feature.

Source

pub async fn open_async(reader: R) -> Result<Self, StreamError>

Available on crate feature async only.

Open and validate a 2D f64 index from an async reader.

Source

pub async fn open_with_limits_async( reader: R, limits: StreamLimits, ) -> Result<Self, StreamError>

Available on crate feature async only.

Open from an async reader with per-query StreamLimits. See StreamIndex2D::open_with_limits.

Source

pub async fn search_async( &self, query: Box2D, ) -> Result<Vec<usize>, StreamError>

Available on crate feature async only.

Stream the indices of every item whose box intersects query.

Source

pub async fn search_payloads_async( &self, query: Box2D, ) -> Result<Vec<(usize, Vec<u8>)>, StreamError>

Available on crate feature async only.

Stream (item index, payload blob) for every item intersecting query.

Source

pub async fn visit_region_async<Q, F>( &self, query: &Q, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(usize),

Available on crate feature async only.

Stream the indices of every item whose box overlaps the region query — any Overlaps2D shape, not just a box.

Source

pub async fn search_region_async<Q: Overlaps2D>( &self, query: &Q, ) -> Result<Vec<usize>, StreamError>

Available on crate feature async only.

Collect the indices of every item whose box overlaps the region query.

Source

pub async fn visit_payloads_region_async<Q, F>( &self, query: &Q, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(usize, &[u8]),

Available on crate feature async only.

Visit (item index, payload blob) for every item whose box overlaps the region query.

Source

pub async fn search_payloads_region_async<Q: Overlaps2D>( &self, query: &Q, ) -> Result<Vec<(usize, Vec<u8>)>, StreamError>

Available on crate feature async only.

Collect (item index, payload blob) for every item whose box overlaps the region query.

Source

pub async fn visit_payload_prefixes_async<F: FnMut(PayloadPrefix<'_>)>( &self, query: Box2D, prefix_len: usize, visitor: F, ) -> Result<(), StreamError>

Available on crate feature async only.
Source

pub async fn visit_payload_prefixes_region_async<Q, F>( &self, query: &Q, prefix_len: usize, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(PayloadPrefix<'_>),

Available on crate feature async only.
Source

pub async fn visit_payloads_at_ranks_async<F: FnMut(usize, &[u8])>( &self, leaf_ranks: &[usize], visitor: F, ) -> Result<(), StreamError>

Available on crate feature async only.
Source

pub fn has_payload_async(&self) -> bool

Available on crate feature async only.

Whether this index was written with a payload section.

Source§

impl<R> StreamIndex2D<R>

Source

pub fn into_directory(self) -> (StreamDirectory, R)

Split off the reader, keeping the reusable StreamDirectory. No I/O.

Source

pub fn from_directory( dir: &StreamDirectory, reader: R, ) -> Result<Self, StreamError>

Rebuild a 2D f64 index from a cached directory and a fresh reader. No I/O: the directory reads were paid when it was first opened.

Source

pub fn from_directory_with_limits( dir: &StreamDirectory, reader: R, limits: StreamLimits, ) -> Result<Self, StreamError>

from_directory with per-query StreamLimits.

Source

pub fn num_items(&self) -> usize

Number of indexed items.

Source

pub fn is_empty(&self) -> bool

Whether the index has no items.

Source

pub fn node_size(&self) -> usize

Packed node size of the index.

Source

pub fn has_payload(&self) -> bool

Whether this index was written with a payload section.

Source§

impl<R: RangeReader> StreamIndex2D<R>

Source

pub fn open(reader: R) -> Result<Self, StreamError>

Open and validate a 2D f64 index from reader.

Reads and validates the header and level bounds and prefetches the upper levels of the tree. Returns StreamError::Format for a corrupt or wrong-variant index and StreamError::Io for a read failure.

Source

pub fn open_with_limits( reader: R, limits: StreamLimits, ) -> Result<Self, StreamError>

Open with per-query cost StreamLimits. Every query then aborts with StreamError::LimitExceeded if it would exceed a limit — use this to bound a broad query’s reads / bytes / results to your environment (e.g. a worker’s subrequest and memory budgets).

Source

pub fn extent(&self) -> Option<Box2D>

Total extent of all indexed items, or None for an empty index.

Read from the cached root box, so this costs no I/O.

Source

pub fn visit<F: FnMut(usize)>( &self, query: Box2D, visitor: F, ) -> Result<(), StreamError>

Stream the indices of every item whose box intersects query, passing each to visitor.

Fallible: a read from the backing RangeReader can fail mid-query, and a corrupt index is reported as StreamError::Format. Items are yielded in tree-traversal order, which is not part of the API.

Source

pub fn search(&self, query: Box2D) -> Result<Vec<usize>, StreamError>

Stream the indices of every item whose box intersects query.

Source

pub fn search_into( &self, query: Box2D, out: &mut Vec<usize>, ) -> Result<(), StreamError>

Like search, but appends into a reused buffer (cleared first) to avoid reallocating across queries.

Source

pub fn visit_payloads<F: FnMut(usize, &[u8])>( &self, query: Box2D, visitor: F, ) -> Result<(), StreamError>

Visit (item index, payload blob) for every item intersecting query.

The payload section is stored in leaf order, so a spatial query fetches its blobs (and their offset table) in coalesced reads — a handful of round trips even over a remote source, instead of one per item. The blob slice is valid only for the duration of each call. Returns StreamError::NoPayload if the index has no payload section.

Source

pub fn search_payloads( &self, query: Box2D, ) -> Result<Vec<(usize, Vec<u8>)>, StreamError>

Collect (item index, payload blob) for every item intersecting query. The owning counterpart of visit_payloads.

Source

pub fn visit_region<Q, F>( &self, query: &Q, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(usize),

Stream the indices of every item whose box overlaps the region query — any Overlaps2D shape (a polygon, triangle, …), not just a box.

Subtrees whose node box falls outside query are pruned during the streamed descent, so a region query fetches only the leaves it overlaps — less data than its bounding box. (Pruning can fragment the coalesced runs, so the range-request count is shape-dependent; the bytes always shrink.)

Source

pub fn search_region<Q: Overlaps2D>( &self, query: &Q, ) -> Result<Vec<usize>, StreamError>

Collect the indices of every item whose box overlaps the region query.

Source

pub fn visit_payloads_region<Q, F>( &self, query: &Q, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(usize, &[u8]),

Visit (item index, payload blob) for every item whose box overlaps the region query. Like visit_payloads but for a custom Overlaps2D shape; node-box pruning fetches only the leaves the region touches.

Source

pub fn search_payloads_region<Q: Overlaps2D>( &self, query: &Q, ) -> Result<Vec<(usize, Vec<u8>)>, StreamError>

Collect (item index, payload blob) for every item whose box overlaps the region query. The owning counterpart of visit_payloads_region.

Source

pub fn visit_payload_prefixes<F: FnMut(PayloadPrefix<'_>)>( &self, query: Box2D, prefix_len: usize, visitor: F, ) -> Result<(), StreamError>

Visit a PayloadPrefix for every item intersecting query: id, leaf rank, full payload length, and the first prefix_len payload bytes.

Payload bodies past the prefix are not read — lengths come from the offset table (or the fixed stride) — so identity prefixes and size summaries cost a fraction of visit_payloads. Capture leaf_rank values here and feed a page of them to visit_payloads_at_ranks to fetch full payloads later. Returns StreamError::NoPayload if the index has no payload section.

§Example
use packed_spatial_index::{Box2D, Index2DBuilder, SliceReader, StreamIndex2D};

let mut builder = Index2DBuilder::new(2);
builder.add(Box2D::new(0.0, 0.0, 1.0, 1.0));
builder.add(Box2D::new(5.0, 5.0, 6.0, 6.0));
let index = builder.finish()?;
let bytes = index.to_bytes_with_payloads(&[
    b"first payload".as_slice(),
    b"second payload".as_slice(),
])?;

let stream = StreamIndex2D::open(SliceReader::new(bytes))?;
let mut headers = Vec::new();
stream.visit_payload_prefixes(Box2D::new(-1.0, -1.0, 7.0, 7.0), 5, |p| {
    headers.push((p.id, p.leaf_rank, p.payload_len, p.prefix.to_vec()));
})?;
assert_eq!(headers.len(), 2);

let page_ranks = [headers[0].1];
let mut page = Vec::new();
stream.visit_payloads_at_ranks(&page_ranks, |rank, blob| {
    page.push((rank, blob.to_vec()));
})?;
assert_eq!(page[0].0, headers[0].1);
assert_eq!(page[0].1.len(), headers[0].2);
Source

pub fn visit_payload_prefixes_region<Q, F>( &self, query: &Q, prefix_len: usize, visitor: F, ) -> Result<(), StreamError>
where Q: Overlaps2D, F: FnMut(PayloadPrefix<'_>),

visit_payload_prefixes for a custom Overlaps2D region; node-box pruning fetches only the leaves the region touches.

Source

pub fn visit_payloads_at_ranks<F: FnMut(usize, &[u8])>( &self, leaf_ranks: &[usize], visitor: F, ) -> Result<(), StreamError>

Visit (leaf rank, payload blob) for an explicit set of leaf ranks — random-access payload reads for ranks captured by a prefix visit. Ranks are sorted and deduplicated internally, read in coalesced ascending runs, and emitted in ascending rank order. A rank at or past the item count fails with StreamError::InvalidRank.

Auto Trait Implementations§

§

impl<R> Freeze for StreamIndex2D<R>
where R: Freeze,

§

impl<R> RefUnwindSafe for StreamIndex2D<R>
where R: RefUnwindSafe,

§

impl<R> Send for StreamIndex2D<R>
where R: Send,

§

impl<R> Sync for StreamIndex2D<R>
where R: Sync,

§

impl<R> Unpin for StreamIndex2D<R>
where R: Unpin,

§

impl<R> UnsafeUnpin for StreamIndex2D<R>
where R: UnsafeUnpin,

§

impl<R> UnwindSafe for StreamIndex2D<R>
where R: UnwindSafe,

Blanket Implementations§

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
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.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.