wave17 complete: systemd/emacs/vim/qemu/tcl/kafka-0007/spark-0004 + 559/240

This commit is contained in:
russell@unturf.com 2026-03-27 20:15:47 -04:00
parent 4221966e66
commit cce7ec653a
32 changed files with 3007 additions and 5 deletions

View file

@ -0,0 +1,247 @@
package unit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* tcl-0001: DoImport O(C×P) export pattern scan per namespace import
*
* Models Tcl's namespace import machinery.
* SLOW: for each of C commands, linear scan P export patterns (current Tcl code)
* FAST: pre-build a HashSet of exported command names; O(1) per command check
*
* In Tcl_Import with wildcard pattern, DoImport is called for each of C commands
* that match the import pattern. Each DoImport call scans P export patterns
* using Tcl_StringMatch. Total: O(C × P).
*/
public class TclDoImportAlgorithm {
// Simple wildcard matcher (subset of Tcl_StringMatch)
static boolean stringMatch(String str, String pattern) {
if (pattern.equals("*")) return true;
if (pattern.endsWith("*")) {
String prefix = pattern.substring(0, pattern.length() - 1);
return str.startsWith(prefix);
}
return str.equals(pattern);
}
// --- SLOW: linear scan of export patterns per command (current DoImport) ---
static class SlowNamespace {
Map<String, Object> cmdTable = new HashMap<>();
List<String> exportPatterns = new ArrayList<>();
long opCount = 0;
void defineCommand(String name) {
cmdTable.put(name, new Object());
}
void addExportPattern(String pattern) {
exportPatterns.add(pattern);
}
/** Check if cmdName is exported: linear scan over P patterns */
boolean isExported(String cmdName) {
for (String pattern : exportPatterns) {
opCount++;
if (stringMatch(cmdName, pattern)) {
return true;
}
}
return false;
}
/**
* Simulate Tcl_Import with wildcard (imports all commands matching importPat
* that are also exported).
* Outer: O(C) hash iteration; inner: O(P) export check per command = O(C*P).
*/
int importAll(String importPat) {
int count = 0;
for (String cmdName : cmdTable.keySet()) {
if (stringMatch(cmdName, importPat)) {
if (isExported(cmdName)) { // O(P) per command
count++;
}
}
}
return count;
}
}
// --- FAST: HashSet cache of exported command names ---
static class FastNamespace {
Map<String, Object> cmdTable = new HashMap<>();
List<String> exportPatterns = new ArrayList<>();
Set<String> exportedCmdsCache = null; // null = needs rebuild
long opCount = 0;
void defineCommand(String name) {
cmdTable.put(name, new Object());
exportedCmdsCache = null; // invalidate on new command
}
void addExportPattern(String pattern) {
exportPatterns.add(pattern);
exportedCmdsCache = null; // invalidate on export change
}
/** Build the exported-commands cache once: O(C * P) total, amortized O(1) per lookup */
void buildExportCache() {
exportedCmdsCache = new HashSet<>();
for (String cmdName : cmdTable.keySet()) {
for (String pattern : exportPatterns) {
opCount++;
if (stringMatch(cmdName, pattern)) {
exportedCmdsCache.add(cmdName);
break;
}
}
}
}
/** Check if cmdName is exported: O(1) hash lookup */
boolean isExported(String cmdName) {
if (exportedCmdsCache == null) {
buildExportCache();
}
opCount++;
return exportedCmdsCache.contains(cmdName);
}
/**
* Simulate Tcl_Import: O(C) outer, O(1) inner after cache build.
* Cache is built once; subsequent imports are O(C).
*/
int importAll(String importPat) {
int count = 0;
for (String cmdName : cmdTable.keySet()) {
if (stringMatch(cmdName, importPat)) {
if (isExported(cmdName)) { // O(1) after cache
count++;
}
}
}
return count;
}
}
// --- Test harness ---
static int passed = 0;
static int total = 0;
static void check(String name, boolean cond) {
total++;
if (cond) {
passed++;
System.out.println(" PASS: " + name);
} else {
System.out.println(" FAIL: " + name);
}
}
public static void main(String[] args) {
System.out.println("=== tcl-0001: DoImport O(C*P) export pattern scan ===");
int C = 1000; // commands in source namespace (e.g., Tk, Itcl)
int P = 50; // export patterns
SlowNamespace slow = new SlowNamespace();
FastNamespace fast = new FastNamespace();
// Define C commands: half with "pub_" prefix (to be exported), half with "priv_"
for (int i = 0; i < C / 2; i++) {
slow.defineCommand("pub_cmd_" + i);
fast.defineCommand("pub_cmd_" + i);
}
for (int i = 0; i < C / 2; i++) {
slow.defineCommand("priv_cmd_" + i);
fast.defineCommand("priv_cmd_" + i);
}
// P export patterns: most export pub_cmd_* subsets
// First pattern matches everything with prefix "pub_cmd_"
slow.addExportPattern("pub_cmd_*");
fast.addExportPattern("pub_cmd_*");
// Add P-1 more specific patterns (won't match much, but still scanned)
for (int i = 1; i < P; i++) {
slow.addExportPattern("special_" + i + "_*");
fast.addExportPattern("special_" + i + "_*");
}
// First import: correctness check
int slowCount = slow.importAll("*");
int fastCount = fast.importAll("*");
check("slow imports correct count (" + (C/2) + ")", slowCount == C / 2);
check("fast imports correct count (" + (C/2) + ")", fastCount == C / 2);
check("slow and fast agree", slowCount == fastCount);
// Correctness: specific commands
check("slow: pub_cmd_0 is exported", slow.isExported("pub_cmd_0"));
check("fast: pub_cmd_0 is exported", fast.isExported("pub_cmd_0"));
check("slow: priv_cmd_0 is NOT exported", !slow.isExported("priv_cmd_0"));
check("fast: priv_cmd_0 is NOT exported", !fast.isExported("priv_cmd_0"));
// Op count comparison: measure 10 repeated imports (cache warm for fast)
slow.opCount = 0;
fast.opCount = 0;
fast.exportedCmdsCache = null; // start fresh
int importRuns = 10;
for (int r = 0; r < importRuns; r++) {
slow.importAll("*");
fast.importAll("*");
}
long slowOps = slow.opCount;
long fastOps = fast.opCount;
double ratio = (double) slowOps / fastOps;
System.out.println();
System.out.printf("C=%d commands, P=%d export patterns, %d import calls:%n", C, P, importRuns);
System.out.printf(" SLOW ops (linear pattern scan per cmd): %,d%n", slowOps);
System.out.printf(" FAST ops (cache build once + O(1) lookups): %,d%n", fastOps);
System.out.printf(" Ratio: %.1fx%n", ratio);
// SLOW: O(C*P) per call × 10 calls (early exit on first match for half, full scan for other half)
check("slow ops >= C*importRuns", slowOps >= (long) C * importRuns);
// FAST: O(C*P) once for cache build, then O(C) per subsequent import
// Total fast C*P + (importRuns-1)*C
check("fast ops <= (C*P + importRuns*C*2)", fastOps <= (long)(C * P + importRuns * C * 2));
check("ratio >= 5x", ratio >= 5.0);
// Additional: multiple imports reuse cache (fast stays O(C), slow stays O(C*P))
slow.opCount = 0;
fast.opCount = 0;
int imports = 10;
for (int i = 0; i < imports; i++) {
slow.importAll("*");
fast.importAll("*");
}
long slowOps2 = slow.opCount;
long fastOps2 = fast.opCount;
double ratio2 = (double) slowOps2 / fastOps2;
System.out.printf("%nAfter %d repeated imports (cache hot for fast):%n", imports);
System.out.printf(" SLOW ops: %,d%n", slowOps2);
System.out.printf(" FAST ops: %,d%n", fastOps2);
System.out.printf(" Ratio: %.1fx%n", ratio2);
check("repeated import ratio >= 10x", ratio2 >= 10.0);
System.out.println();
System.out.println(passed + "/" + total + " PASS");
if (passed != total) {
System.exit(1);
}
}
}