2.7 KiB
2.7 KiB
UNDF: UNDF-2026-000000595
onos-0004: ConnectivityIntentCompiler resourcesAllocated List.contains O(R×C) → O(C) with Set
Classification
| Field | Value |
|---|---|
| CWE | CWE-407 Inefficient Algorithmic Complexity |
| Severity | MEDIUM |
| Component | core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java:263,274,288 |
| Function | ConnectivityIntentCompiler.allocateBandwidth() |
| Hot path | Intent compilation — called per bandwidth allocation request |
| Status | PATCHED (unit test PASS) |
Defect
allocateBandwidth() builds two List collections and then uses .contains() inside
.stream().filter() — O(R) per element — to deduplicate resources:
// ConnectivityIntentCompiler.java:253
List<Resource> resourcesAllocated =
resourcesFromAllocations(resourceAllocations); // List<Resource>
List<ResourceId> idsResourcesAllocated = resourceIds(resourcesAllocated); // List<ResourceId>
// O(R) per element — iterates all resourcesAllocated for each incoming resource
List<Resource> incomingResources =
resources(connectPoints, bw).stream()
.filter(r -> !resourcesAllocated.contains(r)) // O(R)
.collect(Collectors.toList());
// O(R) per element again
List<Resource> resourcesToAdd =
incomingResources.stream()
.filter(r -> !idsResourcesAllocated.contains(r.id())) // O(R)
.collect(Collectors.toList());
// O(R) per element a third time
.filter(rA -> resourceIds(resourcesToUpdate).contains(rA.resource().id())) // O(R)
With R=100 already-allocated resources and C=50 incoming connect-point resource candidates:
100 × 50 × 3 = 15,000 comparisons per allocateBandwidth() call, repeated for each
intent recompile and every topology change that triggers reallocation.
Fix
Convert resourcesAllocated and idsResourcesAllocated to Set before the streams:
Set<Resource> resourcesAllocatedSet = new HashSet<>(resourcesAllocated);
Set<ResourceId> idsResourcesAllocatedSet = new HashSet<>(idsResourcesAllocated);
List<Resource> incomingResources =
resources(connectPoints, bw).stream()
.filter(r -> !resourcesAllocatedSet.contains(r)) // O(1)
.collect(Collectors.toList());
List<Resource> resourcesToAdd =
incomingResources.stream()
.filter(r -> !idsResourcesAllocatedSet.contains(r.id())) // O(1)
.collect(Collectors.toList());
Speedup: ~50× at R=100, C=50 (15,000 → 300 effective ops).