pub(crate) struct Scan<'a> {
q: &'a Search,
needle: Option<[u8; 16]>,
probes: Vec<AttrProbe>,
ranges: Vec<Probe>,
after: Reverse<(i64, u32, u64, u32)>,
}Expand description
Everything the per-block half of a search reads, and nothing it writes.
One struct rather than five arguments because it crosses a thread boundary:
shared by reference, immutable for the whole scan, and therefore Sync
without a lock. What is left out is as deliberate — hits and stats are
the only state a block scan produces, and both are returned rather than
accumulated, which is what makes the blocks independent.
Fields§
§q: &'a Search§needle: Option<[u8; 16]>§probes: Vec<AttrProbe>§ranges: Vec<Probe>§after: Reverse<(i64, u32, u64, u32)>Implementations§
Source§impl<'a> Scan<'a>
impl<'a> Scan<'a>
Sourcepub(crate) fn new(q: &'a Search) -> Scan<'a>
pub(crate) fn new(q: &'a Search) -> Scan<'a>
The per-block half of a query, prepared once.
Everything here is derived from q alone, which is what lets one Scan
serve every block of a search and every thread scanning them.
Sourcepub(crate) fn wave(
&self,
refs: &[Src<'_>],
from: usize,
to: usize,
) -> Vec<Result<(Option<Block>, Vec<Hit>)>> ⓘ
pub(crate) fn wave( &self, refs: &[Src<'_>], from: usize, to: usize, ) -> Vec<Result<(Option<Block>, Vec<Hit>)>> ⓘ
Blocks [from, to) scanned at once, answered in block order.
std::thread::scope and not a pool: the threads borrow the mapping, the
query and each other’s nothing, and a scope is the one construct that
lets them do that without an Arc around every field. They are also the
wrong threads to pool — a pool exists to amortise spawns against short
tasks, and a block scan is milliseconds against a spawn’s microseconds.
The caller’s own thread takes the first block, so a wave with no helpers — the first wave of every search, and every wave on a busy node — spawns nothing at all.
to is the wave the ramp asked for and the answer may be shorter: what
SPARE hands out decides how many blocks this wave actually covers,
and the caller advances by the number of answers rather than by the
width it asked for.
Auto Trait Implementations§
impl<'a> Freeze for Scan<'a>
impl<'a> RefUnwindSafe for Scan<'a>
impl<'a> Send for Scan<'a>
impl<'a> Sync for Scan<'a>
impl<'a> Unpin for Scan<'a>
impl<'a> UnsafeUnpin for Scan<'a>
impl<'a> UnwindSafe for Scan<'a>
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].