Skip to main content

DiGraph

Struct DiGraph 

Source
pub struct DiGraph { /* private fields */ }

Implementations§

Source§

impl DiGraph

Source

pub fn clear_edges(&mut self)

br-r37-c1-clearedgesinplace (cc): drop all edges in place, keeping nodes (index, order, attrs). O(E)+O(V): clear the edges map + every succ/pred index row; the revision bump invalidates the CSR + all-int caches. Sibling of Graph::clear_edges and MultiDiGraph::clear_edges. The binding’s prior path collected the mirror keys and called remove_edge per edge (each an O(degree) row retain -> O(E*degree), measured ~0.003-0.011x vs nx); this is the in-place fix.

Source

pub fn clone_with_fresh_policy(&self) -> Self

br-r37-c1-7dpyg: structural clone with a FRESH RuntimePolicy — see Graph::clone_with_fresh_policy.

Source

pub fn new(mode: CompatibilityMode) -> Self

Source

pub fn with_runtime_policy(runtime_policy: RuntimePolicy) -> Self

Source

pub fn induced_subgraph_ordered( &self, order: &[usize], runtime_policy: RuntimePolicy, ) -> Self

br-r37-c1-indsub: directed twin of Graph::induced_subgraph_ordered — build the induced subgraph over order (parent node indices, already in the caller’s output order) with no node-name hashing.

add_edge_with_attrs costs two String allocations, four name hashes and TWO record_decision ledger entries per arc (the second carrying four EvidenceTerms, eight more String allocations). Everything it re-derives is already known here. Invariants reproduced directly: edges keyed by the ORIENTED new-index pair (direction is identity for a directed edge, so no canonicalization), and a succ/pred row records its endpoint when the arc is emitted, so both row orders are the walk order — matching nx’s add_edges_from over the induced walk.

order must contain distinct, in-range parent indices.

Source

pub fn strict() -> Self

Source

pub fn hardened() -> Self

Source

pub fn mode(&self) -> CompatibilityMode

Source

pub fn node_count(&self) -> usize

Source

pub fn edge_count(&self) -> usize

Source

pub fn revision(&self) -> u64

Source

pub fn csr(&self) -> Arc<DiCsr> ⓘ

br-r37-c1-d58s8 P1: revision-keyed integer CSR of both row families. O(V+E) rebuild only when the graph changed since the cached build; kernels get index walks identical to the String walks (per-row order preserved).

Source

pub fn edge_weights_all_int(&self, attr: &str) -> bool

br-r37-c1-d58s8: revision-keyed memo of “every edge’s attr value is an integer (missing = default 1 = int)”.

Source

pub fn has_node(&self, node: &str) -> bool

Source

pub fn successors_indices(&self, idx: usize) -> Option<&[usize]>

br-r37-c1-1l8s0: direct slice access to the eager succ index row, by node position (through the position view while slots are not dense).

Source

pub fn predecessors_indices(&self, idx: usize) -> Option<&[usize]>

Direct slice access to the eager pred index row, by node position.

Source

pub fn has_edge(&self, source: &str, target: &str) -> bool

Source

pub fn has_edge_by_indices(&self, source_idx: usize, target_idx: usize) -> bool

br-r37-c1-04z53 (cc): directed has_edge straight from insertion-order indices (source-major), skipping the i.to_string() heap alloc for int nodes. Names come from the node table by index (borrowed); the caller guards each index with node_index_matches_int. Mirror of Graph::has_edge_by_indices.

br-r37-c1-p1tvg: this used to resolve both indices back to NAMES and call has_edge, which hashes two Strings to rediscover the very indices it was handed — exactly the cost a caller pays an index route to avoid. The edges map has been keyed by the ORIENTED (source_idx, target_idx) pair since the d58s8 flip, so the pair IS the key. An out-of-range index still answers false: every key in the map names two live nodes, so no key can carry one.

Source

pub fn nodes_ordered(&self) -> Vec<&str>

Source

pub fn node_index_matches_int(&self, idx: usize) -> bool

br-cc-nbunchbulk: does the node at contiguous index idx have the exact int name idx? O(1) index probe + no-alloc parse — the int membership fast path for _nbunch_present (sibling of the undirected Graph accessor).

