133 lines
5.1 KiB
Java
133 lines
5.1 KiB
Java
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<String> 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<String> computeIgnored(List<String> allFeatures,
|
||
String[] addedFeatures,
|
||
Set<String> modelFeatures) {
|
||
comparisons = 0;
|
||
Set<String> 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<String> computeIgnored(List<String> allFeatures,
|
||
Set<String> addedFeaturesSet,
|
||
Set<String> modelFeatures) {
|
||
comparisons = 0;
|
||
Set<String> 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<String> buildFeatureMap(int count) {
|
||
List<String> 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<String> 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<String> buildAddedSet(List<String> allFeatures, int addedCount) {
|
||
Set<String> 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<String> features = buildFeatureMap(f);
|
||
String[] addedArr = buildAddedArray(features, addedCount);
|
||
Set<String> addedSet = buildAddedSet(features, addedCount);
|
||
Set<String> 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);
|
||
}
|
||
}
|
||
}
|