From 13ad2422a2b1413e50e5beac75f27e22ec554f17 Mon Sep 17 00:00:00 2001 From: elecbug Date: Thu, 16 Oct 2025 21:50:06 +0900 Subject: [PATCH] refactor: package name --- README.md | 1 - .../algorithm/algorithm.go | 0 .../algorithm/betweenness_centrality.go | 7 +- {network-graph => graph}/algorithm/cache.go | 2 +- .../algorithm/closeness_centrality.go | 7 +- .../algorithm/clustering_coefficient.go | 7 +- .../config => graph/algorithm}/config.go | 2 +- .../degree_assortativity_coefficient.go | 25 ++-- .../algorithm/degree_centrality.go | 9 +- .../algorithm/diameter.go | 5 +- .../algorithm/edge_betweenness_centrality.go | 7 +- .../algorithm/eigenvector_centrality.go | 7 +- .../algorithm/modularity.go | 7 +- .../algorithm/page_rank.go | 7 +- .../algorithm/shortest_path.go | 11 +- .../config => graph/algorithm}/subconfig.go | 4 +- {network-graph/graph => graph}/edge.go | 2 +- {network-graph/graph => graph}/graph.go | 2 +- {network-graph => graph}/graph_test.go | 17 +-- {network-graph/graph => graph}/node.go | 2 +- {network-graph => graph}/node/node.go | 0 {network-graph => graph}/path/path.go | 2 +- .../standard_graph/barabasi_albert.go | 4 +- .../standard_graph/erdos_reyni.go | 4 +- .../standard_graph/random_geometric.go | 4 +- .../standard_graph/random_regular.go | 4 +- .../graph => graph}/standard_graph/seed.go | 0 .../standard_graph/standard_graph.go | 0 .../standard_graph/watts_strogatz.go | 4 +- .../graph => graph}/standard_graph/waxman.go | 4 +- p2p/network.go | 4 +- p2p/p2p_test.go | 2 +- slice/bsearch.go | 39 ----- slice/bsearch_test.go | 79 ---------- slice/sort.go | 137 ------------------ slice/sort_test.go | 53 ------- 36 files changed, 75 insertions(+), 396 deletions(-) rename {network-graph => graph}/algorithm/algorithm.go (100%) rename {network-graph => graph}/algorithm/betweenness_centrality.go (93%) rename {network-graph => graph}/algorithm/cache.go (90%) rename {network-graph => graph}/algorithm/closeness_centrality.go (91%) rename {network-graph => graph}/algorithm/clustering_coefficient.go (94%) rename {network-graph/algorithm/config => graph/algorithm}/config.go (98%) rename {network-graph => graph}/algorithm/degree_assortativity_coefficient.go (86%) rename {network-graph => graph}/algorithm/degree_centrality.go (92%) rename {network-graph => graph}/algorithm/diameter.go (67%) rename {network-graph => graph}/algorithm/edge_betweenness_centrality.go (94%) rename {network-graph => graph}/algorithm/eigenvector_centrality.go (95%) rename {network-graph => graph}/algorithm/modularity.go (97%) rename {network-graph => graph}/algorithm/page_rank.go (96%) rename {network-graph => graph}/algorithm/shortest_path.go (95%) rename {network-graph/algorithm/config => graph/algorithm}/subconfig.go (97%) rename {network-graph/graph => graph}/edge.go (97%) rename {network-graph/graph => graph}/graph.go (98%) rename {network-graph => graph}/graph_test.go (91%) rename {network-graph/graph => graph}/node.go (96%) rename {network-graph => graph}/node/node.go (100%) rename {network-graph => graph}/path/path.go (97%) rename {network-graph/graph => graph}/standard_graph/barabasi_albert.go (92%) rename {network-graph/graph => graph}/standard_graph/erdos_reyni.go (87%) rename {network-graph/graph => graph}/standard_graph/random_geometric.go (90%) rename {network-graph/graph => graph}/standard_graph/random_regular.go (94%) rename {network-graph/graph => graph}/standard_graph/seed.go (100%) rename {network-graph/graph => graph}/standard_graph/standard_graph.go (100%) rename {network-graph/graph => graph}/standard_graph/watts_strogatz.go (93%) rename {network-graph/graph => graph}/standard_graph/waxman.go (92%) delete mode 100644 slice/bsearch.go delete mode 100644 slice/bsearch_test.go delete mode 100644 slice/sort.go delete mode 100644 slice/sort_test.go diff --git a/README.md b/README.md index 1784e7d..a1a7965 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ go get github.com/elecbug/netkit@latest ### Extensible - [`bimap`](./bimap/): Bidirectional map with O(1) lookups key->value and value->key. -- [`slice`](./slice/): Generic helpers: binary search, stable merge sort, parallel sort, and `IsSorted`. ## Development diff --git a/network-graph/algorithm/algorithm.go b/graph/algorithm/algorithm.go similarity index 100% rename from network-graph/algorithm/algorithm.go rename to graph/algorithm/algorithm.go diff --git a/network-graph/algorithm/betweenness_centrality.go b/graph/algorithm/betweenness_centrality.go similarity index 93% rename from network-graph/algorithm/betweenness_centrality.go rename to graph/algorithm/betweenness_centrality.go index 2aba5e7..b81d480 100644 --- a/network-graph/algorithm/betweenness_centrality.go +++ b/graph/algorithm/betweenness_centrality.go @@ -4,9 +4,8 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // BetweennessCentrality computes betweenness centrality using cached all shortest paths. @@ -14,7 +13,7 @@ import ( // - For each pair (s,t), each interior node on a shortest path gets 1/|SP(s,t)| credit. // - Undirected graphs enqueue only i 2/((n-1)(n-2)), directed => 1/((n-1)(n-2)). -func BetweennessCentrality(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func BetweennessCentrality(g *graph.Graph, cfg *Config) map[node.ID]float64 { res := make(map[node.ID]float64) if g == nil { return res diff --git a/network-graph/algorithm/cache.go b/graph/algorithm/cache.go similarity index 90% rename from network-graph/algorithm/cache.go rename to graph/algorithm/cache.go index 1771dc3..ab6ff65 100644 --- a/network-graph/algorithm/cache.go +++ b/graph/algorithm/cache.go @@ -3,7 +3,7 @@ package algorithm import ( "sync" - "github.com/elecbug/netkit/network-graph/path" + "github.com/elecbug/netkit/graph/path" ) var cachedAllShortestPaths = make(map[string]path.GraphPaths) diff --git a/network-graph/algorithm/closeness_centrality.go b/graph/algorithm/closeness_centrality.go similarity index 91% rename from network-graph/algorithm/closeness_centrality.go rename to graph/algorithm/closeness_centrality.go index f7ce1c3..b73947b 100644 --- a/network-graph/algorithm/closeness_centrality.go +++ b/graph/algorithm/closeness_centrality.go @@ -1,9 +1,8 @@ package algorithm import ( - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // ClosenessCentrality computes NetworkX-compatible closeness centrality. @@ -18,7 +17,7 @@ import ( // Requirements: // - AllShortestPaths(g, cfg) must respect directedness of g. // - cfg.Closeness.WfImproved follows NetworkX default (true) unless overridden. -func ClosenessCentrality(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func ClosenessCentrality(g *graph.Graph, cfg *Config) map[node.ID]float64 { out := make(map[node.ID]float64) if g == nil { return out diff --git a/network-graph/algorithm/clustering_coefficient.go b/graph/algorithm/clustering_coefficient.go similarity index 94% rename from network-graph/algorithm/clustering_coefficient.go rename to graph/algorithm/clustering_coefficient.go index 2747d2b..bc26048 100644 --- a/network-graph/algorithm/clustering_coefficient.go +++ b/graph/algorithm/clustering_coefficient.go @@ -4,16 +4,15 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // ClusteringCoefficientAll computes local clustering coefficients for all nodes. // - If g.IsBidirectional()==false (directed): Fagiolo (2007) directed clustering (matches NetworkX). // - If g.IsBidirectional()==true (undirected): standard undirected clustering. // Returns map[node.ID]float64 with a value for every node in g. -func ClusteringCoefficient(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func ClusteringCoefficient(g *graph.Graph, cfg *Config) map[node.ID]float64 { res := make(map[node.ID]float64) if g == nil { return res diff --git a/network-graph/algorithm/config/config.go b/graph/algorithm/config.go similarity index 98% rename from network-graph/algorithm/config/config.go rename to graph/algorithm/config.go index aff128e..8713e06 100644 --- a/network-graph/algorithm/config/config.go +++ b/graph/algorithm/config.go @@ -1,5 +1,5 @@ // Package config provides configuration settings for the graph algorithms. -package config +package algorithm import ( "runtime" diff --git a/network-graph/algorithm/degree_assortativity_coefficient.go b/graph/algorithm/degree_assortativity_coefficient.go similarity index 86% rename from network-graph/algorithm/degree_assortativity_coefficient.go rename to graph/algorithm/degree_assortativity_coefficient.go index 5de4a6a..396ff93 100644 --- a/network-graph/algorithm/degree_assortativity_coefficient.go +++ b/graph/algorithm/degree_assortativity_coefficient.go @@ -5,9 +5,8 @@ package algorithm import ( "math" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // DegreeAssortativityCoefficient computes Newman's degree assortativity coefficient (Pearson correlation) @@ -24,7 +23,7 @@ import ( // // - Self-loops are ignored by default (configurable). // - Replace neighbor getters with your Graph's actual API if different. -func DegreeAssortativityCoefficient(g *graph.Graph, cfg *config.Config) float64 { +func DegreeAssortativityCoefficient(g *graph.Graph, cfg *Config) float64 { if g == nil { return 0.0 } @@ -35,8 +34,8 @@ func DegreeAssortativityCoefficient(g *graph.Graph, cfg *config.Config) float64 } // Resolve config with sane defaults. - assCfg := &config.AssortativityCoefficientConfig{ - Mode: config.AssortativityProjected, + assCfg := &AssortativityCoefficientConfig{ + Mode: AssortativityProjected, IgnoreSelfLoops: true, } if cfg != nil && cfg.Assortativity != nil { @@ -50,8 +49,8 @@ func DegreeAssortativityCoefficient(g *graph.Graph, cfg *config.Config) float64 isUndirected := g.IsBidirectional() // Default directed mode: "out-in" is common in literature. - if !isUndirected && assCfg.Mode == config.AssortativityProjected { - assCfg.Mode = config.AssortativityOutIn + if !isUndirected && assCfg.Mode == AssortativityProjected { + assCfg.Mode = AssortativityOutIn } // Build an index for upper-triangle filtering on undirected graphs. @@ -119,19 +118,19 @@ func DegreeAssortativityCoefficient(g *graph.Graph, cfg *config.Config) float64 jv = float64(undeg[v]) } else { switch assCfg.Mode { - case config.AssortativityOutIn: + case AssortativityOutIn: ju = float64(outDeg[u]) jv = float64(inDeg[v]) - case config.AssortativityOutOut: + case AssortativityOutOut: ju = float64(outDeg[u]) jv = float64(outDeg[v]) - case config.AssortativityInIn: + case AssortativityInIn: ju = float64(inDeg[u]) jv = float64(inDeg[v]) - case config.AssortativityInOut: + case AssortativityInOut: ju = float64(inDeg[u]) jv = float64(outDeg[v]) - case config.AssortativityProjected: + case AssortativityProjected: // Directed but projected (if user explicitly requests) ju = float64(undeg[u]) jv = float64(undeg[v]) diff --git a/network-graph/algorithm/degree_centrality.go b/graph/algorithm/degree_centrality.go similarity index 92% rename from network-graph/algorithm/degree_centrality.go rename to graph/algorithm/degree_centrality.go index 28691e7..8526ab0 100644 --- a/network-graph/algorithm/degree_centrality.go +++ b/graph/algorithm/degree_centrality.go @@ -4,9 +4,8 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // DegreeCentralityConfig (suggested to be added inside your config package) @@ -22,7 +21,7 @@ import ( // Mode string // } // -// In config.Config: +// In Config: // type Config struct { // Workers int // Degree *DegreeCentralityConfig @@ -33,7 +32,7 @@ import ( // - Undirected: deg(u)/(n-1). // - Directed (default "total"): (in(u)+out(u))/(n-1). Use "in"/"out" for the specific variants. // Self-loops are ignored for centrality. -func DegreeCentrality(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func DegreeCentrality(g *graph.Graph, cfg *Config) map[node.ID]float64 { res := make(map[node.ID]float64) if g == nil { return res diff --git a/network-graph/algorithm/diameter.go b/graph/algorithm/diameter.go similarity index 67% rename from network-graph/algorithm/diameter.go rename to graph/algorithm/diameter.go index bbfbcbb..261ace6 100644 --- a/network-graph/algorithm/diameter.go +++ b/graph/algorithm/diameter.go @@ -1,12 +1,11 @@ package algorithm import ( - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" + "github.com/elecbug/netkit/graph" ) // Diameter computes the diameter of the graph using all-pairs shortest paths. -func Diameter(g *graph.Graph, cfg *config.Config) int { +func Diameter(g *graph.Graph, cfg *Config) int { result := 0 paths := AllShortestPaths(g, cfg) diff --git a/network-graph/algorithm/edge_betweenness_centrality.go b/graph/algorithm/edge_betweenness_centrality.go similarity index 94% rename from network-graph/algorithm/edge_betweenness_centrality.go rename to graph/algorithm/edge_betweenness_centrality.go index eb6d20d..1775b03 100644 --- a/network-graph/algorithm/edge_betweenness_centrality.go +++ b/graph/algorithm/edge_betweenness_centrality.go @@ -4,9 +4,8 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) func makeEdgeKey(u, v node.ID, undirected bool) (node.ID, node.ID) { @@ -38,7 +37,7 @@ func makeEdgeKey(u, v node.ID, undirected bool) (node.ID, node.ID) { // - map[node.ID]map[node.ID]float64 where: // - Undirected: key is canonical [min(u,v), max(u,v)] // - Directed: key is (u,v) ordered -func EdgeBetweennessCentrality(g *graph.Graph, cfg *config.Config) map[node.ID]map[node.ID]float64 { +func EdgeBetweennessCentrality(g *graph.Graph, cfg *Config) map[node.ID]map[node.ID]float64 { out := make(map[node.ID]map[node.ID]float64) if g == nil { return out diff --git a/network-graph/algorithm/eigenvector_centrality.go b/graph/algorithm/eigenvector_centrality.go similarity index 95% rename from network-graph/algorithm/eigenvector_centrality.go rename to graph/algorithm/eigenvector_centrality.go index f673bde..6639b01 100644 --- a/network-graph/algorithm/eigenvector_centrality.go +++ b/graph/algorithm/eigenvector_centrality.go @@ -5,9 +5,8 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // EigenvectorCentrality computes eigenvector centrality using parallel power iteration. @@ -17,7 +16,7 @@ import ( // Set Reverse=true to use successors/out-edges (right eigenvector). // // Unweighted edges are assumed. The result vector is L2-normalized (sum of squares == 1). -func EigenvectorCentrality(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func EigenvectorCentrality(g *graph.Graph, cfg *Config) map[node.ID]float64 { out := make(map[node.ID]float64) if g == nil { return out diff --git a/network-graph/algorithm/modularity.go b/graph/algorithm/modularity.go similarity index 97% rename from network-graph/algorithm/modularity.go rename to graph/algorithm/modularity.go index 7b65ee7..5927c10 100644 --- a/network-graph/algorithm/modularity.go +++ b/graph/algorithm/modularity.go @@ -6,15 +6,14 @@ import ( "container/heap" "math" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // Modularity computes Newman-Girvan modularity Q. // If cfg.Modularity.Partition == nil, it runs greedy CNM to obtain a partition first. // All computations are performed on an undirected projection (to match NetworkX). -func Modularity(g *graph.Graph, cfg *config.Config) float64 { +func Modularity(g *graph.Graph, cfg *Config) float64 { if g == nil || cfg == nil || cfg.Modularity == nil { return 0.0 } diff --git a/network-graph/algorithm/page_rank.go b/graph/algorithm/page_rank.go similarity index 96% rename from network-graph/algorithm/page_rank.go rename to graph/algorithm/page_rank.go index 09bbeba..bd9a65c 100644 --- a/network-graph/algorithm/page_rank.go +++ b/graph/algorithm/page_rank.go @@ -5,9 +5,8 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // PageRank computes PageRank using a parallel power-iteration that mirrors NetworkX semantics: @@ -17,7 +16,7 @@ import ( // - For directed graphs, Reverse=false is the standard PageRank (incoming influence). // Reverse=true flips direction (treat in-neighbors as outs). // - For undirected graphs, neighbors are used as outs (degree-based normalization). -func PageRank(g *graph.Graph, cfg *config.Config) map[node.ID]float64 { +func PageRank(g *graph.Graph, cfg *Config) map[node.ID]float64 { res := make(map[node.ID]float64) if g == nil { return res diff --git a/network-graph/algorithm/shortest_path.go b/graph/algorithm/shortest_path.go similarity index 95% rename from network-graph/algorithm/shortest_path.go rename to graph/algorithm/shortest_path.go index 65ad998..c3f61cc 100644 --- a/network-graph/algorithm/shortest_path.go +++ b/graph/algorithm/shortest_path.go @@ -4,10 +4,9 @@ import ( "runtime" "sync" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" - "github.com/elecbug/netkit/network-graph/path" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" + "github.com/elecbug/netkit/graph/path" ) // ShortestPaths finds all shortest paths between two nodes in a graph. @@ -59,7 +58,7 @@ func ShortestPaths(g *graph.Graph, start, end node.ID) []path.Path { // (matching prior behavior and saving work). If you need reversed node order per entry, that can be changed, // but be aware of the extra cost. // - Self paths [u][u] are set to a single self path. -func AllShortestPaths(g *graph.Graph, cfg *config.Config) path.GraphPaths { +func AllShortestPaths(g *graph.Graph, cfg *Config) path.GraphPaths { if g == nil { return path.GraphPaths{} } @@ -327,7 +326,7 @@ func allShortestPathsBFS(g *graph.Graph, start, end node.ID) []path.Path { // - For each source u, the inner map contains v -> dist(u,v) for all reachable v (including u with 0). // - Unreachable targets are omitted from the inner map. // - Uses a worker pool sized by cfg.Workers (or NumCPU when <=0). -func AllShortestPathLength(g *graph.Graph, cfg *config.Config) path.PathLength { +func AllShortestPathLength(g *graph.Graph, cfg *Config) path.PathLength { out := make(path.PathLength) if g == nil { return out diff --git a/network-graph/algorithm/config/subconfig.go b/graph/algorithm/subconfig.go similarity index 97% rename from network-graph/algorithm/config/subconfig.go rename to graph/algorithm/subconfig.go index 7d7a867..18472ff 100644 --- a/network-graph/algorithm/config/subconfig.go +++ b/graph/algorithm/subconfig.go @@ -1,6 +1,6 @@ -package config +package algorithm -import "github.com/elecbug/netkit/network-graph/node" +import "github.com/elecbug/netkit/graph/node" // ClosenessCentralityConfig holds the configuration settings for the closeness centrality algorithm. type ClosenessCentralityConfig struct { diff --git a/network-graph/graph/edge.go b/graph/edge.go similarity index 97% rename from network-graph/graph/edge.go rename to graph/edge.go index a05547a..319664c 100644 --- a/network-graph/graph/edge.go +++ b/graph/edge.go @@ -3,7 +3,7 @@ package graph import ( "fmt" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph/node" ) // AddEdge adds an edge from -> to. If bidirectional is true, adds the reverse edge as well. diff --git a/network-graph/graph/graph.go b/graph/graph.go similarity index 98% rename from network-graph/graph/graph.go rename to graph/graph.go index 19d3df5..1e57d89 100644 --- a/network-graph/graph/graph.go +++ b/graph/graph.go @@ -7,7 +7,7 @@ import ( "fmt" "strings" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph/node" ) // Graph maintains nodes and adjacency edges. diff --git a/network-graph/graph_test.go b/graph/graph_test.go similarity index 91% rename from network-graph/graph_test.go rename to graph/graph_test.go index ac3fde7..0d13e3a 100644 --- a/network-graph/graph_test.go +++ b/graph/graph_test.go @@ -1,4 +1,4 @@ -package network_graph_test +package graph_test import ( "encoding/json" @@ -9,11 +9,10 @@ import ( "reflect" "testing" - "github.com/elecbug/netkit/network-graph/algorithm" - "github.com/elecbug/netkit/network-graph/algorithm/config" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" - "github.com/elecbug/netkit/network-graph/path" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/algorithm" + "github.com/elecbug/netkit/graph/node" + "github.com/elecbug/netkit/graph/path" ) func TestSimple(t *testing.T) { @@ -76,12 +75,12 @@ func TestPathLengths(t *testing.T) { var want path.PathLength t.Run("WithPaths", func(t *testing.T) { - got = algorithm.AllShortestPaths(g, &config.Config{Workers: 4}) + got = algorithm.AllShortestPaths(g, &algorithm.Config{Workers: 4}) }) gotLengths := got.OnlyLength() t.Run("WithoutPaths", func(t *testing.T) { - want = algorithm.AllShortestPathLength(g, &config.Config{Workers: 4}) + want = algorithm.AllShortestPathLength(g, &algorithm.Config{Workers: 4}) }) if !reflect.DeepEqual(gotLengths, want) { @@ -163,7 +162,7 @@ func TestDirectionalGraph(t *testing.T) { func graphMetrics(t *testing.T, g *graph.Graph, text string) { results := make(map[string]interface{}) - cfg := config.Default() + cfg := algorithm.Default() t.Run("ShortestPaths", func(t *testing.T) { // results["shortest_path_length"] = algo.AllShortestPathLength(g, cfg) diff --git a/network-graph/graph/node.go b/graph/node.go similarity index 96% rename from network-graph/graph/node.go rename to graph/node.go index b38d783..12b20fd 100644 --- a/network-graph/graph/node.go +++ b/graph/node.go @@ -3,7 +3,7 @@ package graph import ( "fmt" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph/node" ) // AddNode adds a node to the graph. diff --git a/network-graph/node/node.go b/graph/node/node.go similarity index 100% rename from network-graph/node/node.go rename to graph/node/node.go diff --git a/network-graph/path/path.go b/graph/path/path.go similarity index 97% rename from network-graph/path/path.go rename to graph/path/path.go index 1182209..88b7ade 100644 --- a/network-graph/path/path.go +++ b/graph/path/path.go @@ -2,7 +2,7 @@ package path import ( - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph/node" ) // Path represents an ordered sequence of nodes with a hop distance. diff --git a/network-graph/graph/standard_graph/barabasi_albert.go b/graph/standard_graph/barabasi_albert.go similarity index 92% rename from network-graph/graph/standard_graph/barabasi_albert.go rename to graph/standard_graph/barabasi_albert.go index fa31330..1b41761 100644 --- a/network-graph/graph/standard_graph/barabasi_albert.go +++ b/graph/standard_graph/barabasi_albert.go @@ -1,8 +1,8 @@ package standard_graph import ( - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // BarabasiAlbertGraph generates a graph based on the Barabási–Albert preferential attachment model. diff --git a/network-graph/graph/standard_graph/erdos_reyni.go b/graph/standard_graph/erdos_reyni.go similarity index 87% rename from network-graph/graph/standard_graph/erdos_reyni.go rename to graph/standard_graph/erdos_reyni.go index a4db56e..555a278 100644 --- a/network-graph/graph/standard_graph/erdos_reyni.go +++ b/graph/standard_graph/erdos_reyni.go @@ -1,8 +1,8 @@ package standard_graph import ( - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // ErdosRenyiGraph generates a random graph based on the Erdős-Rényi model. diff --git a/network-graph/graph/standard_graph/random_geometric.go b/graph/standard_graph/random_geometric.go similarity index 90% rename from network-graph/graph/standard_graph/random_geometric.go rename to graph/standard_graph/random_geometric.go index b1f08fe..54f6532 100644 --- a/network-graph/graph/standard_graph/random_geometric.go +++ b/graph/standard_graph/random_geometric.go @@ -3,8 +3,8 @@ package standard_graph import ( "math" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // RandomGeometricGraph generates a random geometric graph (RGG). diff --git a/network-graph/graph/standard_graph/random_regular.go b/graph/standard_graph/random_regular.go similarity index 94% rename from network-graph/graph/standard_graph/random_regular.go rename to graph/standard_graph/random_regular.go index d6651a4..fad15c6 100644 --- a/network-graph/graph/standard_graph/random_regular.go +++ b/graph/standard_graph/random_regular.go @@ -1,8 +1,8 @@ package standard_graph import ( - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // RandomRegularGraph generates a random k-regular graph with n nodes. diff --git a/network-graph/graph/standard_graph/seed.go b/graph/standard_graph/seed.go similarity index 100% rename from network-graph/graph/standard_graph/seed.go rename to graph/standard_graph/seed.go diff --git a/network-graph/graph/standard_graph/standard_graph.go b/graph/standard_graph/standard_graph.go similarity index 100% rename from network-graph/graph/standard_graph/standard_graph.go rename to graph/standard_graph/standard_graph.go diff --git a/network-graph/graph/standard_graph/watts_strogatz.go b/graph/standard_graph/watts_strogatz.go similarity index 93% rename from network-graph/graph/standard_graph/watts_strogatz.go rename to graph/standard_graph/watts_strogatz.go index cacbcac..6fd736d 100644 --- a/network-graph/graph/standard_graph/watts_strogatz.go +++ b/graph/standard_graph/watts_strogatz.go @@ -1,8 +1,8 @@ package standard_graph import ( - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // WattsStrogatzGraph generates a Watts–Strogatz small-world graph. diff --git a/network-graph/graph/standard_graph/waxman.go b/graph/standard_graph/waxman.go similarity index 92% rename from network-graph/graph/standard_graph/waxman.go rename to graph/standard_graph/waxman.go index 2558024..e3194e5 100644 --- a/network-graph/graph/standard_graph/waxman.go +++ b/graph/standard_graph/waxman.go @@ -3,8 +3,8 @@ package standard_graph import ( "math" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" ) // WaxmanGraph generates a Waxman random graph. diff --git a/p2p/network.go b/p2p/network.go index df0149f..54b39ef 100644 --- a/p2p/network.go +++ b/p2p/network.go @@ -7,8 +7,8 @@ import ( "sync" "time" - "github.com/elecbug/netkit/network-graph/graph" - "github.com/elecbug/netkit/network-graph/node" + "github.com/elecbug/netkit/graph" + "github.com/elecbug/netkit/graph/node" "github.com/elecbug/netkit/p2p/broadcast" ) diff --git a/p2p/p2p_test.go b/p2p/p2p_test.go index 9806128..9defc33 100644 --- a/p2p/p2p_test.go +++ b/p2p/p2p_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/elecbug/netkit/network-graph/graph/standard_graph" + "github.com/elecbug/netkit/graph/standard_graph" "github.com/elecbug/netkit/p2p" "github.com/elecbug/netkit/p2p/broadcast" ) diff --git a/slice/bsearch.go b/slice/bsearch.go deleted file mode 100644 index d896e3f..0000000 --- a/slice/bsearch.go +++ /dev/null @@ -1,39 +0,0 @@ -// Package slice provides generic slice utilities such as binary search and sorting. -package slice - -// CompareType indicates the relation of the probed element to the target. -type CompareType int - -const ( - // TARGET_SMALL indicates the target is larger than the probed element; search right. - TARGET_SMALL CompareType = -1 - // EQUAL indicates the target matches the probed element. - EQUAL CompareType = 0 - // TARGET_BIG indicates the target is smaller than the probed element; search left. - TARGET_BIG CompareType = 1 -) - -// Bsearch performs a binary search on a sorted slice. -// The compare function should return one of TARGET_SMALL, EQUAL, or TARGET_BIG -// for the probed element. It returns the index i such that -// compare(slice[i]) == EQUAL, -// or -1 if no such element exists. -func Bsearch[T any](slice []T, compare func(target T) CompareType) int { - left, right := 0, len(slice)-1 - - for left <= right { - mid := (left + right) / 2 - - if compare(slice[mid]) == EQUAL { - return mid - } else if compare(slice[mid]) == TARGET_SMALL { - left = mid + 1 - } else if compare(slice[mid]) == TARGET_BIG { - right = mid - 1 - } else { - panic("compare must return a value from compare_type") - } - } - - return -1 -} diff --git a/slice/bsearch_test.go b/slice/bsearch_test.go deleted file mode 100644 index 4b69e37..0000000 --- a/slice/bsearch_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package slice_test - -import ( - "testing" - - "github.com/elecbug/netkit/slice" -) - -func TestBsearch(t *testing.T) { - arr := make([]int, 1000000) - - for i := 0; i < len(arr); i++ { - arr[i] = i * 2 - } - - idx := slice.Bsearch(arr, func(target int) slice.CompareType { - if target == 123456 { - return slice.EQUAL - } else if target < 123456 { - return slice.TARGET_SMALL - } else { - return slice.TARGET_BIG - } - }) - - if idx != -1 { - t.Logf("Index: %d, value: %d", idx, arr[idx]) - } else { - t.Logf("Do not find: %d", idx) - } - - idx = slice.Bsearch(arr, func(target int) slice.CompareType { - if target == 123457 { - return slice.EQUAL - } else if target < 123457 { - return slice.TARGET_SMALL - } else { - return slice.TARGET_BIG - } - }) - - if idx != -1 { - t.Logf("Index: %d, value: %d", idx, arr[idx]) - } else { - t.Logf("Do not find: %d", idx) - } - - idx = slice.Bsearch(arr, func(target int) slice.CompareType { - if target == -1 { - return slice.EQUAL - } else if target < -1 { - return slice.TARGET_SMALL - } else { - return slice.TARGET_BIG - } - }) - - if idx != -1 { - t.Logf("Index: %d, value: %d", idx, arr[idx]) - } else { - t.Logf("Do not find: %d", idx) - } - - idx = slice.Bsearch(arr, func(target int) slice.CompareType { - if target == 10000000 { - return slice.EQUAL - } else if target < 10000000 { - return slice.TARGET_SMALL - } else { - return slice.TARGET_BIG - } - }) - - if idx != -1 { - t.Logf("Index: %d, value: %d", idx, arr[idx]) - } else { - t.Logf("Do not find: %d", idx) - } -} diff --git a/slice/sort.go b/slice/sort.go deleted file mode 100644 index 8b0a0b7..0000000 --- a/slice/sort.go +++ /dev/null @@ -1,137 +0,0 @@ -package slice - -import "sync" - -// Sort performs a merge sort on slice using compare. -// The compare function should return true if a should come before b. -func Sort[T any](slice []T, compare func(a, b T) bool) { - if len(slice) <= 1 { - return - } - - var mergeSort func(arr []T, compare func(a, b T) bool) []T - var merge func(left, right []T, compare func(a, b T) bool) []T - - mergeSort = func(arr []T, compare func(a, b T) bool) []T { - if len(arr) <= 1 { - return arr - } - - mid := len(arr) / 2 - left := mergeSort(arr[:mid], compare) - right := mergeSort(arr[mid:], compare) - return merge(left, right, compare) - } - - merge = func(left, right []T, compare func(a, b T) bool) []T { - result := make([]T, 0, len(left)+len(right)) - i, j := 0, 0 - - for i < len(left) && j < len(right) { - if compare(left[i], right[j]) { - result = append(result, left[i]) - i++ - } else { - result = append(result, right[j]) - j++ - } - } - - // Append remaining elements - result = append(result, left[i:]...) - result = append(result, right[j:]...) - return result - } - - // Sort and copy back the result - sorted := mergeSort(slice, compare) - copy(slice, sorted) -} - -// ParallelSort performs a parallel merge sort on slice using compare. -// level is the maximum recursion depth to parallelize. -func ParallelSort[T any](slice []T, compare func(a, b T) bool, level int) { - if len(slice) <= 1 { - return - } - - var mergeSort func(arr []T, compare func(a, b T) bool, depth int, wg *sync.WaitGroup) []T - var merge func(left, right []T, compare func(a, b T) bool) []T - - mergeSort = func(arr []T, compare func(a, b T) bool, depth int, parentWG *sync.WaitGroup) []T { - defer func() { - if parentWG != nil { - parentWG.Done() - } - }() - - if len(arr) <= 1 { - return arr - } - - mid := len(arr) / 2 - - left := arr[:mid] - right := arr[mid:] - - if depth < level { - var wg sync.WaitGroup - wg.Add(2) - - go func() { - left = mergeSort(left, compare, depth+1, &wg) - }() - right = mergeSort(right, compare, depth+1, &wg) - - wg.Wait() - } else { - left = mergeSort(left, compare, depth+1, nil) - right = mergeSort(right, compare, depth+1, nil) - } - - return merge(left, right, compare) - } - - merge = func(left, right []T, compare func(a, b T) bool) []T { - result := make([]T, 0, len(left)+len(right)) - i, j := 0, 0 - - for i < len(left) && j < len(right) { - if compare(left[i], right[j]) { - result = append(result, left[i]) - i++ - } else { - result = append(result, right[j]) - j++ - } - } - - // Append remaining elements - result = append(result, left[i:]...) - result = append(result, right[j:]...) - return result - } - - // Sort and copy back the result - - var wg sync.WaitGroup - depth := 0 - - wg.Add(1) - sorted := mergeSort(slice, compare, depth+1, &wg) - wg.Wait() - - copy(slice, sorted) -} - -// IsSorted verifies that slice is sorted. -// It returns true if for all adjacent elements a, b in slice, compare(a, b) is true. -func IsSorted[T any](slice []T, compare func(a, b T) bool) bool { - for i := 0; i < len(slice)-1; i++ { - if !compare(slice[i], slice[i+1]) { - return false - } - } - - return true -} diff --git a/slice/sort_test.go b/slice/sort_test.go deleted file mode 100644 index f89c037..0000000 --- a/slice/sort_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package slice_test - -import ( - "math/rand" - "sort" - "testing" - "time" - - "github.com/elecbug/netkit/slice" -) - -func TestSort(t *testing.T) { - result := []float64{0, 0, 0} - iter := 10 - - for i := 0; i < iter; i++ { - data := make([]int, 1000000) - - for i := range data { - data[i] = rand.Int() - } - - copy1 := make([]int, len(data)) - copy2 := make([]int, len(data)) - copy3 := make([]int, len(data)) - copy(copy1, data) - copy(copy2, data) - copy(copy3, data) - - start := time.Now().UnixNano() - sort.Slice(copy1, func(i, j int) bool { return copy1[i] < copy1[j] }) - end := float64(time.Now().UnixNano()-start) / 10e6 - t.Logf("General sort: %v, time: %fms", slice.IsSorted(copy1, func(i, j int) bool { return i < j }), end) - result[0] += end - - start = time.Now().UnixNano() - slice.Sort(copy2, func(i, j int) bool { return i < j }) - end = float64(time.Now().UnixNano()-start) / 10e6 - t.Logf("go_type sort: %v, time: %fms", slice.IsSorted(copy2, func(i, j int) bool { return i < j }), end) - result[1] += end - - start = time.Now().UnixNano() - slice.ParallelSort(copy3, func(i, j int) bool { return i < j }, 7) - end = float64(time.Now().UnixNano()-start) / 10e6 - t.Logf("go_type parallel sort: %v, time: %fms", slice.IsSorted(copy3, func(i, j int) bool { return i < j }), end) - result[2] += end - } - - t.Logf("--Benchmark--") - t.Logf("General sort: %fms", result[0]/float64(iter)) - t.Logf("go_type sort: %fms", result[1]/float64(iter)) - t.Logf("go_type parallel sort: %fms", result[2]/float64(iter)) -}