Source

pub fn node_names_are_positions(&self) -> bool

sfq4w.3: see Graph::node_names_are_positions.

Source

pub fn get_node_index(&self, node: &str) -> Option<usize>

Source

pub fn get_node_name(&self, index: usize) -> Option<&str>

Source

pub fn successors(&self, node: &str) -> Option<Vec<&str>>

Successors of node (outgoing neighbors). Returns None if node absent.

Source

pub fn successors_iter( &self, node: &str, ) -> Option<impl Iterator<Item = &str> + '_>

Source

pub fn out_edge_attrs( &self, node: &str, ) -> Option<impl Iterator<Item = &AttrMap> + '_>

yr2oc.4: the attribute maps of node’s out-edges in successor-row order. Read by slot: no position translation after a removal.

Source

pub fn in_edge_attrs( &self, node: &str, ) -> Option<impl Iterator<Item = &AttrMap> + '_>

yr2oc.4: the attribute maps of node’s in-edges in predecessor-row order. Read by slot: no position translation after a removal.

Source

pub fn predecessors(&self, node: &str) -> Option<Vec<&str>>

Predecessors of node (incoming neighbors). Returns None if node absent.

Source

pub fn apply_row_orders(&mut self, orders: &[(String, Vec<String>)], pred: bool)

br-r37-c1-u3qyn: restore explicit succ/pred row orders (pickle round-trip) — see Graph::apply_row_orders. which selects the adjacency side.

Source

pub fn reorder_pred_rows_for_nx_copy_walk(&mut self)

br-r37-c1-0ek49: reorder every PRED row into NetworkX’s DiGraph.copy() walk order. nx copy rebuilds via the u-major succ walk ((u, v, d) for u in _adj for v in _adj[u]), which recreates succ rows in their original order but fills each pred row in walk order: (pos(u), index of v within succ[u]). Call on a fresh clone inside copy-shaped constructors; graph content is unchanged, only pred row order moves.

Source

pub fn reorder_rows_like(&mut self, source: &Self, swap: bool)

br-r37-c1-36v6r: order each successor and predecessor row as source’s row for the node of the same name - its succ / pred rows, or its pred / succ rows when swap (a reverse view’s). A graph built from a filtered or reverse view of source by a copy-shaped walk fills pred rows in succ-walk order (networkx’s view.copy() does the same), where the view’s pred row is source’s row filtered. Entries source’s row lacks keep their relative order after the matched ones. Graph content is unchanged; revision moves if any row does.

Source

pub fn set_row_orders( &mut self, succ_rows: &[Vec<usize>], pred_rows: &[Vec<usize>], ) -> bool

br-r37-c1-36v6r: order every successor and predecessor row as given - succ_rows[i] / pred_rows[i] are the rows of the node at position i, neighbours as positions - for a row order no graph holds, such as a to_directed(as_view=True) view’s (both rows the undirected graph’s row). All or nothing: false, and nothing changes, unless every given row is a permutation of the current one.

Source

pub fn predecessors_iter( &self, node: &str, ) -> Option<impl Iterator<Item = &str> + '_>

Source

pub fn neighbors(&self, node: &str) -> Option<Vec<&str>>

Neighbors = successors (matches NetworkX DiGraph.neighbors() convention).

Source

pub fn neighbors_iter( &self, node: &str, ) -> Option<impl Iterator<Item = &str> + '_>

Source

pub fn neighbor_count(&self, node: &str) -> usize

Source

pub fn out_degree(&self, node: &str) -> usize

Out-degree: number of successors.

Source

pub fn in_degree(&self, node: &str) -> usize

In-degree: number of predecessors.

Source

pub fn degree(&self, node: &str) -> usize

Total degree: in_degree + out_degree.

Source

pub fn out_degree_by_index(&self, idx: usize) -> usize

br-r37-c1-degidx: index-based degree accessors — O(1), zero String hashing (the &str path costs get_index_of per call; degree pays it twice). Used by the directed DegreeView iterator which walks nodes in index order.

Source

pub fn in_degree_by_index(&self, idx: usize) -> usize

