a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
49 lines
1.8 KiB
Go
49 lines
1.8 KiB
Go
package mcp
|
|
|
|
import (
|
|
"github.com/zzet/gortex/internal/analysis"
|
|
)
|
|
|
|
// personalizedPageRank runs a Random-Walk-with-Restart (Personalized
|
|
// PageRank) from the given seed node IDs over the adjacency snapshot
|
|
// and returns each reachable node's proximity score. It is the seam the
|
|
// rerank pipeline's ProximitySignal (and context_closure's proximity
|
|
// mode) reach centrality through.
|
|
//
|
|
// Walks flow through a Merkle-keyed cache (see ppr_cache.go) so repeated
|
|
// walks on an unchanged graph — or on packages that did not change
|
|
// between snapshots — return instantly instead of re-iterating the whole
|
|
// CSR. The cache is bypassed when disabled (GORTEX_PPR_CACHE_DISABLE) or
|
|
// when the snapshot has no package roots.
|
|
func (s *Server) personalizedPageRank(snap *analysis.AdjacencySnapshot, seeds []string) map[string]float64 {
|
|
if snap == nil || len(seeds) == 0 {
|
|
return nil
|
|
}
|
|
cache := s.pprCache
|
|
// topK caps the walk to its highest-scoring nodes before it is cached,
|
|
// so a single retained entry stays a few hundred KB instead of a full-
|
|
// graph-sized map. Applied on both paths so a cached and an uncached
|
|
// walk return the same result.
|
|
topK := pprCacheDefaultTopK
|
|
if cache != nil {
|
|
topK = cache.topK
|
|
}
|
|
if cache == nil || !cache.enabled {
|
|
return snap.PersonalizedPageRankTopK(seeds, 0, topK)
|
|
}
|
|
// Merkle-keyed walk cache: the key embeds the per-package content
|
|
// roots the walk depends on, so an unchanged walk hits even across
|
|
// a snapshot rebuild, and only a walk touching a changed package
|
|
// recomputes. An empty key (no package roots, or no seed resolves)
|
|
// falls through to an uncached walk.
|
|
key := snap.WalkCacheKey(seeds, 0)
|
|
if key != "" {
|
|
if scores, ok := cache.get(key); ok {
|
|
return scores
|
|
}
|
|
}
|
|
scores := snap.PersonalizedPageRankTopK(seeds, 0, topK)
|
|
cache.put(key, scores)
|
|
return scores
|
|
}
|