package defects.libvirt.unit; import java.util.*; /** * libvirt-0001: virCPUx86UpdateLive() addedFeatures g_strv_contains O(F×A). * * Models the loop in virCPUx86UpdateLive() (cpu_x86.c:3189–3222): * for each feature in map->features: * if g_strv_contains(model->addedFeatures, feature->name) → O(A) * * Defective: addedFeatures is a String[] scanned linearly per feature. * Fixed: addedFeatures is a HashSet with O(1) contains. */ public class Libvirt0001CpuUpdateLiveAlgorithm { // ----------------------------------------------------------------------- // Defective: O(F × A) — linear strv scan per feature // ----------------------------------------------------------------------- public static class DefectiveUpdateLive { public int comparisons; /** * @param allFeatures all F feature names in the global map * @param addedFeatures A feature names marked as "added" to this model * @param modelFeatures features explicitly in the CPU definition * @return set of feature names that should be ignored */ public Set computeIgnored(List allFeatures, String[] addedFeatures, Set modelFeatures) { comparisons = 0; Set ignored = new HashSet<>(); for (String feature : allFeatures) { boolean explicit = modelFeatures.contains(feature); if (!explicit && addedFeatures != null) { // g_strv_contains: O(A) linear scan for (String added : addedFeatures) { comparisons++; if (added.equals(feature)) { ignored.add(feature); break; } } } } return ignored; } } // ----------------------------------------------------------------------- // Fixed: O(F) — HashSet contains is O(1) // ----------------------------------------------------------------------- public static class FixedUpdateLive { public int comparisons; public Set computeIgnored(List allFeatures, Set addedFeaturesSet, Set modelFeatures) { comparisons = 0; Set ignored = new HashSet<>(); for (String feature : allFeatures) { comparisons++; boolean explicit = modelFeatures.contains(feature); if (!explicit && addedFeaturesSet != null && addedFeaturesSet.contains(feature)) { ignored.add(feature); } } return ignored; } } // ----------------------------------------------------------------------- // Helpers // ----------------------------------------------------------------------- public static List buildFeatureMap(int count) { List features = new ArrayList<>(); for (int i = 0; i < count; i++) { features.add("feat-" + i); } return features; } /** Build addedFeatures as String[] (defective path). */ public static String[] buildAddedArray(List allFeatures, int addedCount) { String[] added = new String[addedCount]; for (int i = 0; i < addedCount; i++) { added[i] = allFeatures.get(i); // first addedCount features are "added" } return added; } /** Build addedFeatures as HashSet (fixed path). */ public static Set buildAddedSet(List allFeatures, int addedCount) { Set set = new HashSet<>(); for (int i = 0; i < addedCount; i++) { set.add(allFeatures.get(i)); } return set; } public static void main(String[] args) { System.out.println("libvirt-0001: virCPUx86UpdateLive addedFeatures O(F×A) vs O(F)"); System.out.println("=".repeat(60)); int[] fSizes = {100, 300, 500, 800}; int addedCount = 50; DefectiveUpdateLive defective = new DefectiveUpdateLive(); FixedUpdateLive fixed = new FixedUpdateLive(); System.out.printf("%-8s %-8s %-12s %-12s %-8s%n", "F", "A", "Defect ops", "Fixed ops", "Ratio"); for (int f : fSizes) { List features = buildFeatureMap(f); String[] addedArr = buildAddedArray(features, addedCount); Set addedSet = buildAddedSet(features, addedCount); Set modelFeatures = new HashSet<>(); defective.computeIgnored(features, addedArr, modelFeatures); fixed.computeIgnored(features, addedSet, modelFeatures); double ratio = (double) defective.comparisons / Math.max(fixed.comparisons, 1); System.out.printf("%-8d %-8d %-12d %-12d %.1f×%n", f, addedCount, defective.comparisons, fixed.comparisons, ratio); } } }