74 lines
2.1 KiB
Markdown
74 lines
2.1 KiB
Markdown
# UNDF: UNDF-2026-000000416
|
||
# hazelcast-0002 — QueueContainer.contains() O(D×Q) nested scan
|
||
|
||
## Classification
|
||
|
||
| Field | Value |
|
||
|-------|-------|
|
||
| CWE | CWE-407: Algorithmic Complexity — Linear Membership Test in Outer Loop |
|
||
| Severity | MEDIUM |
|
||
| Component | `hazelcast/src/main/java/com/hazelcast/collection/impl/queue/QueueContainer.java` |
|
||
| Method | `contains(Collection<Data> dataSet)` |
|
||
| Lines | 753–767 |
|
||
| Public API | `IQueue.containsAll(Collection)` |
|
||
|
||
## Defective Code
|
||
|
||
```java
|
||
// QueueContainer.java:753-767
|
||
public boolean contains(Collection<Data> dataSet) {
|
||
for (Data data : dataSet) { // O(D) outer loop
|
||
boolean contains = false;
|
||
for (QueueItem item : getItemQueue()) { // O(Q) inner scan
|
||
if (item.getSerializedObject() != null && item.getSerializedObject().equals(data)) {
|
||
contains = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!contains) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
```
|
||
|
||
For each of D query items, the entire Q-item queue is scanned linearly.
|
||
|
||
## Root Cause
|
||
|
||
No pre-built lookup structure over queue items. Each membership test costs O(Q).
|
||
Total cost for `containsAll(D items)` on a Q-item queue: **O(D × Q)**.
|
||
|
||
## Fix
|
||
|
||
Build a `Set<Data>` from the queue's serialized objects once, then check each query
|
||
item against the set in O(1).
|
||
|
||
```java
|
||
public boolean contains(Collection<Data> dataSet) {
|
||
Set<Data> queueData = new HashSet<>(getItemQueue().size() * 2);
|
||
for (QueueItem item : getItemQueue()) {
|
||
if (item.getSerializedObject() != null) {
|
||
queueData.add(item.getSerializedObject());
|
||
}
|
||
}
|
||
for (Data data : dataSet) { // O(D)
|
||
if (!queueData.contains(data)) { // O(1)
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
```
|
||
|
||
## Complexity
|
||
|
||
| | Before | After |
|
||
|-|--------|-------|
|
||
| `contains(D items)` on Q-item queue | O(D × Q) | O(Q + D) |
|
||
|
||
## Speedup Estimate
|
||
|
||
At D = 500, Q = 1 000 (all-distinct, worst case — every item found): **~250× fewer comparisons**.
|
||
At D = 200, Q = 5 000: **~1 000× fewer comparisons**.
|