127 lines
4.8 KiB
Java
127 lines
4.8 KiB
Java
package defects.libvirt.unit;
|
||
|
||
import java.util.*;
|
||
|
||
/**
|
||
* libvirt-0002: x86ModelFromCPU() x86FeatureFind O(C×F) linear scan.
|
||
*
|
||
* Models the loop in x86ModelFromCPU() (cpu_x86.c:1407–1424):
|
||
* for each feature in cpu->features:
|
||
* x86FeatureFind(map, name) → O(F) linear scan of global feature map
|
||
*
|
||
* Defective: feature map is a List<String> scanned linearly per CPU feature.
|
||
* Fixed: feature map is a HashMap<String,Integer> with O(1) lookup.
|
||
*/
|
||
public class Libvirt0002CpuFeatureFindAlgorithm {
|
||
|
||
// -----------------------------------------------------------------------
|
||
// Defective: O(C × F) — linear scan of map->features per cpu feature
|
||
// -----------------------------------------------------------------------
|
||
public static class DefectiveFeatureFind {
|
||
public int comparisons;
|
||
|
||
/**
|
||
* @param cpuFeatures C explicit feature names in the domain CPU def
|
||
* @param mapFeatureList F feature names in the global map (ordered)
|
||
* @return list of resolved feature indices
|
||
*/
|
||
public List<Integer> resolveFeatures(List<String> cpuFeatures,
|
||
List<String> mapFeatureList) {
|
||
comparisons = 0;
|
||
List<Integer> resolved = new ArrayList<>();
|
||
for (String cpuFeat : cpuFeatures) {
|
||
// x86FeatureFind: linear scan
|
||
int idx = -1;
|
||
for (int i = 0; i < mapFeatureList.size(); i++) {
|
||
comparisons++;
|
||
if (mapFeatureList.get(i).equals(cpuFeat)) {
|
||
idx = i;
|
||
break;
|
||
}
|
||
}
|
||
if (idx >= 0) resolved.add(idx);
|
||
}
|
||
return resolved;
|
||
}
|
||
}
|
||
|
||
// -----------------------------------------------------------------------
|
||
// Fixed: O(C) — HashMap lookup per feature
|
||
// -----------------------------------------------------------------------
|
||
public static class FixedFeatureFind {
|
||
public int comparisons;
|
||
|
||
public List<Integer> resolveFeatures(List<String> cpuFeatures,
|
||
Map<String, Integer> featureByName) {
|
||
comparisons = 0;
|
||
List<Integer> resolved = new ArrayList<>();
|
||
for (String cpuFeat : cpuFeatures) {
|
||
comparisons++;
|
||
Integer idx = featureByName.get(cpuFeat);
|
||
if (idx != null) resolved.add(idx);
|
||
}
|
||
return resolved;
|
||
}
|
||
}
|
||
|
||
// -----------------------------------------------------------------------
|
||
// Helpers
|
||
// -----------------------------------------------------------------------
|
||
|
||
public static List<String> buildMapFeatureList(int count) {
|
||
List<String> list = new ArrayList<>();
|
||
for (int i = 0; i < count; i++) {
|
||
list.add("map-feat-" + i);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public static Map<String, Integer> buildFeatureIndex(List<String> mapFeatures) {
|
||
Map<String, Integer> idx = new HashMap<>();
|
||
for (int i = 0; i < mapFeatures.size(); i++) {
|
||
idx.put(mapFeatures.get(i), i);
|
||
}
|
||
return idx;
|
||
}
|
||
|
||
/**
|
||
* Build C CPU features that are spread across the map (worst case: features
|
||
* are at the end of the list, maximising linear-scan depth).
|
||
*/
|
||
public static List<String> buildCpuFeatures(List<String> mapFeatures,
|
||
int cpuFeatureCount) {
|
||
List<String> cpu = new ArrayList<>();
|
||
int start = Math.max(0, mapFeatures.size() - cpuFeatureCount);
|
||
for (int i = start; i < mapFeatures.size(); i++) {
|
||
cpu.add(mapFeatures.get(i));
|
||
}
|
||
return cpu;
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println("libvirt-0002: x86ModelFromCPU x86FeatureFind O(C×F) vs O(C)");
|
||
System.out.println("=".repeat(60));
|
||
|
||
int[] fSizes = {100, 300, 500, 800};
|
||
int cpuFeatureCount = 100;
|
||
|
||
DefectiveFeatureFind defective = new DefectiveFeatureFind();
|
||
FixedFeatureFind fixed = new FixedFeatureFind();
|
||
|
||
System.out.printf("%-8s %-8s %-12s %-12s %-8s%n",
|
||
"F", "C", "Defect ops", "Fixed ops", "Ratio");
|
||
|
||
for (int f : fSizes) {
|
||
List<String> mapList = buildMapFeatureList(f);
|
||
Map<String, Integer> mapIdx = buildFeatureIndex(mapList);
|
||
List<String> cpuFeats = buildCpuFeatures(mapList, cpuFeatureCount);
|
||
|
||
defective.resolveFeatures(cpuFeats, mapList);
|
||
fixed.resolveFeatures(cpuFeats, mapIdx);
|
||
|
||
double ratio = (double) defective.comparisons / Math.max(fixed.comparisons, 1);
|
||
System.out.printf("%-8d %-8d %-12d %-12d %.1f×%n",
|
||
f, cpuFeatureCount, defective.comparisons, fixed.comparisons, ratio);
|
||
}
|
||
}
|
||
}
|