feat: add go bindings package
What does this MR do and why?
Adds go bindings package:
- adds Go module so the indexer can be seamlessly called from Go
- updates CI to build c_bindings static lib as part of the release
- adds CI test for building/using go bindings
This thin go package can be used when using knowledge graph from Go.
Related Issues
Related to gitlab-org/gitlab-zoekt-indexer#90 (closed)
Testing
Go test(s) can be either executed in CI by triggering "build-bindings" job, or executed locally with:
mise build_lib
cd bindings/go/indexer
go test
Also it can be tested with a simple program:
package main
import "gitlab.com/gitlab-org/rust/knowledge-graph/bindings/go/indexer"
const RepoDir = "/home/honza/tmp/repos/repo-small"
const DbDir = "/home/honza/tmp/kuzu_dbs/repo1"
func main() {
indexer.FullIndex(RepoDir, DbDir, "/tmp/parquet", 1)
}
Also may be necessary to replace the package with local version:
honza@jprovaznik--181201391-Z5N94 ~/dev/binding-test (master)$ cat go.mod
module main
go 1.24.5
require (
gitlab.com/gitlab-org/rust/knowledge-graph/bindings/go v0.0.0-00010101000000-000000000000 // indirect
)
replace gitlab.com/gitlab-org/rust/knowledge-graph/bindings/go => ../../dev/knowledge-graph/bindings/go
Performance Analysis
Performance Checklist
-
Have you reviewed your memory allocations to ensure you're optimizing correctly? Are you cloning or copying unnecessary data? -
Have you profiled with cargo benchorcriterionto measure performance impact? -
Are you using zero-copy operations where possible (e.g., &strinstead ofString, slice references)? -
Have you considered using Cow<'_, T>for conditional ownership to avoid unnecessary clones? -
Are iterator chains and lazy evaluation being used effectively instead of intermediate collections? -
Are you reusing allocations where possible (e.g., Vec::clear()and reuse vs new allocation)? -
Have you considered using SmallVecor similar for small, stack-allocated collections? -
Are async operations properly structured to avoid blocking the executor? -
Have you reviewed unsafecode blocks for both safety and performance implications? -
Are you using appropriate data structures (e.g., HashMapvsBTreeMapvsIndexMap)? -
Have you considered compile-time optimizations (e.g., const fn, generics instead of trait objects)? -
Are debug assertions ( debug_assert!) used instead of runtime checks where appropriate?
Edited by Jan Provaznik