Skip to main content

Scratch

Struct Scratch 

Source
pub struct Scratch { /* private fields */ }
Expand description

The tables a set operation fills in on its way to an answer.

A union walks everything into one table and lets the table be the duplicate check. An accumulating intersection counts into one. Both of those used to be built per call, which is a hash table out of the allocator on a command path, and it is the thing the text rows of the benchmark were mostly spending their time on.

So the tables belong to the caller now. A database keeps one of these and hands it in, the tables are cleared rather than dropped between calls, and a SUNION over sets no larger than the last one pays the allocator nothing at all. The memory that costs is one table as big as the largest union the database has been asked for, which is smaller than the answer it already had to build.

setops_small’s union/text/k2 row, nanoseconds per operation over two text sets of eight members, went from 368.54 to 248.18 when the table stopped being built per call. That is 1.48 times on a command shaped like the ones people actually send. The integer rows do not move at all, because those take the merge plan and never build a table in the first place, which is the same split the Small work saw from the other side.

It is Default, so a caller that does not care can pass &mut Scratch::default() and get exactly the old behaviour.

Implementations§

Source§

impl Scratch

Source

pub fn new() -> Scratch

Empty tables that have not asked the allocator for anything yet.

Source

pub fn memory_bytes(&self) -> usize

What the tables are holding on to, for MEMORY USAGE and for tests.

Trait Implementations§

Source§

impl Debug for Scratch

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Scratch

Source§

fn default() -> Scratch

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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