Source

pub fn degree_by_index(&self, idx: usize) -> usize

Source

pub fn out_edges<'a>(&'a self, node: &'a str) -> Vec<(&'a str, &'a str)>

Outgoing edges from node as (source, target) pairs.

Source

pub fn in_edges<'a>(&'a self, node: &'a str) -> Vec<(&'a str, &'a str)>

Incoming edges to node as (source, target) pairs.

Source

pub fn node_attrs(&self, node: &str) -> Option<&AttrMap>

Source

pub fn node_attrs_by_index(&self, idx: usize) -> Option<&AttrMap>

Source

pub fn edge_attrs(&self, source: &str, target: &str) -> Option<&AttrMap>

Attributes of directed edge source→target.

Source

pub fn edge_attrs_by_indices( &self, source_idx: usize, target_idx: usize, ) -> Option<&AttrMap>

br-r37-c1-d58s8: index-keyed attr access (oriented). Zero node-map probes for callers already holding indices.

Source

pub fn any_edge_has_attr(&self, key: &str) -> bool

br-r37-c1-hasattrlazyfix: does ANY directed edge carry the attribute key in the authoritative Rust storage (the inner edges AttrMaps), regardless of whether the lazy edge_py_attrs Python mirror has been materialized? ~O(E) key checks.

Source

pub fn all_edge_attr_values_scalar(&self) -> bool

Directed twin of Graph::all_edge_attr_values_scalar: true if EVERY inner edge attr value is a faithful scalar (Int/Float/Bool). No-alloc scan over the edge store values — contrast edges_ordered_borrowed, which allocates an O(E) Vec and resolves node names per edge. Used by the reverse gate.

Source

pub fn any_node_has_attrs(&self) -> bool

br-r37-c1-hasanyattrlazyfix: any node / any edge carries a Python-visible attr per the authoritative inner storage (not the lazy *_py_attrs mirrors).

Source

pub fn any_edge_has_attrs(&self) -> bool

Source

pub fn edges_indexed( &self, ) -> impl Iterator<Item = ((usize, usize), &AttrMap)> + '_

br-r37-c1-prdir: iterate every directed edge as ((source_idx, target_idx), &AttrMap) straight from the index-keyed edge store, in insertion order. Lets COO/CSR exporters read each edge’s weight with ONE attr lookup instead of the per-edge edges.get(&(u,v)) hash that the successors-then-edge_attrs_by_indices path pays.

Source

pub fn evidence_ledger(&self) -> &EvidenceLedger

Source

pub fn drain_decision_records(&mut self) -> Vec<DecisionRecord>

Source

pub fn record_external_recovery( &mut self, operation: impl Into<Cow<'static, str>>, rationale: impl Into<Cow<'static, str>>, )

Record a bounded recovery performed outside the graph (e.g. a reader skipping a malformed line in hardened mode) in this graph’s ledger.

Source

pub fn runtime_policy(&self) -> &RuntimePolicy

Source

pub fn set_runtime_policy(&mut self, runtime_policy: RuntimePolicy)

Source

pub fn is_directed(&self) -> bool

Type identity: always true for DiGraph.

Source

pub fn is_multigraph(&self) -> bool

Type identity: always false for DiGraph (not a multigraph).

Source

pub fn add_node(&mut self, node: impl AsRef<str> + Into<String>) -> bool

Source

pub fn add_node_with_attrs( &mut self, node: impl AsRef<str> + Into<String>, attrs: AttrMap, ) -> bool

Source

pub fn apply_node_defaults(&mut self, defaults: &AttrMap) -> bool

Source

pub fn add_edge( &mut self, source: impl AsRef<str>, target: impl AsRef<str>, ) -> Result<(), GraphError>

Source

pub fn add_edge_with_attrs( &mut self, source: impl AsRef<str>, target: impl AsRef<str>, attrs: AttrMap, ) -> Result<(), GraphError>

br-r37-c1-jc9e4: the directed mirror of the Graph sibling — the endpoint keys are never owned here, and each is resolved with ONE map probe. This used to own both keys, clone each again for autocreation, and then hash each up to three times (contains_key, get_index_of for the edge key, get_index_of again for the successor/predecessor rows). The census measured the directed pair at the undirected pair’s pre-lever numbers, so none of that transferred on its own.

