synapse-0001: sync handler newly_joined_rooms List membership O(J*N); matrix-js-sdk CLEAN
synapse/handlers/sync.py _get_rooms_changed: newly_joined_rooms is List[str] checked with `in` inside for-loop over all joined rooms (line 2252). O(J*N) where J=joined rooms, N=newly joined. Fix: use Set. 99x at J=5000.
This commit is contained in:
parent
7d89e30de9
commit
15db2a0269
5 changed files with 181 additions and 1 deletions
89
defects/synapse/test/SynapseSyncNewlyJoinedRoomsTest.java
Normal file
89
defects/synapse/test/SynapseSyncNewlyJoinedRoomsTest.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
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<String> joinedRoomIds, List<String> 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<String> joinedRoomIds, Set<String> 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<String> 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<String> newlyJoinedList = new ArrayList<>(N_NEWLY);
|
||||
Set<String> 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue