Skip to main content

EdgeRef

Struct EdgeRef 

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

One end of an edge in an adjacency list — interned (0.8.0, B2, D-115).

Five fields, no heap payload, size_of 24 bytes against 104 bytes of struct plus around 250 of strings before. Every field but the weight is an index into its Subgraph’s pool, so reading one needs the graph:

for e in graph.out_edges("a") {
    println!("{} {} {}", e.node(&graph), e.edge_type(&graph), e.weight());
}

That is the visible cost of the change, and it is the reason B1 had to privatise these fields first: a public node: String cannot become a u32. The win is reachability, not speed (D-073’s category): graphs that did not fit the byte budget start fitting.

§Invariants

An EdgeRef is tied to the specific Subgraph it was retrieved from. Querying it against a different one — via an accessor like Self::node, or via derived PartialEq — is a logic error that will silently return incorrect data or report equality where none exists. Because the handle is Copy it can be stored in a struct that outlives the graph; it stays well-formed and becomes meaningless without its pool.

PartialEq is the sharp edge, and it is kept rather than removed: within one graph, index equality is exactly the comparison a caller wants, and it is cheaper and stricter than comparing five strings. Across two graphs it compares indices that mean different things — a wrong answer that needs no accessor call at all, so it sits outside the mental model of “querying”. Before interning, == compared the strings and could not be wrong this way.

This logic error does not result in undefined behaviour — every index goes through bounds-checked slice indexing and there is no unsafe here — but the results are otherwise unspecified.

The handle is intentionally not lifetime-branded, which would make the invariant a compile error, because that propagates a generic parameter through every algorithm and every signature that mentions a Subgraph. See D-115 for the argument and for what to do if this is ever hit in practice.

Implementations§

Source§

impl EdgeRef

Source

pub fn node<'a>(&self, graph: &'a Subgraph) -> &'a str

The far end of the edge: the target in out_edges, the source in in_edges.

Takes the graph because the string lives in its pool. graph must be the one this edge came from; passing another is a programming error and will panic or answer nonsense, exactly as indexing the wrong slice would.

Source

pub fn edge_type<'a>(&self, graph: &'a Subgraph) -> &'a str

Source

pub fn weight(&self) -> f64

The only field that is not interned, because an f64 is already 8 bytes and a pool of them would cost more than it saved.

Source

pub fn valid_from<'a>(&self, graph: &'a Subgraph) -> &'a str

Source

pub fn valid_to<'a>(&self, graph: &'a Subgraph) -> &'a str

Trait Implementations§

Source§

impl Clone for EdgeRef

Source§

fn clone(&self) -> EdgeRef

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 EdgeRef

Source§

impl Debug for EdgeRef

Written by hand so a failing assert_eq! cannot be mistaken for one about strings.

The derived form printed EdgeRef { node: 3, edge_type: 1, .. }, which reads as data and is not: those are pool indices, meaningless without the graph. The # is there to say so at a glance.

Source§

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

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

impl PartialEq for EdgeRef

Source§

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

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

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

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for EdgeRef

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = 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

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more