Source

pub fn extend_edges_unrecorded<I, S, T>(&mut self, edges: I) -> usize
where I: IntoIterator<Item = (S, T)>, S: Into<String>, T: Into<String>,

Bulk-add a sequence of attribute-free directed edges. Bypasses the per-edge runtime_policy.record_decision call that [add_edge_with_attrs] makes. Instead, emit one summary record for the whole batch.

Intended for fnx-internal callers that build a fresh graph from a known-good edge list where per-edge compatibility accounting would add constant-factor overhead without adding useful policy evidence. Nodes referenced by edges are auto-created if absent, matching add_edge semantics.

Source

pub fn extend_existing_index_edges_unrecorded<I>(&mut self, edges: I) -> usize
where I: IntoIterator<Item = (usize, usize)>,

br-r37-c1-tcidx: bulk-add directed edges by EXISTING node index — the directed sibling of Graph::extend_existing_index_edges_unrecorded. All endpoints MUST already exist (callers gate on all nodes being pre-added). A new edge takes an empty AttrMap; a duplicate (source_idx, target_idx) pair is skipped. Emits the IDENTICAL succ/pred adjacency, revision bump, and batch ledger summary as extend_edges_unrecorded given the same resolved index sequence — but with ZERO String hashing (endpoints arrive as integer indices). Unblocks the O(|V|²)-closure transitive_closure from paying a per-edge get_index_of on both endpoints.

Source

pub fn extend_nodes_unrecorded<I, N>(&mut self, nodes: I) -> usize
where I: IntoIterator<Item = N>, N: Into<String>,

br-r37-c1-digbatch: bulk-add plain nodes (no attrs), one summary ledger record — the directed sibling of Graph::extend_nodes_unrecorded, backing PyDiGraph’s fast integer-node path (add_nodes_from(range) / int list). First insertion wins order; existing nodes are skipped.

Source

pub fn extend_nodes_with_attrs_unrecorded<I>(&mut self, nodes: I) -> usize
where I: IntoIterator<Item = (String, AttrMap)>,

br-r37-c1-dgctor: bulk-add nodes WITH attrs, one summary ledger record — the directed sibling of Graph::extend_nodes_unrecorded extended with per-node AttrMaps. First insertion wins the order; re-inserting an existing node merges attrs (matching add_node_with_attrs).

Source

pub fn extend_edges_with_attrs_unrecorded<I>(&mut self, edges: I) -> usize
where I: IntoIterator<Item = (String, String, AttrMap)>,

br-r37-c1-dgctor: bulk-add ATTRIBUTED directed edges without per-edge ledger records — the directed sibling of Graph::extend_edges_with_attrs_unrecorded. Insert-or-MERGE (duplicate (source, target) extends the existing AttrMap, matching add_edge_with_attrs); nodes auto-created in first-appearance order. Callers must pre-screen “__fnx_incompatible” attr keys.

Source

pub fn extend_prepared_edges_with_attrs_row_staged_unrecorded<I, N>( &mut self, new_nodes: N, edges: I, ) -> usize
where I: IntoIterator<Item = (String, String, AttrMap)>, N: IntoIterator<Item = String>,

Bulk-add ATTRIBUTED directed edges when the caller has already identified newly-created nodes. This keeps edge-map insertion in global input order, then stages successor and predecessor row commits by row so adjacency maps are probed once per touched row rather than once per edge.

Source

pub fn extend_existing_index_edges_with_attrs_unrecorded<I>( &mut self, edges: I, ) -> usize
where I: IntoIterator<Item = (usize, usize, AttrMap)>,

Bulk-add attributed directed edges into a fresh graph when the caller has already assigned NetworkX-compatible node indices in first-seen order.

