fix(api): SNMP/hosts — одна строка на IP (DISTINCT ON), лимиты для больших сканов
Made-with: Cursor
This commit is contained in:
+46
-22
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user