-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathStatementExecutor.java
More file actions
83 lines (74 loc) · 2.76 KB
/
StatementExecutor.java
File metadata and controls
83 lines (74 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package sqlancer;
import java.util.ArrayList;
import java.util.List;
import sqlancer.common.query.Query;
public class StatementExecutor<G extends GlobalState<?, ?, ?>, A extends AbstractAction<G>> {
private final G globalState;
private final A[] actions;
private final ActionMapper<G, A> mapping;
private final AfterQueryAction queryConsumer;
@FunctionalInterface
public interface AfterQueryAction {
void notify(Query<?> q) throws Exception;
}
@FunctionalInterface
public interface ActionMapper<T, A> {
int map(T globalState, A action);
}
public StatementExecutor(G globalState, A[] actions, ActionMapper<G, A> mapping, AfterQueryAction queryConsumer) {
this.globalState = globalState;
this.actions = actions.clone();
this.mapping = mapping;
this.queryConsumer = queryConsumer;
}
@SuppressWarnings("unchecked")
public void executeStatements() throws Exception {
Randomly r = globalState.getRandomly();
int[] nrRemaining = new int[actions.length];
List<A> availableActions = new ArrayList<>();
int total = 0;
for (int i = 0; i < actions.length; i++) {
A action = actions[i];
int nrPerformed = mapping.map(globalState, action);
if (nrPerformed != 0) {
availableActions.add(action);
}
nrRemaining[i] = nrPerformed;
total += nrPerformed;
}
while (total != 0) {
A nextAction = null;
int selection = r.getInteger(0, total);
int previousRange = 0;
int i;
for (i = 0; i < nrRemaining.length; i++) {
if (previousRange <= selection && selection < previousRange + nrRemaining[i]) {
nextAction = actions[i];
break;
} else {
previousRange += nrRemaining[i];
}
}
assert nextAction != null;
assert nrRemaining[i] > 0;
nrRemaining[i]--;
@SuppressWarnings("rawtypes")
Query query = null;
try {
boolean success;
int nrTries = 0;
do {
query = nextAction.getQuery(globalState);
success = globalState.executeStatement(query);
} while (nextAction.canBeRetried() && !success
&& nrTries++ < globalState.getOptions().getNrStatementRetryCount());
} catch (IgnoreMeException ignored) {
}
if (query != null && query.couldAffectSchema()) {
globalState.updateSchema();
queryConsumer.notify(query);
}
total--;
}
}
}