This bypasses the string-key lookup path in [extend_prepared_edges_with_attrs_row_staged_unrecorded]: node labels are installed once, then edges are committed directly by (source_idx, target_idx). Duplicate directed edges merge attributes without appending another successor/predecessor entry, matching DiGraph.add_edges_from. br-r37-c1-dodattrbatch: bulk-add ATTRIBUTED directed edges by EXISTING node index. All endpoints MUST already exist (callers gate on int-labeled nodes). A new edge takes the AttrMap; a duplicate (source, target) MERGES last-wins like add_edge_with_attrs. Sibling of the fresh-index attr extend minus node creation; integer index rows only (no String hashing).

Source

pub fn extend_fresh_index_edges_with_attrs_unrecorded<I, N>( &mut self, nodes: N, edges: I, ) -> usize
where I: IntoIterator<Item = (usize, usize, AttrMap)>, N: IntoIterator<Item = String>,

Source

pub fn apply_edge_defaults(&mut self, defaults: &AttrMap) -> bool

Source

pub fn replace_edge_attrs( &mut self, source: &str, target: &str, attrs: AttrMap, ) -> bool

br-r37-c1-sjf4t: overwrite the attribute map for an existing edge.

Source

pub fn replace_node_attrs(&mut self, node: &str, attrs: AttrMap) -> bool

br-r37-c1-sjf4t: overwrite the attribute map for an existing node.

Source

pub fn remove_edge(&mut self, source: &str, target: &str) -> bool

Remove directed edge source→target. Returns true if it existed.

Source

pub fn remove_node(&mut self, node: &str) -> bool

Remove node and all incident edges (both incoming and outgoing).

Source

pub fn remove_nodes_from<'a, I>(&mut self, nodes: I) -> (usize, usize)
where I: IntoIterator<Item = &'a str>,

Source

pub fn is_compact(&self) -> bool

Nothing removed since the last compaction: every node’s slot is its position (O(1)).

Source

pub fn ensure_compact(&mut self)

Source

pub fn edges_ordered(&self) -> Vec<EdgeSnapshot>

Edges in deterministic order: iterate nodes in insertion order, then each node’s successors in insertion order.

Source

pub fn edges_ordered_indices_borrowed(&self) -> Vec<(usize, usize, &AttrMap)>

Source

pub fn edges_ordered_borrowed(&self) -> Vec<(&str, &str, &AttrMap)>

Source

pub fn weighted_size_int(&self, weight: &str) -> Option<i128>

br-r37-c1-wsize (cc): integer size(weight) from the store — directed twin of Graph::weighted_size_int. A directed edge (u,v,w) adds w to out_degree(u) and in_degree(v), so sum(degree)/2 halves back to each edge’s weight once; a self-loop adds w to both in and out of one node → 2w → halves to w, again one stored edge counted once. Returns None on any non-integer weight (caller uses the exact degree path); missing weight defaults to nx’s int 1.

Source

pub fn reversed(&self) -> Self

br-r37-c1-revborrow: O(V+E) directed transpose. The reverse of a DiGraph keeps the SAME node table (identical insertion order, identical indices), so reversing is a pure topology flip — no String hashing, no per-edge node-index lookups, no re-insertion through the name table (the edge-iterate + edges_ordered() clone + extend_edges_with_attrs_* re-hash path is O(E) String/hash work this avoids entirely).

Successor rows are rebuilt by walking the ORIGINAL successor rows in node-major (ascending source index) order and appending the reversed endpoint, so the reversed graph’s edges_ordered() stream is byte-identical to NetworkX’s reverse(), which walks self.edges() (u-major successor order) and adds each (v, u). pred_indices[u] ends up equal to the original succ_indices[u], matching NetworkX’s reversed pred order as well. Node + edge attribute maps are cloned verbatim.

Source

pub fn edges_ordered_indices(&self) -> Vec<(usize, usize)>

Directed edge endpoints in the same order as edges_ordered_borrowed.

Source

pub fn snapshot(&self) -> DiGraphSnapshot

Source

pub fn to_undirected(&self) -> Graph

Convert to an undirected Graph by dropping directionality. Both (u→v) and (v→u) merge into a single undirected edge. When both exist, the latter’s attributes overwrite the former’s.

Trait Implementations§

Source§

impl Clone for DiGraph

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 Debug for DiGraph

Source§

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

Formats the value using the given formatter. 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> 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, 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.