# 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**.
