graph

package module
v0.12.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

graph

A Go library for creating and manipulating graph data structures.

Go Report Card Go Go Reference


Status

Build & Test

CI GitHub issues

Quality

Quality Gate Status CodeQL

Package and Deploy

Release


Features

This Go-based graph library is designed for versatility, performance, and extensibility, leveraging generics to handle various graph-related operations seamlessly. Key features include:

  • Generics-Based Design: Leverages Go generics for a flexible and type-safe graph interface supporting custom vertex and edge types.
  • Trait-Driven Configuration: Supports traits such as directed/undirected, weighted, acyclic, rooted, and multigraph properties.
  • Comprehensive Graph Operations: Provides efficient algorithms for CRUD operations, set operations, adjacency/predecessor maps, and graph cloning.
  • Traversal and Pathfinding: Implements breadth-first, depth-first, and shortest-path algorithms. Supports minimum and maximum spanning tree computation.
  • Graph Metrics: Offers centrality measures (degree, closeness, betweenness, eigenvector), clustering coefficients, density, diameter, and average path length.
  • Community and Ranking Analysis: Includes modularity and PageRank calculations for advanced graph analysis.
  • Cycle Management: Prevents cycles in acyclic graphs during edge additions.
  • Streaming Support: Enables paginated streaming of vertices and edges with context management for cancellation and resumption.
  • Customizable Input/Output: Supports flexible graph serialization and custom reader/writer implementations.
  • Concurrency Safe: Designed for thread-safe operations in multi-threaded environments.
  • Lightweight and Efficient: Optimized for high performance with minimal overhead.
  • Zero Dependencies: Lightweight implementation with no external dependencies beyond the standard library.
  • Supports io.Reader Interface:
    • Graph Serialization: Export and import graphs to/from various formats for interoperability.
    • Customizable Readers and Writers: Create tailored I/O operations for graph persistence.

Verify with Cosign

Cosign is used to sign releases for integrity verification.

To verify the integrity of the release tarball, you can use Cosign to check the signature and checksums. Follow these steps:

