Skip to main content

SequentialClusterReader

Struct SequentialClusterReader 

Source
pub struct SequentialClusterReader {
    pub metrics: SequentialClusterReaderMetrics,
}
Expand description

Sequential cluster reader for single-I/O chain optimization.

This struct performs sequential I/O operations on confirmed linear chains and tracks metrics for diagnostic analysis.

§Design

  • Metrics tracking: metrics field tracks read time, bytes, and counts
  • Single I/O: read_chain_clusters() performs one large read_bytes() call
  • Deferred deserialization: extract_neighbors() deserializes on-demand

§Example

use crate::backend::native::adjacency::SequentialClusterReader;

let mut reader = SequentialClusterReader::new();

// Read all clusters for a chain in one I/O operation
let cluster_offsets = [(1024, 4096), (5120, 4096), (9216, 4096)];
let buffer = reader.read_chain_clusters(graph_file, &cluster_offsets)?;

// Extract neighbors for cluster at index 1
let neighbors = reader.extract_neighbors(&buffer, 1, &cluster_offsets)?;

// Access metrics
println!("Read time: {:.2}ms, Bytes: {}", reader.metrics.read_time_ms(), reader.metrics.total_bytes_read);

Fields§

§metrics: SequentialClusterReaderMetrics

Metrics for diagnostic analysis (Phase 37)

Implementations§

Source§

impl SequentialClusterReader

Source

pub fn new() -> Self

Create new sequential cluster reader with zero-initialized metrics

Source

pub fn read_chain_clusters( &mut self, graph_file: &mut GraphFile, cluster_offsets: &[(u64, u32)], ) -> NativeResult<Vec<u8>>

Read all clusters for a chain in a single I/O operation.

This method performs a single sequential read of all contiguous clusters for a confirmed linear chain. The clusters are returned as raw bytes to defer deserialization until neighbor extraction.

§Parameters
  • graph_file: Mutable borrow for I/O operations
  • cluster_offsets: Slice of (offset, size) tuples, MUST be contiguous
§Returns
  • Ok(Vec): Raw bytes containing all clusters concatenated
  • Err(NativeBackendError):
    • InvalidParameter: If cluster_offsets is empty
    • RecordTooLarge: If total size exceeds MAX_CLUSTER_BUFFER_SIZE
    • Io: If file read fails
§Precondition

Caller MUST validate contiguity first (via are_clusters_contiguous()). This method assumes clusters are contiguous and reads them as one block. Non-contiguous clusters will result in garbage data.

§Example
use crate::backend::native::adjacency::{are_clusters_contiguous, SequentialClusterReader};

let mut reader = SequentialClusterReader::new();
let cluster_offsets = [(1024, 4096), (5120, 4096), (9216, 4096)];

// Validate contiguity first
assert!(are_clusters_contiguous(&cluster_offsets));

// Read all clusters in one I/O operation
let buffer = reader.read_chain_clusters(graph_file, &cluster_offsets)?;
assert_eq!(buffer.len(), 12288); // 3 × 4096
Source

pub fn extract_neighbors( &mut self, buffer: &[u8], cluster_index: usize, cluster_offsets: &[(u64, u32)], ) -> NativeResult<Vec<NativeNodeId>>

Extract neighbors for a specific cluster from buffered bytes.

This method deserializes a single cluster from the concatenated buffer returned by read_chain_clusters(). Deserialization is performed on-demand to avoid CPU cost for clusters never accessed.

§Parameters
  • buffer: Raw cluster bytes from read_chain_clusters()
  • cluster_index: Index of cluster within the buffer (0-based)
  • cluster_offsets: Original offsets slice (to calculate byte position)
§Returns
  • Ok(Vec): Neighbor IDs for the requested cluster
  • Err(NativeBackendError):
    • InvalidParameter: If cluster_index is out of bounds
    • Deserialization errors from EdgeCluster::deserialize()
§Byte Offset Calculation

The byte offset for a cluster is calculated by summing the sizes of all preceding clusters in the buffer:

cluster_index=0: byte_offset = 0
cluster_index=1: byte_offset = cluster_offsets[0].size
cluster_index=2: byte_offset = cluster_offsets[0].size + cluster_offsets[1].size
...
§Example
use crate::backend::native::adjacency::SequentialClusterReader;

let mut reader = SequentialClusterReader::new();
let cluster_offsets = [(1024, 4096), (5120, 4096), (9216, 4096)];
let buffer = reader.read_chain_clusters(graph_file, &cluster_offsets)?;

// Extract neighbors from first cluster (index 0)
let neighbors_0 = reader.extract_neighbors(&buffer, 0, &cluster_offsets)?;

// Extract neighbors from second cluster (index 1)
let neighbors_1 = reader.extract_neighbors(&buffer, 1, &cluster_offsets)?;

// Extract neighbors from third cluster (index 2)
let neighbors_2 = reader.extract_neighbors(&buffer, 2, &cluster_offsets)?;

Trait Implementations§

Source§

impl Default for SequentialClusterReader

Source§

fn default() -> Self

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

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V