Cybersecurity-Projects/PROJECTS/intermediate/security-news-scraper/internal/cluster/rebuild.go

52 lines
1.2 KiB
Go

// ©AngelaMos | 2026
// rebuild.go
package cluster
import (
"github.com/CarterPerez-dev/nadezhda/internal/store"
)
type Stats struct {
Total int
MultiSource int
LargestSize int
}
func Rebuild(st *store.Store, jaccardThreshold float64, windowSeconds, sinceUnix int64) (Stats, error) {
candidates, err := st.ClusterCandidates(sinceUnix)
if err != nil {
return Stats{}, err
}
cveMap, err := st.ArticleCVEMap()
if err != nil {
return Stats{}, err
}
items := make([]Item, len(candidates))
for i, c := range candidates {
items[i] = Item{ID: c.ID, SourceID: c.SourceID, Title: c.Title, Time: c.Time, CVEs: cveMap[c.ID]}
}
clusters := Compute(items, jaccardThreshold, windowSeconds)
rows := make([]store.ClusterRow, len(clusters))
stats := Stats{Total: len(clusters)}
for i, c := range clusters {
rows[i] = store.ClusterRow{
Key: c.Key, Members: c.Members, FirstSeen: c.FirstSeen, LastSeen: c.LastSeen,
}
if c.SourceCount > 1 {
stats.MultiSource++
}
if size := len(c.Members); size > stats.LargestSize {
stats.LargestSize = size
}
}
if err := st.ReplaceClusters(rows); err != nil {
return Stats{}, err
}
return stats, nil
}