578/240 — rustc-0004/vertx-0001/asterisk-0003/bitcoin-0001/actix-web-0003/hazelcast-0001+0002/rabbitmq-0005/nginx-0003/haproxy-0003/envoy-0003/istio-0003
This commit is contained in:
parent
dde5ec97fb
commit
e4ee168b1e
50 changed files with 4775 additions and 5 deletions
216
defects/hazelcast/unit/HazelcastQueueAlgorithm.java
Normal file
216
defects/hazelcast/unit/HazelcastQueueAlgorithm.java
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* hazelcast-0001: QueueContainer.compareAndRemove() — ArrayList.contains() O(Q×D)
|
||||
* hazelcast-0002: QueueContainer.contains() — inner queue scan O(D×Q)
|
||||
*
|
||||
* Standalone unit test — no JUnit required.
|
||||
* Compile: javac -d defects/hazelcast/unit defects/hazelcast/unit/HazelcastQueueAlgorithm.java
|
||||
* Run: java -cp defects/hazelcast/unit unit.HazelcastQueueAlgorithm
|
||||
*
|
||||
* QueueItem is modelled as a plain String (the serialized object).
|
||||
* Collections mirror the production types: LinkedList (queue), ArrayList (dataList).
|
||||
*/
|
||||
public class HazelcastQueueAlgorithm {
|
||||
|
||||
static long slowOps;
|
||||
static long fastOps;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// hazelcast-0001: compareAndRemove
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* SLOW: mirrors QueueContainer.compareAndRemove() — ArrayList dataList.contains()
|
||||
* is called inside the outer loop over every queue item.
|
||||
*/
|
||||
static Map<Integer, String> slowCompareAndRemove(Queue<String> itemQueue,
|
||||
Collection<String> dataList,
|
||||
boolean retain) {
|
||||
slowOps = 0;
|
||||
Map<Integer, String> map = new LinkedHashMap<>();
|
||||
int id = 0;
|
||||
for (String item : itemQueue) {
|
||||
id++;
|
||||
slowOps++; // outer loop step
|
||||
boolean found = false;
|
||||
for (String d : dataList) { // ArrayList linear scan — O(D)
|
||||
slowOps++;
|
||||
if (d.equals(item)) { found = true; break; }
|
||||
}
|
||||
if ((retain && !found) || (!retain && found)) {
|
||||
map.put(id, item);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* FAST: patched compareAndRemove — pre-build HashSet<Data> before outer loop.
|
||||
*/
|
||||
static Map<Integer, String> fastCompareAndRemove(Queue<String> itemQueue,
|
||||
Collection<String> dataList,
|
||||
boolean retain) {
|
||||
fastOps = 0;
|
||||
Set<String> dataSet = new HashSet<>(dataList); // O(D) one-time
|
||||
fastOps += dataList.size();
|
||||
Map<Integer, String> map = new LinkedHashMap<>();
|
||||
int id = 0;
|
||||
for (String item : itemQueue) {
|
||||
id++;
|
||||
fastOps++; // O(1) hash lookup
|
||||
boolean found = dataSet.contains(item);
|
||||
if ((retain && !found) || (!retain && found)) {
|
||||
map.put(id, item);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// hazelcast-0002: contains (containsAll)
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* SLOW: mirrors QueueContainer.contains() — scans entire queue for each query item.
|
||||
*/
|
||||
static boolean slowContains(Queue<String> itemQueue, Collection<String> dataSet) {
|
||||
slowOps = 0;
|
||||
for (String data : dataSet) { // outer loop over D queries
|
||||
slowOps++;
|
||||
boolean found = false;
|
||||
for (String item : itemQueue) { // inner scan O(Q)
|
||||
slowOps++;
|
||||
if (item.equals(data)) { found = true; break; }
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* FAST: patched contains — build HashSet from queue once, then O(1) per query.
|
||||
*/
|
||||
static boolean fastContains(Queue<String> itemQueue, Collection<String> dataSet) {
|
||||
fastOps = 0;
|
||||
Set<String> queueData = new HashSet<>(itemQueue.size() * 2);
|
||||
for (String item : itemQueue) {
|
||||
fastOps++; // O(Q) build
|
||||
queueData.add(item);
|
||||
}
|
||||
for (String data : dataSet) {
|
||||
fastOps++; // O(D) lookups, each O(1)
|
||||
if (!queueData.contains(data)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test helpers
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
static Queue<String> buildQueue(int q) {
|
||||
Queue<String> queue = new LinkedList<>();
|
||||
for (int i = 0; i < q; i++) queue.add("item-" + i);
|
||||
return queue;
|
||||
}
|
||||
|
||||
/** dataList: D items, half overlap with queue, half are unique. */
|
||||
static List<String> buildDataList(int q, int d) {
|
||||
List<String> list = new ArrayList<>(d);
|
||||
for (int i = 0; i < d / 2; i++) list.add("item-" + i); // overlaps
|
||||
for (int i = 0; i < d - d / 2; i++) list.add("remove-" + i); // not in queue
|
||||
return list;
|
||||
}
|
||||
|
||||
/** dataSet for containsAll: all items present so worst-case full scan. */
|
||||
static List<String> buildAllPresentList(int q, int d) {
|
||||
List<String> list = new ArrayList<>(d);
|
||||
for (int i = 0; i < d; i++) list.add("item-" + i);
|
||||
return list;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// hazelcast-0001 test
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
static void testCompareAndRemove(int q, int d, int expectedNx) {
|
||||
Queue<String> queue = buildQueue(q);
|
||||
List<String> dataList = buildDataList(q, d);
|
||||
|
||||
Map<Integer, String> slowResult = slowCompareAndRemove(new LinkedList<>(queue), dataList, false);
|
||||
long slow = slowOps;
|
||||
|
||||
Map<Integer, String> fastResult = fastCompareAndRemove(new LinkedList<>(queue), dataList, false);
|
||||
long fast = fastOps;
|
||||
|
||||
boolean match = slowResult.equals(fastResult);
|
||||
boolean ratio = slow > fast * expectedNx;
|
||||
|
||||
System.out.printf("[0001] compareAndRemove q=%-5d d=%-4d slow=%8d fast=%6d ratio=%5.1fx match=%b PASS=%b%n",
|
||||
q, d, slow, fast, (double) slow / fast, match, match && ratio);
|
||||
|
||||
if (!match || !ratio) {
|
||||
throw new AssertionError(
|
||||
"FAIL compareAndRemove q=" + q + " d=" + d +
|
||||
" match=" + match + " slowOps=" + slow + " fastOps=" + fast +
|
||||
" needed ratio>" + expectedNx);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// hazelcast-0002 test
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
static void testContains(int q, int d, int expectedNx) {
|
||||
Queue<String> queue = buildQueue(q);
|
||||
List<String> queryList = buildAllPresentList(q, d);
|
||||
|
||||
boolean slowResult = slowContains(new LinkedList<>(queue), queryList);
|
||||
long slow = slowOps;
|
||||
|
||||
boolean fastResult = fastContains(new LinkedList<>(queue), queryList);
|
||||
long fast = fastOps;
|
||||
|
||||
boolean match = slowResult == fastResult;
|
||||
boolean ratio = slow > fast * expectedNx;
|
||||
|
||||
System.out.printf("[0002] contains q=%-5d d=%-4d slow=%8d fast=%6d ratio=%5.1fx match=%b PASS=%b%n",
|
||||
q, d, slow, fast, (double) slow / fast, match, match && ratio);
|
||||
|
||||
if (!match || !ratio) {
|
||||
throw new AssertionError(
|
||||
"FAIL contains q=" + q + " d=" + d +
|
||||
" match=" + match + " slowOps=" + slow + " fastOps=" + fast +
|
||||
" needed ratio>" + expectedNx);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// main
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== hazelcast-0001: QueueContainer.compareAndRemove O(Q*D) vs O(Q+D) ===");
|
||||
testCompareAndRemove(200, 100, 5);
|
||||
testCompareAndRemove(1000, 500, 20);
|
||||
testCompareAndRemove(2000, 1000, 50);
|
||||
|
||||
System.out.println("=== hazelcast-0002: QueueContainer.contains O(D*Q) vs O(Q+D) ===");
|
||||
testContains(200, 100, 5);
|
||||
testContains(1000, 500, 20);
|
||||
testContains(2000, 1000, 50);
|
||||
|
||||
System.out.println("6/6 PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue