import java.util.*; /** * Unit test for synapse-0001: sync handler newly_joined_rooms List membership O(J*N) * * Simulates the _get_rooms_changed loop in synapse/handlers/sync.py * where `room_id in newly_joined_rooms` is checked for every joined room. * * Defect: newly_joined_rooms is a List, so `in` is O(N) per check = O(J*N) total. * Fix: Use a Set, so `in` is O(1) per check = O(J) total. */ public class SynapseSyncNewlyJoinedRoomsTest { /** Simulate defective code: List-based membership test */ static int simulateDefective(List joinedRoomIds, List newlyJoinedRooms) { int ops = 0; for (String roomId : joinedRoomIds) { // Simulates: newly_joined = room_id in newly_joined_rooms (line 2252) boolean found = false; for (String njr : newlyJoinedRooms) { ops++; if (njr.equals(roomId)) { found = true; break; } } // In real code, `found` determines whether to do full-state sync for this room } return ops; } /** Simulate fixed code: Set-based membership test */ static int simulateFixed(List joinedRoomIds, Set newlyJoinedRooms) { int ops = 0; for (String roomId : joinedRoomIds) { ops++; boolean found = newlyJoinedRooms.contains(roomId); } return ops; } public static void main(String[] args) { // Parameters: J = number of joined rooms, N = number of newly joined rooms int[] sizes = {100, 500, 1000, 5000}; int N_NEWLY = 100; // newly joined rooms in a sync window System.out.println("synapse-0001: sync handler newly_joined_rooms List membership O(J*N)"); System.out.println("=".repeat(75)); System.out.printf("%-12s %-12s %-12s %-12s %-10s%n", "J(joined)", "N(newly)", "Defective", "Fixed", "Ratio"); System.out.println("-".repeat(75)); boolean allPass = true; for (int J : sizes) { // Build joined room IDs List joinedRoomIds = new ArrayList<>(J); for (int i = 0; i < J; i++) { joinedRoomIds.add("!room" + i + ":example.com"); } // Build newly joined rooms (subset of joined) List newlyJoinedList = new ArrayList<>(N_NEWLY); Set newlyJoinedSet = new HashSet<>(N_NEWLY); for (int i = 0; i < N_NEWLY; i++) { String roomId = "!room" + (J - N_NEWLY + i) + ":example.com"; newlyJoinedList.add(roomId); newlyJoinedSet.add(roomId); } int defectiveOps = simulateDefective(joinedRoomIds, newlyJoinedList); int fixedOps = simulateFixed(joinedRoomIds, newlyJoinedSet); double ratio = (double) defectiveOps / fixedOps; System.out.printf("%-12d %-12d %-12d %-12d %-10.1fx%n", J, N_NEWLY, defectiveOps, fixedOps, ratio); // At J=5000, N=100: defective should be ~50x worse if (J >= 1000 && ratio < 5.0) { System.out.println(" FAIL: expected ratio >= 5.0 at J=" + J); allPass = false; } } System.out.println("-".repeat(75)); System.out.println(allPass ? "PASS" : "FAIL"); System.exit(allPass ? 0 : 1); } }