import java.util.*; /** * CWE-407 simulation tests for darktable defects. * * darktable-0001: map_locations image diff via g_list_find O(N*M) * darktable-0002: _tag_add_tags_to_list dedup via g_list_find O(T*L) * darktable-0003: map view clustering sel_imgs g_list_find inside O(I*J) loop */ public class DarktableTest { // --------------------------------------------------------------- // darktable-0001: map_locations symmetric diff O(N*M) vs O(N+M) // --------------------------------------------------------------- /** Defective: g_list_find inside loop — O(N*M) */ static int mapLocationDiffDefective(List oldImgs, List newImgs) { int ops = 0; // detach old not in new for (int id : oldImgs) { for (int nid : newImgs) { ops++; if (nid == id) break; } } // attach new not in old for (int id : newImgs) { for (int oid : oldImgs) { ops++; if (oid == id) break; } } return ops; } /** Fixed: GHashTable for O(1) lookup — O(N+M) */ static int mapLocationDiffFixed(List oldImgs, List newImgs) { int ops = 0; Set newSet = new HashSet<>(newImgs); ops += newImgs.size(); for (int id : oldImgs) { newSet.contains(id); ops++; } Set oldSet = new HashSet<>(oldImgs); ops += oldImgs.size(); for (int id : newImgs) { oldSet.contains(id); ops++; } return ops; } static void testMapLocationDiff() { int N = 1000; List oldImgs = new ArrayList<>(); List newImgs = new ArrayList<>(); for (int i = 0; i < N; i++) { oldImgs.add(i); newImgs.add(i + N / 2); } int defectOps = mapLocationDiffDefective(oldImgs, newImgs); int fixedOps = mapLocationDiffFixed(oldImgs, newImgs); double ratio = (double) defectOps / fixedOps; System.out.printf("darktable-0001 map_locations diff: defect=%d fixed=%d ratio=%.1fx%n", defectOps, fixedOps, ratio); assert ratio > 10 : "Expected >10x ratio, got " + ratio; System.out.println(" PASS"); } // --------------------------------------------------------------- // darktable-0002: tag dedup via g_list_find O(T*L) ≈ O(N²) // --------------------------------------------------------------- /** Defective: linear scan dedup */ static int tagAddToListDefective(List existingTags, List newTags) { int ops = 0; List list = new ArrayList<>(existingTags); for (int tag : newTags) { boolean found = false; for (int t : list) { ops++; if (t == tag) { found = true; break; } } if (!found) list.add(tag); } return ops; } /** Fixed: HashSet companion */ static int tagAddToListFixed(List existingTags, List newTags) { int ops = 0; Set seen = new HashSet<>(existingTags); ops += existingTags.size(); for (int tag : newTags) { ops++; if (!seen.contains(tag)) { seen.add(tag); } } return ops; } static void testTagAddToList() { int N = 500; List existing = new ArrayList<>(); List toAdd = new ArrayList<>(); // all unique — worst case for dedup for (int i = 0; i < N; i++) existing.add(i); for (int i = N; i < 2 * N; i++) toAdd.add(i); int defectOps = tagAddToListDefective(existing, toAdd); int fixedOps = tagAddToListFixed(existing, toAdd); double ratio = (double) defectOps / fixedOps; System.out.printf("darktable-0002 tag dedup: defect=%d fixed=%d ratio=%.1fx%n", defectOps, fixedOps, ratio); assert ratio > 50 : "Expected >50x ratio, got " + ratio; System.out.println(" PASS"); } // --------------------------------------------------------------- // darktable-0003: map view sel_imgs inside O(I*J) clustering loop // --------------------------------------------------------------- /** Defective: g_list_find(sel_imgs, imgid) inside nested I×J loop — O(I²×S) */ static long mapViewClusterDefective(int imgCount, List selImgs, int[] clusterIds) { long ops = 0; for (int i = 0; i < imgCount; i++) { int group = clusterIds[i]; for (int j = 0; j < imgCount; j++) { if (clusterIds[j] == group) { // linear scan of sel_imgs for (int s : selImgs) { ops++; if (s == j) break; } } } } return ops; } /** Fixed: HashSet for O(1) selection check — O(I²+S) */ static long mapViewClusterFixed(int imgCount, List selImgs, int[] clusterIds) { long ops = 0; Set selSet = new HashSet<>(selImgs); ops += selImgs.size(); for (int i = 0; i < imgCount; i++) { int group = clusterIds[i]; for (int j = 0; j < imgCount; j++) { if (clusterIds[j] == group) { selSet.contains(j); ops++; } } } return ops; } static void testMapViewCluster() { int I = 500; int S = 200; List selImgs = new ArrayList<>(); for (int i = 0; i < S; i++) selImgs.add(i); // All in one cluster — worst case int[] clusterIds = new int[I]; Arrays.fill(clusterIds, 1); long defectOps = mapViewClusterDefective(I, selImgs, clusterIds); long fixedOps = mapViewClusterFixed(I, selImgs, clusterIds); double ratio = (double) defectOps / fixedOps; System.out.printf("darktable-0003 map view cluster sel: defect=%d fixed=%d ratio=%.1fx%n", defectOps, fixedOps, ratio); assert ratio > 10 : "Expected >10x ratio, got " + ratio; System.out.println(" PASS"); } // --------------------------------------------------------------- public static void main(String[] args) { testMapLocationDiff(); testTagAddToList(); testMapViewCluster(); System.out.println("\nAll 3 darktable CWE-407 tests PASSED."); } }