# Fetch the latest release tag from GitHub API (e.g., "v0.12.0")
TAG=$(curl -s https://api.github.com/repos/sixafter/graph/releases/latest | jq -r .tag_name)

# Remove leading "v" for filenames (e.g., "v0.12.0" -> "0.12.0")
VERSION=${TAG#v}

# ---------------------------------------------------------------------
# Verify the source archive using Sigstore bundles
# ---------------------------------------------------------------------

# Download the release tarball and its signature bundle
curl -LO "https://github.com/sixafter/graph/releases/download/${TAG}/graph-${VERSION}.tar.gz"
curl -LO "https://github.com/sixafter/graph/releases/download/${TAG}/graph-${VERSION}.tar.gz.sigstore.json"

# Verify the tarball with Cosign using the published public key
cosign verify-blob \
  --key "https://raw.githubusercontent.com/sixafter/graph/main/cosign.pub" \
  --bundle "graph-${VERSION}.tar.gz.sigstore.json" \
  "graph-${VERSION}.tar.gz"

# ---------------------------------------------------------------------
# Verify the checksums manifest using Sigstore bundles
# ---------------------------------------------------------------------

curl -LO "https://github.com/sixafter/graph/releases/download/${TAG}/checksums.txt"
curl -LO "https://github.com/sixafter/graph/releases/download/${TAG}/checksums.txt.sigstore.json"

cosign verify-blob \
  --key "https://raw.githubusercontent.com/sixafter/graph/main/cosign.pub" \
  --bundle "checksums.txt.sigstore.json" \
  "checksums.txt"

# ---------------------------------------------------------------------
# Confirm local artifact integrity
# ---------------------------------------------------------------------

shasum -a 256 -c checksums.txt

If valid, Cosign will output:

Verified OK

Verify Go module

To validate that the Go module archive served by GitHub, go mod download, and the Go proxy are all consistent, run the module-verify target. This performs a full cross-check of the tag archive and module ZIPs to confirm they match byte-for-byte.


Installation

Using go get

To install this package, run the following command:

go get -u github.com/sixafter/graph

To use the package in your Go project, import it as follows:

import "github.com/sixafter/graph"

Contributing

Contributions are welcome. See CONTRIBUTING


License

This project is licensed under the Apache 2.0 License. See LICENSE file.

Documentation

Overview

Package graph provides interfaces and types to model and manipulate graphs, including vertices, edges, and their associated properties.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAdjacencyMap is used as the base error when failing to retrieve the adjacency map.
	ErrAdjacencyMap = errors.New("failed to get adjacency map")

	// ErrVertexRetrieval is used as the base error when failing to retrieve a vertex.
	ErrVertexRetrieval = errors.New("failed to get vertex")

	// ErrAddVertex is used as the base error when failing to add a vertex.
	ErrAddVertex = errors.New("failed to add vertex")

	// ErrAddEdge is used as the base error when failing to add an edge.
	ErrAddEdge = errors.New("failed to add edge")

	// ErrCloneGraph is returned when cloning a graph fails.
	ErrCloneGraph = errors.New("failed to clone the graph")

	// ErrCyclicGraph indicates that the graph Contains cycles and the operation cannot proceed.
	ErrCyclicGraph = errors.New("operation cannot be performed on graph with cycles")

	// ErrEdgeAlreadyExists is returned when attempting to add an edge that already exists.
	ErrEdgeAlreadyExists = errors.New("edge already exists")

	// ErrEdgeCreatesCycle is returned when an edge would create a cycle in a graph
	// where cycles are not allowed.
	ErrEdgeCreatesCycle = errors.New("edge would create a cycle")

	// ErrEdgeNotFound is returned when an edge is not found in the graph.
	ErrEdgeNotFound = errors.New("edge not found")

	// ErrFailedToAddEdge is returned when adding an edge to the graph fails.
	ErrFailedToAddEdge = errors.New("failed to add edge")

	// ErrFailedToAddEdges is returned when edges cannot be added during a graph operation.
	ErrFailedToAddEdges = errors.New("failed to add edges")

	// ErrFailedToAddVertex is returned when adding a vertex to the graph fails.
	ErrFailedToAddVertex = errors.New("failed to add vertex")

	// ErrFailedToAddVertices is returned when vertices cannot be added during a graph operation.
	ErrFailedToAddVertices = errors.New("failed to add vertices")

	// ErrFailedToCloneGraph indicates a failure in cloning the graph.
	ErrFailedToCloneGraph = errors.New("failed to clone the graph")

	// ErrFailedToGetAdjacencyMap indicates a failure in retrieving the graph's adjacency map.
	ErrFailedToGetAdjacencyMap = errors.New("failed to get adjacency map")

	// ErrFailedToGetEdges is returned when the edge list of a graph cannot be retrieved.
	ErrFailedToGetEdges = errors.New("failed to get edges")

	// ErrFailedToGetGraphOrder indicates a failure in retrieving the graph's order.
	ErrFailedToGetGraphOrder = errors.New("failed to get graph order")

	// ErrFailedToGetPredecessorMap indicates a failure in retrieving the graph's predecessor map.
	ErrFailedToGetPredecessorMap = errors.New("failed to get predecessor map")

	// ErrFailedToGetVertex is returned when a vertex cannot be retrieved from the graph.
	ErrFailedToGetVertex = errors.New("failed to get vertex")

	// ErrFailedToListEdges is returned when the graph fails to list edges during an operation.
	ErrFailedToListEdges = errors.New("failed to list edges")

	// ErrFailedToListVertices is returned when the graph fails to list vertices during an operation.
	ErrFailedToListVertices = errors.New("failed to list vertices")

	// ErrFailedToRemoveEdge is returned when removing an edge from the graph fails.
	ErrFailedToRemoveEdge = errors.New("failed to remove edge")

	// ErrGetAdjacencyMap is returned when the adjacency map retrieval fails.
	ErrGetAdjacencyMap = errors.New("failed to get adjacency map")

	// ErrGetVertex is returned when a vertex cannot be retrieved.
	ErrGetVertex = errors.New("failed to get vertex")

	// ErrPredecessorMapFailed is returned when there is an error obtaining the predecessor
	// map of a graph. The predecessor map is used for operations like cycle detection.
	ErrPredecessorMapFailed = errors.New("could not get predecessor map")

	// ErrSameSourceAndTarget is returned when the source and target vertices of an operation
	// are the same. This is typically used in scenarios where cycles are being detected or avoided.
	ErrSameSourceAndTarget = errors.New("source and target vertices are the same")

	// ErrSCCDetectionNotDirected is returned when an attempt is made to detect strongly
	// connected components (SCCs) in a graph that is not a directed graph. SCC detection is only
	// valid for DirectedGraph graphs.
	ErrSCCDetectionNotDirected = errors.New("strongly connected components (SCCs) can only be detected in directed graph graphs")

	// ErrTargetNotReachable is returned when the target vertex is not reachable
	// from the source vertex in a graph operation such as ShortestPath.
	ErrTargetNotReachable = errors.New("target vertex not reachable from source")

	// ErrUndirectedGraph indicates that the operation cannot be performed on an Undirected graph.
	ErrUndirectedGraph = errors.New("operation cannot be performed on Undirected graph")

	// ErrVertexAlreadyExists is returned when attempting to add a vertex that already exists.
	ErrVertexAlreadyExists = errors.New("vertex already exists")

	// ErrVertexHasEdges is returned when trying to remove a vertex that still has edges.
	ErrVertexHasEdges = errors.New("vertex has edges")

	// ErrVertexNotFound is returned when a vertex is not found in the graph.
	ErrVertexNotFound = errors.New("vertex not found")

	// ErrGraphTypeMismatch is returned when attempting to perform set operations
	// on graphs with differing types or traits.
	ErrGraphTypeMismatch = errors.New("graph type mismatch")

	ErrNilInputGraph = errors.New("input graph cannot be nil")
)

Functions

func FNV1aHash128 added in v0.5.0

func FNV1aHash128(s string) [16]byte

FNV1aHash128 returns the 128-bit FNV-1a hash of the given string as a [16]byte array.

FNV-1a 128-bit is a fast, non-cryptographic hash with excellent distribution properties. The returned [16]byte value is suitable for use as a key in hash tables, graphs, or for deduplication.

This function uses Go's standard library hash/fnv package and panics if an unexpected error occurs.

Example:

key := graph.FNV1aHash128("vertex-id")

func FNV1aHash64 added in v0.5.0

func FNV1aHash64(s string) uint64

FNV1aHash64 returns the 64-bit FNV-1a hash of the given string.

FNV-1a is a fast, non-cryptographic hash function with good distribution properties, suitable for use in hash tables, graph vertex keys, and similar use cases. The returned hash value is always the same for the same input string.

This function uses the Go standard library's hash/fnv package, and panics if an unexpected error occurs during hashing (which should never happen in practice).

Example:

key := graph.FNV1aHash64("vertex-id")

func Float32Hash

func Float32Hash(v float32) float32

Float32Hash returns the given float as its hash.

This is a simple identity function that is useful when the float itself uniquely identifies the vertex in the graph.

Example:

g := simple.New(graph.Float32Hash, graph.Directed())
g.AddVertex(1.0)
g.AddVertex(2.0)
g.AddEdge(1.0, 2.0)

func Float64Hash

func Float64Hash(v float64) float64

Float64Hash returns the given float as its hash.

This is a simple identity function that is useful when the float itself uniquely identifies the vertex in the graph.

Example:

g := simple.New(graph.Float64Hash, graph.Directed())
g.AddVertex(1.0)
g.AddVertex(2.0)
g.AddEdge(1.0, 2.0)

func IntHash

func IntHash(v int) int

IntHash returns the given integer as its hash.

This is a simple identity function that is useful when the integer itself uniquely identifies the vertex in the graph.

Example:

g := simple.New(graph.IntHash, graph.Directed())
g.AddVertex(1)
g.AddVertex(2)
g.AddEdge(1, 2)

func Sha256Hash added in v0.5.0

func Sha256Hash(s string) [32]byte

Sha256Hash returns the 256-bit SHA-2 hash of the given string as a [32]byte array.

SHA-256 is a cryptographically secure hash function with excellent distribution properties. The returned [32]byte value is suitable for use as a cryptographic fingerprint, secure key, or unique identifier.

This function uses Go's standard library crypto/sha256 package.

Example:

key := graph.Sha256Hash("vertex-id")

func StringHash

func StringHash(v string) string

StringHash returns the given string as its hash.

This is a simple identity function that is useful when the string itself uniquely identifies the vertex in the graph.

Example:

g := simple.New(graph.StringHash, graph.Directed())
g.AddVertex("A")
g.AddVertex("B")
g.AddEdge("A", "B")

Types

type Cloneable

type Cloneable[T any] interface {
	// Clone creates a deep copy of the object.
	Clone() T
}

Cloneable represents a type that can produce a deep copy of itself.

Example:

original := obj
cloned := original.Clone()
if !reflect.DeepEqual(original, cloned) {
	log.Fatal("Clone is not identical to original")
}

type Comparable

type Comparable[T any] interface {
	CompareTo(other T) int
}

type Cursor

type Cursor interface {
	// State returns the current state of the cursor as a serialized byte slice.
	State() []byte

	// SetState restores the cursor state from a serialized byte slice.
	SetState(state []byte) error
}

Cursor is an interface representing a position in the graph stream. It allows for serialization and deserialization of the cursor state, enabling resumption of streams at a specific point.

Methods:

  • State: Returns the current state of the cursor as a serialized byte slice.
  • SetState: Restores the cursor state from a serialized byte slice.

Example:

cursor := &simple.EmptyCursor()
state := cursor.State()
fmt.Printf("Serialized Cursor State: %s\n", state)

err := cursor.SetState(state)
if err != nil {
    log.Fatalf("Failed to restore cursor state: %v", err)
}
fmt.Printf("Cursor State Restored")

type Edge

type Edge[T any] interface {
	Cloneable[Edge[T]]

	// Source is the starting vertex of the edge.
	Source() T

	// Target is the ending vertex of the edge.
	Target() T

	// Properties contains additional information or metadata about the edge,
	// such as weight, capacity, or any custom values.
	Properties() EdgeProperties
}

Edge represents a connection between two vertices in a graph.

Example:

edge := graph.NewEdge("A", "B", graph.EdgeWeight(10))
fmt.Printf("Edge from %v to %v\n", edge.Source(), edge.Target())

type EdgeOption

type EdgeOption func(EdgeProperties)

EdgeOption defines a functional option for configuring edge properties.

Example:

edge := graph.NewEdge("A", "B", graph.EdgeWeight(15), graph.EdgeItem("color", "red"))

type EdgeProperties

type EdgeProperties interface {
	Cloneable[EdgeProperties]

	// Items retrieves key-value pairs associated with the edge.
	Items() map[string]any

	// Metadata returns custom user-defined information for the edge.
	Metadata() any

	// Weight specifies the weight of the edge. Default is 0 if not explicitly set.
	Weight() float64
}

EdgeProperties defines properties associated with a graph edge.

Example:

edgeProps := edge.Properties()
weight := edgeProps.Weight()
customValue := edgeProps.Items()["custom"]
fmt.Printf("Weight: %v, Custom Value: %v\n", weight, customValue)

type Hash

type Hash[K Ordered, T any] func(T) K

Hash is a function type that maps a vertex of type T to a hash of type K.

type Interface

type Interface[K Ordered, T any] interface {
	// AddVertex creates a new Vertex in the graph. If the Vertex already exists,
	// it returns ErrVertexAlreadyExists. Functional options can be used to set
	// Vertex properties such as weight or v.
	//
	// Example:
	//  hash := graph.StringHash("A")
	//  vertex := graph.NewVertexWithOptions(hash, "A", graph.VertexWeight(4), graph.VertexItem("label", "Node A"))
	//	err := graph.AddVertex(vertex)
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddVertex(value Vertex[K, T]) error

	// AddVertexWithOptions creates a new Vertex in the graph. If the Vertex already exists,
	// it returns ErrVertexAlreadyExists. Functional options can be used to set
	// Vertex properties such as weight or v.
	//
	// Example:
	//	err := graph.AddVertexWithOptions("A", graph.VertexWeight(4), graph.VertexItem("label", "Node A"))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddVertexWithOptions(value T, options ...VertexOption) error

	// AddVerticesFrom imports all vertices along with their properties from the
	// given graph into the current graph. Stops and returns an error if any Vertex
	// already exists.
	//
	// Example:
	//	err := graph.AddVerticesFrom(otherGraph)
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddVerticesFrom(g Interface[K, T]) error

	// Vertex retrieves the Vertex with the given hash value. Returns
	// ErrVertexNotFound if the Vertex does not exist.
	//
	// Example:
	//	vertex, err := graph.Vertex("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Println(vertex)
	Vertex(hash K) (Vertex[K, T], error)

	// SetVertexWithOptions updates the properties of an existing vertex using functional
	// options. Returns ErrVertexNotFound if the vertex does not exist.
	//
	// Example:
	//	err := graph.SetVertexWithOptions("A", "B", graph.VertexWeight(20))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	SetVertexWithOptions(value T, options ...VertexOption) error

	// RemoveVertex removes the Vertex identified by the given hash from the graph.
	// Returns ErrVertexHasEdges if the Vertex still has edges, or ErrVertexNotFound
	// if the Vertex does not exist.
	//
	// Example:
	//	err := graph.RemoveVertex("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	RemoveVertex(hash K) error

	// Vertices returns a slice containing all Vertex values in the graph.
	//
	// Example:
	//	vertices, err := graph.Vertices()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	for _, vertex := range vertices {
	//		fmt.Println(vertex)
	//	}
	Vertices() ([]Vertex[K, T], error)

	// StreamVerticesWithContext streams vertices from the graph in paginated batches. The stream can be canceled
	// or timed out using a context, and the state of the cursor can be used to resume from the last point.
	//
	// Parameters:
	//   - ctx: The context to manage cancellation or timeout of the stream.
	//   - cursor: A Cursor object to track and manage the streaming state.
	//   - limit: The maximum number of vertices to include in each batch.
	//   - ch: The channel to which vertices will be sent.
	//
	// Returns:
	//   - An updated Cursor reflecting the new position in the stream.
	//   - An error if the operation is canceled or encounters an issue.
	//
	// Example:
	//   cursor := simple.EmptyCursor()
	//   ch := make(chan []Vertex[int, string])
	//   go func() {
	//       cursor, err := g.StreamVerticesWithContext(ctx, cursor, 10, ch)
	//       if err != nil {
	//           log.Printf("Stream failed: %v", err)
	//       }
	//   }()
	//   for batch := range ch {
	//       for _, vertex := range batch {
	//           fmt.Printf("Vertex: %v\n", vertex)
	//       }
	//   }
	StreamVerticesWithContext(ctx context.Context, cursor Cursor, limit int, ch chan<- []Vertex[K, T]) (Cursor, error)

	// HasVertex checks if a Vertex with the specified identifier exists in the graph.
	//
	// Parameters:
	//   - hash: The identifier of the Vertex to check. Its type (K) must be comparable.
	//
	// Returns:
	//   - bool: A boolean value indicating whether the Vertex exists in the graph (true if it exists, false otherwise).
	//   - error: An error if the operation fails (e.g., due to an underlying storage or implementation issue).
	//
	// Example:
	//   exists, err := graph.HasVertex("vertex1")
	//   if err != nil {
	//       log.Fatalf("Error checking Vertex: %v", err)
	//   }
	//   if exists {
	//       fmt.Println("Vertex exists in the graph.")
	//   } else {
	//       fmt.Println("Vertex does not exist in the graph.")
	//   }
	HasVertex(hash K) (bool, error)

	// AddEdge creates an edge between the source and target vertices. Returns
	// ErrVertexNotFound if either Vertex is missing, ErrEdgeAlreadyExists if the
	// edge already exists, or ErrEdgeCreatesCycle if adding the edge creates a
	// cycle in a cycle-preventing graph. Functional options can be used to set
	// edge properties such as weight or v.
	//
	// Example:
	//	edge := simple.NewEdgeWithOptions("A", "B", graph.EdgeWeight(10), graph.EdgeItem("color", "blue"))
	//	err := graph.AddEdge(edge)
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddEdge(edge Edge[K]) error

	// AddEdgeWithOptions creates an edge between the source and target vertices. Returns
	// ErrVertexNotFound if either Vertex is missing, ErrEdgeAlreadyExists if the
	// edge already exists, or ErrEdgeCreatesCycle if adding the edge creates a
	// cycle in a cycle-preventing graph. Functional options can be used to set
	// edge properties such as weight or v.
	//
	// Example:
	//	err := graph.AddEdgeWithOptions("A", "B", graph.EdgeWeight(10), graph.EdgeItem("color", "blue"))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddEdgeWithOptions(source, target K, options ...EdgeOption) error

	// AddEdgesFrom imports all edges from another graph into the current graph.
	// The vertices that the edges connect must already exist in the current graph.
	//
	// Example:
	//	err := graph.AddEdgesFrom(otherGraph)
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	AddEdgesFrom(g Interface[K, T]) error

	// Edge retrieves the edge between two vertices. For Undirected graphs, the
	// order of the source and target vertices does not matter. Returns ErrEdgeNotFound
	// if the edge does not exist.
	//
	// Example:
	//	edge, err := graph.Edge("A", "B")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Println(edge)
	Edge(source, target K) (Edge[T], error)

	// Edges returns a slice of all edges in the graph. Each edge Contains the
	// source and target Vertex hashes, along with edge properties.
	//
	// Example:
	//	edges, err := graph.Edges()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	for _, edge := range edges {
	//		fmt.Printf("Edge: %+v\n", edge)
	//	}
	Edges() ([]Edge[K], error)

	// StreamEdgesWithContext streams edges from the graph in paginated batches. The stream can be canceled
	// or timed out using a context, and the state of the cursor can be used to resume from the last point.
	//
	// Parameters:
	//   - ctx: The context to manage cancellation or timeout of the stream.
	//   - cursor: A Cursor object to track and manage the streaming state.
	//   - limit: The maximum number of edges to include in each batch.
	//   - ch: The channel to which edges will be sent.
	//
	// Returns:
	//   - An updated Cursor reflecting the new position in the stream.
	//   - An error if the operation is canceled or encounters an issue.
	//
	// Example:
	//   cursor := simple.EmptyCursor()
	//   ch := make(chan Edge[int])
	//   go func() {
	//       cursor, err := g.StreamEdgesWithContext(ctx, cursor, 10, ch)
	//       if err != nil {
	//           log.Printf("Stream failed: %v", err)
	//       }
	//   }()
	//   for edge := range ch {
	//       fmt.Printf("Edge: %v\n", edge)
	//   }
	StreamEdgesWithContext(ctx context.Context, cursor Cursor, limit int, ch chan<- Edge[K]) (Cursor, error)

	// SetEdgeWithOptions updates the properties of an existing edge using functional
	// options. Returns ErrEdgeNotFound if the edge does not exist.
	//
	// Example:
	//	err := graph.SetEdgeWithOptions("A", "B", graph.EdgeWeight(20))
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	SetEdgeWithOptions(source, target K, options ...EdgeOption) error

	// RemoveEdge removes the edge between the given source and target vertices.
	// Returns ErrEdgeNotFound if the edge does not exist.
	//
	// Example:
	//	err := graph.RemoveEdge("A", "B")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	RemoveEdge(source, target K) error

	// HasEdge checks if an edge exists between the source and target vertices.
	// Returns true if the edge exists, false otherwise.
	//
	// Example:
	//	exists, err := graph.HasEdge("A", "B")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Edge exists: %v\n", exists)
	HasEdge(source, target K) (bool, error)

	// AdjacencyMap generates and returns an adjacency map representing all
	// outgoing edges for each Vertex in the graph.
	//
	// Example:
	//	adjMap, err := graph.AdjacencyMap()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Adjacency Map: %+v\n", adjMap)
	AdjacencyMap() (map[K]map[K]Edge[K], error)

	// PredecessorMap generates and returns a map representing all incoming
	// edges for each Vertex in the graph.
	//
	// Example:
	//	predMap, err := graph.PredecessorMap()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Predecessor Map: %+v\n", predMap)
	PredecessorMap() (map[K]map[K]Edge[K], error)

	// Clone creates a deep copy of the graph and returns the new instance.
	//
	// Example:
	//	clonedGraph, err := graph.Clone()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	Clone() (Interface[K, T], error)

	// Order returns the number of vertices in the graph.
	//
	// Example:
	//	order, err := graph.Order()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Interface order: %d\n", order)
	Order() (int, error)

	// Size returns the number of edges in the graph.
	//
	// Example:
	//	size, err := graph.Len()
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Interface size: %d\n", size)
	Size() (int, error)

	// Hash retrieves the hash function used by the graph. The hash function maps a Vertex
	// of type T to a hash of type K, which is used internally to identify vertices.
	//
	// This allows clients to understand or reuse the hashing logic for operations
	// that involve Vertex identification, such as comparing vertices or exporting
	// the graph structure.
	//
	// Returns:
	//   - A Hash[K, T] function that maps vertices to their unique hash values.
	//
	// Example:
	//   hashFunc := graph.Hash()
	//   vertex := "A"
	//   vertexHash := hashFunc(Vertex)
	//   fmt.Printf("Hash for Vertex %v: %v\n", vertex, vertexHash)
	Hash() Hash[K, T]

	// Traits returns the graph's traits, such as whether it is directed, weighted,
	// or acyclic. These traits must be set when creating a graph using the New function.
	//
	// Example:
	//	traits := graph.Traits()
	//	fmt.Printf("Directed: %v, Weighted: %v, Acyclic: %v\n", traits.Directed, traits.Weighted, traits.Acyclic)
	Traits() *Traits

	// Neighbors retrieves the vertices adjacent to the specified vertex in the graph.
	//
	// For directed graphs, it returns the outgoing neighbors of the vertex.
	// For undirected graphs, it returns all vertices connected to the specified vertex.
	//
	// Parameters:
	//   - hash: The identifier of the vertex whose neighbors are to be retrieved.
	//
	// Returns:
	//   - A slice of Vertex[K, T] values that are adjacent to the specified vertex.
	//   - An error if the vertex does not exist in the graph.
	//
	// Notes:
	//   - If the vertex exists but has no neighbors (e.g., an isolated vertex), the returned slice will be empty.
	//   - For undirected graphs, both vertices connected by an edge are considered neighbors of each other.
	//
	// Example:
	//	neighbors, err := graph.Neighbors("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	for _, neighbor := range neighbors {
	//		fmt.Printf("Neighbor ID: %v, Value: %v\n", neighbor.ID, neighbor.Value)
	//	}
	Neighbors(hash K) ([]Vertex[K, T], error)

	// Degree returns the total degree of the specified Vertex.
	//
	// For Undirected graphs, this is the number of adjacent vertices.
	// For directed graphs, this is the sum of in-degree and out-degree.
	//
	// Parameters:
	//   - hash: The identifier of the Vertex.
	//
	// Returns:
	//   - An integer representing the degree of the Vertex.
	//   - An error if the Vertex does not exist or the operation fails.
	//
	// Example:
	//	degree, err := graph.Degree("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Degree of A: %d\n", degree)
	Degree(hash K) (int, error)

	// InDegree returns the number of incoming edges to the specified Vertex.
	//
	// Applicable only for directed graphs. For Undirected graphs, this is
	// the number of adjacent vertices and thus identical in value to Degree.
	//
	// Parameters:
	//   - hash: The identifier of the Vertex.
	//
	// Returns:
	//   - An integer representing the in-degree of the Vertex.
	//   - An error if the Vertex does not exist, the graph is Undirected, or the operation fails.
	//
	// Example:
	//	inDegree, err := graph.InDegree("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("In-Degree of A: %d\n", inDegree)
	InDegree(hash K) (int, error)

	// OutDegree returns the number of outgoing edges from the specified Vertex.
	//
	// Applicable only for directed graphs. For Undirected graphs, this is
	// the number of adjacent vertices and thus identical in value to Degree.
	//
	// Parameters:
	//   - hash: The identifier of the Vertex.
	//
	// Returns:
	//   - An integer representing the out-degree of the Vertex.
	//   - An error if the Vertex does not exist, the graph is Undirected, or the operation fails.
	//
	// Example:
	//	outDegree, err := graph.OutDegree("A")
	//	if err != nil {
	//		log.Fatal(err)
	//	}
	//	fmt.Printf("Out-Degree of A: %d\n", outDegree)
	OutDegree(hash K) (int, error)
}

Interface represents a generic graph metadata structure consisting of vertices of type T identified by a hash of type K. It provides methods for managing vertices, edges, and graph properties.

type Ordered

type Ordered interface {
	comparable // Ensures equality (`==`, `!=`) is supported.
	constraints.Ordered
}

type Traits

type Traits struct {
	// IsAcyclic indicates whether the graph is acyclic. An acyclic graph does not
	// contain cycles (closed paths).
	IsAcyclic bool

	// IsDirected indicates whether the graph is DirectedGraph. In a DirectedGraph graph,
	// edges have a specific direction from a source to a target.
	IsDirected bool

	// IsMultiGraph indicates whether the graph is a multigraph. A multigraph is a
	// graph that allows multiple edges between the same pair of vertices.
	IsMultiGraph bool

	// IsRooted indicates whether the graph is rooted. A rooted graph is a graph
	// with a designated root node, common in tree structures.
	IsRooted bool

	// IsWeighted indicates whether the graph is weighted. Weighted graphs have
	// edges with associated weights.
	IsWeighted bool

	// PreventCycles indicates whether the graph proactively prevents the creation
	// of cycles. This adds checks during edge creation to ensure cycles are not
	// introduced.
	PreventCycles bool
}

Traits represents a set of graph traits and types, such as whether the graph is directed or acyclic. These traits determine the behavior and properties of the graph. They can be set during graph creation using functional options.

Example:

// Create a directed graph.
g := simple.New(graph.IntHash, graph.Directed())

func (*Traits) Clone

func (t *Traits) Clone() *Traits

Clone creates a deep copy of the provided Traits.

func (*Traits) Equals

func (t *Traits) Equals(other *Traits) bool

Equals returns true if the provided Traits are equal to the current Traits.

type TraitsOption

type TraitsOption func(*Traits)

func Acyclic

func Acyclic() TraitsOption

Acyclic creates an acyclic graph. An acyclic graph does not contain cycles. Note: This does not prevent cycles from being created explicitly. Use PreventCycles to ensure cycles are avoided during edge creation.

Example:

g := simple.New(graph.IntHash, graph.Acyclic())

func Directed

func Directed() TraitsOption

Directed creates a DirectedGraph graph. In a DirectedGraph graph, edges have a specific direction from a source to a target. This functional option sets the IsDirected field in Traits.

Example:

g := simple.New(graph.IntHash, graph.Directed())

func MultiGraph

func MultiGraph() TraitsOption

MultiGraph creates a multigraph. A multigraph is a graph that allows multiple edges between the same pair of vertices. This functional option sets the IsMultiGraph field in Traits.

Example:

g := simple.New(graph.IntHash, graph.MultiGraph())

func PreventCycles

func PreventCycles() TraitsOption

PreventCycles creates an acyclic graph that explicitly prevents the creation of cycles. This functional option adds checks during edge creation to proactively avoid cycles. Using PreventCycles can affect performance during operations like AddEdge.

Example:

g := simple.New(graph.IntHash, graph.PreventCycles())

func Rooted

func Rooted() TraitsOption

Rooted creates a rooted graph. Rooted graphs have a designated root DefaultVertex, commonly used in tree metadata structures.

Example:

g := simple.New(graph.IntHash, graph.Rooted())

func Tree

func Tree() TraitsOption

Tree is a shorthand for creating a rooted, acyclic graph. It combines the Rooted and Acyclic functional options. Trees are commonly used in metadata structures like binary trees or general trees.

Example:

g := simple.New(graph.IntHash, graph.Tree())

func Weighted

func Weighted() TraitsOption

Weighted creates a weighted graph. Weighted graphs have edges with associated weights, which can be set using the Edge or AddEdge methods.

Example:

g := simple.New(graph.IntHash, graph.Weighted())

type Vertex

type Vertex[K comparable, T any] interface {
	Cloneable[Vertex[K, T]]

	// ID returns the unique identifier of the vertex.
	ID() K

	// Value retrieves the value associated with the vertex.
	Value() T

	// Properties returns the properties associated with the vertex, such as
	// its attributes and weight.
	Properties() VertexProperties
}

Vertex represents a graph vertex with an identifier, metadata, and properties.

Example:

vertex := graph.NewVertex("A", graph.VertexWeight(10))
fmt.Printf("Vertex ID: %v, Weight: %v\n", vertex.ID(), vertex.Properties().Weight())

type VertexOption

type VertexOption func(VertexProperties)

VertexOption defines a functional option for configuring vertex properties.

Example:

vertex := graph.NewVertex("A", graph.VertexWeight(20), graph.VertexItem("type", "root"))

type VertexProperties

type VertexProperties interface {
	// Items retrieves key-value pairs associated with the vertex.
	Items() map[string]any

	// Weight specifies the weight of the vertex. Default is 0 if not explicitly set.
	Weight() float64

	// Metadata returns custom user-defined information for the vertex.
	Metadata() any
}

VertexProperties defines properties associated with a graph vertex.

Example:

vertexProps := vertex.Properties()
weight := vertexProps.Weight()
metadata := vertexProps.Metadata()
fmt.Printf("Weight: %v, Metadata: %v\n", weight, metadata)

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL