fix(api): SNMP/hosts — одна строка на IP (DISTINCT ON), лимиты для больших сканов

Made-with: Cursor
This commit is contained in:
Луценко Андрей Анатольевич
2026-04-10 15:35:45 +10:00
parent 009aeb5dbf
commit a36edbc26b
4 changed files with 69 additions and 36 deletions
+46 -22
View File
@@ -221,21 +221,11 @@ func (s *MemoryStore) SaveHostResult(scanID string, host HostResult) error {
}
func (s *MemoryStore) ListHostResults(scanID string, limit int) []HostResult {
if limit <= 0 {
limit = 500
}
s.mu.RLock()
defer s.mu.RUnlock()
items := s.hosts[scanID]
if len(items) <= limit {
out := make([]HostResult, len(items))
copy(out, items)
return out
}
out := make([]HostResult, limit)
copy(out, items[:limit])
return out
return dedupeHostsLatest(items, limit)
}
func (s *MemoryStore) SaveOpenPortResult(scanID string, result OpenPortResult) error {
@@ -279,21 +269,11 @@ func (s *MemoryStore) SaveSNMPResult(scanID string, result SNMPResult) error {
}
func (s *MemoryStore) ListSNMPResults(scanID string, limit int) []SNMPResult {
if limit <= 0 {
limit = 1000
}
s.mu.RLock()
defer s.mu.RUnlock()
items := s.snmp[scanID]
if len(items) <= limit {
out := make([]SNMPResult, len(items))
copy(out, items)
return out
}
out := make([]SNMPResult, limit)
copy(out, items[:limit])
return out
return dedupeSNMPLatest(items, limit)
}
func (s *MemoryStore) SaveLLDPResult(scanID string, result LLDPResult) error {
@@ -367,3 +347,47 @@ func newID() (string, error) {
}
return hex.EncodeToString(b[:]), nil
}
func dedupeHostsLatest(items []HostResult, limit int) []HostResult {
if limit <= 0 {
limit = 200000
}
m := make(map[string]HostResult, len(items))
for _, h := range items {
cur, ok := m[h.IP]
if !ok || h.CheckedAt.After(cur.CheckedAt) {
m[h.IP] = h
}
}
out := make([]HostResult, 0, len(m))
for _, h := range m {
out = append(out, h)
}
sort.Slice(out, func(i, j int) bool { return out[i].CheckedAt.After(out[j].CheckedAt) })
if len(out) > limit {
out = out[:limit]
}
return out
}
func dedupeSNMPLatest(items []SNMPResult, limit int) []SNMPResult {
if limit <= 0 {
limit = 200000
}
m := make(map[string]SNMPResult, len(items))
for _, r := range items {
cur, ok := m[r.IP]
if !ok || r.CheckedAt.After(cur.CheckedAt) {
m[r.IP] = r
}
}
out := make([]SNMPResult, 0, len(m))
for _, r := range m {
out = append(out, r)
}
sort.Slice(out, func(i, j int) bool { return out[i].CheckedAt.After(out[j].CheckedAt) })
if len(out) > limit {
out = out[:limit]
}
return out
}