Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Releases: LdDl/ch

v1.10.0 - ManyToMany queries: thread safe pool and other optimizations

29 Nov 19:10
c8549b3

Choose a tag to compare

What's new

  • For ManyToMany queries same changes as in #43 for OneToOne and OneToMany: use epoch-based cleaning
  • Make ManyToMany variation be available for queries pool for thread safe usage

For more info see #49

v1.9.0 - Recustomization

29 Nov 18:20
67294e5

Choose a tag to compare

What's new

  • Added a way to dynamically rebuild CH when update specific edge's weight. Inspired by Customizable Contraction Hierarchies (Dibbelt, Strasser, Wagner) paper, but not using nested dissection, just vertices importance-based ordering.
    This feature allows you to update edge weights without rebuilding the entire contraction hierarchy. Useful for:

    • Traffic updates (congestion, accidents and other events)
    • Time-dependent routing
    g := Graph{}
    graphFromCSV(&g, "data/pgrouting_osm.csv")
    g.PrepareContractionHierarchies()
    
    // Single update with immediate recustomization
    err := g.UpdateEdgeWeight(fromVertex, toVertex, newWeight, true)
    
    // Batch updates (more efficient for multiple changes)
    g.UpdateEdgeWeight(edge1From, edge1To, weight1, false)
    g.UpdateEdgeWeight(edge2From, edge2To, weight2, false)
    g.UpdateEdgeWeight(edge3From, edge3To, weight3, false)
    g.Recustomize() // Apply all changes at once

    When to use single vs batch updates:

    Scenario Method Why
    One edge changed UpdateEdgeWeight(..., true) Simple, immediate
    Multiple edges changed Batch + Recustomize() Faster, single pass
    Real-time traffic feed Batch + periodic Recustomize() Amortize cost

    If you have your own import logic (e.g., reading additional data like GeoJSON coordinates alongside the graph), you need to call FinalizeImport() after loading all vertices, edges, and shortcuts:

    graph := ch.NewGraph()
    
    // Your custom import logic:
    // - CreateVertex() for each vertex
    // - AddEdge() for each edge
    // - SetOrderPos() and SetImportance() for each vertex
    // - AddShortcut() for each shortcut
    
    graph.FinalizeImport() // Required for recustomization support
    
    // Now graph is ready for queries and UpdateEdgeWeight/Recustomize

    This is required because FinalizeImport() builds internal data structures (contractionOrder, shortcutsByVia) needed for dynamic edge weight updates.

    If you use the built-in ImportFromFile() function, this is called automatically.

For the more info see #48

v1.8.0 - Thread safe pool and other optimizations

29 Nov 16:19
76836a9

Choose a tag to compare

What's new

  • Thread-safe API via sync.Pool
  • Optimizations via caching and epoch-based cleaning

For more information see #43

Breaking changes:

  • In #47: Default Graph.ShortestPath() and related methods are no longer thread-safe due to epoch-based buffer reuse. If you need concurrent queries from multiple goroutines, use the new QueryPool API:
    pool := graph.NewQueryPool()
    cost, path := pool.ShortestPath(source, target)
    costs, paths := pool.ShortestPathOneToMany(source, targets)

v1.7.8 - Fix ManyToMany

06 Jun 12:15

Choose a tag to compare

What's new

  1. Replaced rounding in tests for comparing floats to epsilon threshold
  2. ManyToMany was broken due map[] lookup error. See the ref.: 2d61de4

v1.7.7 - Minor

10 Oct 15:05
89d6a81

Choose a tag to compare

What's new

Minor improvements of code.

v1.7.6 - Fix import

30 Apr 16:36

Choose a tag to compare

What's new

  1. There were not closing file. So fix this bug - 9413bf1#diff-5a3040133bc8fe1d1df5b1e886d71838a22430b148df2e80c71bdbc741e52be1
  2. Little naming changes

v1.7.5 - Update export functions

30 Apr 13:21

Choose a tag to compare

What's new

Separate code of ExportToFile() in different blocks:

  • ExportEdgesToFile
  • ExportVerticesToFile
  • ExportShortcutsToFile

There is a little overhead due the loop repeats, but 3-d party packages now can export only needed data (especially shortcuts)

v1.7.4 - Update shortcut getter

30 Apr 11:50

Choose a tag to compare

What's new

  1. Update method graph.IsShortcut.
    Old:
// IsShortcut Returns true if edge is a shortcut (edge defined as two vertices)
func (graph *Graph) IsShortcut(labelFromVertex, labelToVertex int64) (ok bool) {
	_, ok = graph.shortcuts[labelFromVertex][labelToVertex]
	return ok
}

New - Now maps proper source/target IDs + returns ViaVertex ID:

// IsShortcut Returns (vertex_id; true) if edge is a shortcut (edge defined as two vertices)
//
// If source or taget vertex is not found then returns (-1; false)
// If edge is not a shortcut then returns (-1; false)
//
func (graph *Graph) IsShortcut(labelFromVertex, labelToVertex int64) (int64, bool) {
	source, ok := graph.mapping[labelFromVertex]
	if !ok {
		return -1, ok
	}
	target, ok := graph.mapping[labelToVertex]
	if !ok {
		return -1, ok
	}
	shortcut, ok := graph.shortcuts[source][target]
	if !ok {
		return -1, ok
	}
	return graph.Vertices[shortcut.ViaVertex].Label, ok
}

v1.7.3 - New getters

30 Apr 11:41

Choose a tag to compare

What's new

  1. Added new method graph.IsShortcut.
// IsShortcut Returns true if edge is a shortcut (edge defined as two vertices)
func (graph *Graph) IsShortcut(labelFromVertex, labelToVertex int64) (ok bool) {
	_, ok = graph.shortcuts[labelFromVertex][labelToVertex]
	return ok
}
  1. Added new method graph.FindVertex
// FindVertex Returns index of vertex in graph
//
// labelExternal - User defined ID of vertex
// If vertex is not found then returns (-1; false)
//
func (graph *Graph) FindVertex(labelExternal int64) (idx int64, ok bool) {
	idx, ok = graph.mapping[labelExternal]
	if !ok {
		return -1, ok
	}
	return
}

v1.7.2 - Eliminate shortcuts duplicates

30 Apr 08:37

Choose a tag to compare

What's new

  1. Added usefull methods on *Vertex such as: delete / update incident edge.
  2. Eliminated shortcut duplicates, e.g.:
A -> B -> C on some iteration gives shortcut cost 205.
A -> G -> C on some iteration gives shortcut cost less 195.
So we should eliminate A-B-C and create A-G-C