wave14a/c/d: 524/239 — rails-0018/grape-0001..3/django-0005..6/sqlalchemy-0003/go-stdlib-0001/vault-0001/tf-aws-0001
This commit is contained in:
parent
8f0bc73afa
commit
ac0e1e091e
20 changed files with 1948 additions and 21 deletions
220
defects/sqlalchemy/unit/EvaluatedKeysAlgorithm.java
Normal file
220
defects/sqlalchemy/unit/EvaluatedKeysAlgorithm.java
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* sqlalchemy-0003: evaluated_keys list → set in _apply_evaluators()
|
||||
*
|
||||
* Models SQLAlchemy bulk_persistence.py _apply_evaluators():
|
||||
* evaluated_keys = list(value_evaluators.keys())
|
||||
* then: c.key not in evaluated_keys (inside set comprehension over prefetch_cols)
|
||||
* and: .difference(evaluated_keys) (set subtraction)
|
||||
*
|
||||
* Fix: evaluated_keys = set(value_evaluators)
|
||||
*
|
||||
* Standalone Java — no JUnit required.
|
||||
*/
|
||||
public class EvaluatedKeysAlgorithm {
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Simulated column model
|
||||
// -----------------------------------------------------------------------
|
||||
static class Column {
|
||||
final String key;
|
||||
Column(String key) { this.key = key; }
|
||||
@Override public boolean equals(Object o) {
|
||||
return o instanceof Column && ((Column) o).key.equals(this.key);
|
||||
}
|
||||
@Override public int hashCode() { return key.hashCode(); }
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// SLOW: evaluated_keys as plain List
|
||||
// -----------------------------------------------------------------------
|
||||
static Result slowApplyEvaluators(Map<String, Object> valueEvaluators,
|
||||
List<Column> prefetchCols,
|
||||
List<Column> postfetchCols) {
|
||||
List<String> evaluatedKeys = new ArrayList<>(valueEvaluators.keySet()); // ← plain list
|
||||
|
||||
// to_prefetch: {c for c in prefetch_cols if c.key not in evaluated_keys}
|
||||
Set<Column> toPrefetch = new HashSet<>();
|
||||
for (Column c : prefetchCols) {
|
||||
if (!evaluatedKeys.contains(c.key)) { // ← O(K) scan
|
||||
toPrefetch.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
// to_expire = {col.key for col in postfetch_cols}.difference(evaluated_keys)
|
||||
Set<String> toExpire = new HashSet<>();
|
||||
for (Column c : postfetchCols) {
|
||||
toExpire.add(c.key);
|
||||
}
|
||||
toExpire.removeAll(evaluatedKeys); // removeAll(List) = O(P×K)
|
||||
|
||||
return new Result(toPrefetch, toExpire);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// FAST: evaluated_keys as HashSet
|
||||
// -----------------------------------------------------------------------
|
||||
static Result fastApplyEvaluators(Map<String, Object> valueEvaluators,
|
||||
List<Column> prefetchCols,
|
||||
List<Column> postfetchCols) {
|
||||
Set<String> evaluatedKeys = new HashSet<>(valueEvaluators.keySet()); // ← set (or just use valueEvaluators directly)
|
||||
|
||||
Set<Column> toPrefetch = new HashSet<>();
|
||||
for (Column c : prefetchCols) {
|
||||
if (!evaluatedKeys.contains(c.key)) { // ← O(1)
|
||||
toPrefetch.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> toExpire = new HashSet<>();
|
||||
for (Column c : postfetchCols) {
|
||||
toExpire.add(c.key);
|
||||
}
|
||||
toExpire.removeAll(evaluatedKeys); // removeAll(Set) = O(P)
|
||||
|
||||
return new Result(toPrefetch, toExpire);
|
||||
}
|
||||
|
||||
static class Result {
|
||||
final Set<Column> toPrefetch;
|
||||
final Set<String> toExpire;
|
||||
Result(Set<Column> toPrefetch, Set<String> toExpire) {
|
||||
this.toPrefetch = toPrefetch;
|
||||
this.toExpire = toExpire;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Test helpers
|
||||
// -----------------------------------------------------------------------
|
||||
static Map<String, Object> makeEvaluators(int n) {
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
m.put("eval_key_" + i, new Object());
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static List<Column> makeCols(int n, String prefix) {
|
||||
List<Column> cols = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
cols.add(new Column(prefix + i));
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Main
|
||||
// -----------------------------------------------------------------------
|
||||
public static void main(String[] args) {
|
||||
int passed = 0;
|
||||
int total = 0;
|
||||
|
||||
// ---- Correctness: basic case ----
|
||||
{
|
||||
Map<String, Object> evals = new LinkedHashMap<>();
|
||||
evals.put("col_a", new Object());
|
||||
evals.put("col_b", new Object());
|
||||
|
||||
List<Column> prefetch = Arrays.asList(
|
||||
new Column("col_a"), // in evaluatedKeys → NOT in toPrefetch
|
||||
new Column("col_c"), // not in evaluatedKeys → in toPrefetch
|
||||
new Column("col_d") // not in evaluatedKeys → in toPrefetch
|
||||
);
|
||||
List<Column> postfetch = Arrays.asList(
|
||||
new Column("col_a"), // in evaluatedKeys → NOT in toExpire
|
||||
new Column("col_b"), // in evaluatedKeys → NOT in toExpire
|
||||
new Column("col_e") // not in evaluatedKeys → in toExpire
|
||||
);
|
||||
|
||||
Result slow = slowApplyEvaluators(evals, prefetch, postfetch);
|
||||
Result fast = fastApplyEvaluators(evals, prefetch, postfetch);
|
||||
|
||||
total++;
|
||||
assert slow.toPrefetch.size() == fast.toPrefetch.size()
|
||||
: "toPrefetch size: slow=" + slow.toPrefetch.size() + " fast=" + fast.toPrefetch.size();
|
||||
assert slow.toExpire.size() == fast.toExpire.size()
|
||||
: "toExpire size: slow=" + slow.toExpire.size() + " fast=" + fast.toExpire.size();
|
||||
assert slow.toPrefetch.size() == 2 : "expected 2 in toPrefetch, got " + slow.toPrefetch.size();
|
||||
assert slow.toExpire.size() == 1 : "expected 1 in toExpire, got " + slow.toExpire.size();
|
||||
System.out.println("PASS 1/4: correctness basic case");
|
||||
passed++;
|
||||
}
|
||||
|
||||
// ---- Correctness: empty evaluators ----
|
||||
{
|
||||
Map<String, Object> evals = new HashMap<>();
|
||||
List<Column> prefetch = Arrays.asList(new Column("c1"), new Column("c2"));
|
||||
List<Column> postfetch = Arrays.asList(new Column("c3"));
|
||||
|
||||
Result slow = slowApplyEvaluators(evals, prefetch, postfetch);
|
||||
Result fast = fastApplyEvaluators(evals, prefetch, postfetch);
|
||||
|
||||
total++;
|
||||
assert slow.toPrefetch.size() == fast.toPrefetch.size() : "empty evals toPrefetch mismatch";
|
||||
assert slow.toExpire.size() == fast.toExpire.size() : "empty evals toExpire mismatch";
|
||||
// When no evaluators, all cols go to prefetch, all to expire
|
||||
assert slow.toPrefetch.size() == 2 : "expected 2 prefetch";
|
||||
assert slow.toExpire.size() == 1 : "expected 1 expire";
|
||||
System.out.println("PASS 2/4: correctness empty evaluators");
|
||||
passed++;
|
||||
}
|
||||
|
||||
// ---- Performance: N=1000 evaluated keys, 2000 cols ----
|
||||
{
|
||||
int K = 1000;
|
||||
int C = 2000;
|
||||
Map<String, Object> evals = makeEvaluators(K);
|
||||
// half prefetch cols are in evaluated keys
|
||||
List<Column> prefetch = new ArrayList<>();
|
||||
for (int i = 0; i < C/2; i++) prefetch.add(new Column("eval_key_" + i));
|
||||
for (int i = 0; i < C/2; i++) prefetch.add(new Column("other_" + i));
|
||||
|
||||
List<Column> postfetch = new ArrayList<>();
|
||||
for (int i = 0; i < C/2; i++) postfetch.add(new Column("eval_key_" + i));
|
||||
for (int i = 0; i < C/2; i++) postfetch.add(new Column("post_" + i));
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
for (int iter = 0; iter < 10; iter++) slowApplyEvaluators(evals, prefetch, postfetch);
|
||||
long slowNs = (System.nanoTime() - t0) / 10;
|
||||
|
||||
long t1 = System.nanoTime();
|
||||
for (int iter = 0; iter < 10; iter++) fastApplyEvaluators(evals, prefetch, postfetch);
|
||||
long fastNs = (System.nanoTime() - t1) / 10;
|
||||
|
||||
double ratio = (double) slowNs / fastNs;
|
||||
total++;
|
||||
System.out.printf("PERF 3/4: sqlalchemy-0003 K=%d C=%d slow=%dms fast=%dms ratio=%.1fx%n",
|
||||
K, C, slowNs/1_000_000, fastNs/1_000_000, ratio);
|
||||
assert ratio >= 5.0 : "ratio too low: " + ratio;
|
||||
System.out.println("PASS 3/4: sqlalchemy-0003 ratio >= 5x");
|
||||
passed++;
|
||||
}
|
||||
|
||||
// ---- Edge case: all cols in evaluated_keys ----
|
||||
{
|
||||
Map<String, Object> evals = makeEvaluators(50);
|
||||
List<Column> prefetch = new ArrayList<>();
|
||||
List<Column> postfetch = new ArrayList<>();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
prefetch.add(new Column("eval_key_" + i));
|
||||
postfetch.add(new Column("eval_key_" + i));
|
||||
}
|
||||
|
||||
Result slow = slowApplyEvaluators(evals, prefetch, postfetch);
|
||||
Result fast = fastApplyEvaluators(evals, prefetch, postfetch);
|
||||
|
||||
total++;
|
||||
assert slow.toPrefetch.isEmpty() && fast.toPrefetch.isEmpty() : "all-in-evals toPrefetch not empty";
|
||||
assert slow.toExpire.isEmpty() && fast.toExpire.isEmpty() : "all-in-evals toExpire not empty";
|
||||
System.out.println("PASS 4/4: edge case all cols in evaluated_keys");
|
||||
passed++;
|
||||
}
|
||||
|
||||
System.out.printf("%n%d/%d PASS%n", passed, total);
|
||||
if (passed < total) throw new AssertionError("Some tests failed");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue