Skip to main content

StorageProfile

Struct StorageProfile 

Source
pub struct StorageProfile {
    pub seek_latency_s: f64,
    pub sequential_bandwidth_bps: f64,
    pub block_bytes: u64,
}
Expand description

Parameters of a storage medium, expressed in the units the cost model needs.

The two parameters that matter most on non-uniform storage are the seek latency (the fixed price of positioning at a read) and the sequential bandwidth (the marginal price per byte once positioned). On a 7200rpm HDD the former dominates the latter by orders of magnitude, which is precisely why minimizing seek count — not bytes, and not graph hops — is the lever.

Classical in-RAM ANN implicitly assumes StorageProfile::memory, where the seek latency is ~0 and bandwidth is effectively unbounded; under that profile the storage-access term vanishes and only graph hops remain. Slate-ANN takes the profile as an input instead.

Fields§

§seek_latency_s: f64

Latency to position at a fresh random read, in seconds.

For an HDD this is head-seek plus average rotational latency; for an SSD it is a small controller/queue constant; for RAM it is ~0.

§sequential_bandwidth_bps: f64

Sustained sequential transfer rate, in bytes per second.

§block_bytes: u64

Natural transfer granularity of the medium, in bytes.

Reads smaller than this still pay for at least this many bytes of transfer (HDD sector / SSD page / OS page). Used when pricing a read whose payload is smaller than one block.

Implementations§

Source§

impl StorageProfile

Source

pub const fn hdd_7200rpm() -> Self

A representative 7200rpm consumer hard disk drive.

~9 ms seek (≈4.2 ms average rotational latency at 7200rpm plus head seek), ~160 MB/s sequential, 4 KiB minimum transfer. This is the headline target medium: the regime where the uniform-latency assumption is most catastrophically wrong.

Source

pub const fn ssd_nvme() -> Self

A representative consumer NVMe solid-state drive.

~100 µs effective random-access latency, ~3.5 GB/s sequential, 4 KiB page. Random reads are cheap here, which is why SSD-tuned designs (e.g. DiskANN) can afford one small random read per hop.

Source

pub const fn memory() -> Self

Resident memory: the implicit medium of classical in-RAM ANN.

Negligible seek, very high bandwidth, cache-line granularity. Under this profile QueryCost::storage_access_s is ~0 and query cost is dominated by traversal and distance computation — the classical special case.

Source

pub fn transfer_s(self, bytes: u64) -> f64

Seconds to transfer bytes at the medium’s sequential bandwidth.

This is the honest transfer time for an already-summed byte count: zero bytes costs zero. Per-read block-granularity flooring lives in read_s, since “a read smaller than a block still pays for a block” is a property of an individual read, not of an aggregate.

Source

pub fn read_s(self, bytes: u64) -> f64

Modelled latency of a single read of bytes: one seek plus the transfer of at least one block.

Trait Implementations§

Source§

impl Clone for StorageProfile

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for StorageProfile

Source§

impl Debug for StorageProfile

Source§

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

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

impl<'de> Deserialize<'de> for StorageProfile

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for StorageProfile

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for StorageProfile

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for StorageProfile

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.