turn on local context cache.
This commit is contained in:
parent
14372f2515
commit
8279c3da11
|
@ -144,7 +144,6 @@ import java.util.Set;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class ATNConfigSet implements Set<ATNConfig> {
|
public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
// TODO: convert to long like Sam? use list and map from config to ctx?
|
|
||||||
/*
|
/*
|
||||||
The reason that we need this is because we don't want the hash map to use
|
The reason that we need this is because we don't want the hash map to use
|
||||||
the standard hash code and equals. We need all configurations with the same
|
the standard hash code and equals. We need all configurations with the same
|
||||||
|
@ -152,53 +151,28 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
the number of objects associated with ATNConfigs. The other solution is to
|
the number of objects associated with ATNConfigs. The other solution is to
|
||||||
use a hash table that lets us specify the equals/hashcode operation.
|
use a hash table that lets us specify the equals/hashcode operation.
|
||||||
*/
|
*/
|
||||||
public static class Key {
|
public static class ConfigHashSet extends Array2DHashSet<ATNConfig> {
|
||||||
ATNState state;
|
public ConfigHashSet() {
|
||||||
int alt;
|
super(16,2);
|
||||||
SemanticContext semanticContext;
|
|
||||||
|
|
||||||
public Key(ATNState state, int alt, SemanticContext semanticContext) {
|
|
||||||
this.state = state;
|
|
||||||
this.alt = alt;
|
|
||||||
this.semanticContext = semanticContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Key(ATNConfig c) {
|
|
||||||
this(c.state, c.alt, c.semanticContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public int hashCode(ATNConfig o) {
|
||||||
if ( obj==this ) return true;
|
|
||||||
if ( this.hashCode() != obj.hashCode() ) return false;
|
|
||||||
if ( !(obj instanceof Key) ) return false;
|
|
||||||
Key key = (Key)obj;
|
|
||||||
return this.state.stateNumber==key.state.stateNumber
|
|
||||||
&& this.alt==key.alt
|
|
||||||
&& this.semanticContext.equals(key.semanticContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hashCode = 7;
|
int hashCode = 7;
|
||||||
hashCode = 5 * hashCode + state.stateNumber;
|
hashCode = 31 * hashCode + o.state.stateNumber;
|
||||||
hashCode = 5 * hashCode + alt;
|
hashCode = 31 * hashCode + o.alt;
|
||||||
hashCode = 5 * hashCode + semanticContext.hashCode();
|
hashCode = 31 * hashCode + o.semanticContext.hashCode();
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class ConfigHashSet extends Array2DHashSet<ATNConfig> {
|
|
||||||
public int hashCode(ATNConfig o) {
|
|
||||||
return o.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(ATNConfig a, ATNConfig b) {
|
public boolean equals(ATNConfig a, ATNConfig b) {
|
||||||
if ( a==null && b==null ) return true;
|
|
||||||
if ( a==null || b==null ) return false;
|
|
||||||
if ( a==b ) return true;
|
if ( a==b ) return true;
|
||||||
|
if ( a==null || b==null ) return false;
|
||||||
if ( hashCode(a) != hashCode(b) ) return false;
|
if ( hashCode(a) != hashCode(b) ) return false;
|
||||||
return a.equals(b);
|
return a.state.stateNumber==b.state.stateNumber
|
||||||
|
&& a.alt==b.alt
|
||||||
|
&& b.semanticContext.equals(b.semanticContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,10 +238,8 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
if ( config.semanticContext!=SemanticContext.NONE ) {
|
if ( config.semanticContext!=SemanticContext.NONE ) {
|
||||||
hasSemanticContext = true;
|
hasSemanticContext = true;
|
||||||
}
|
}
|
||||||
Key key = new Key(config);
|
ATNConfig existing = configLookup.put(config);
|
||||||
ATNConfig existing = configLookup.get(config);
|
if ( existing==config ) { // we added this new one
|
||||||
if ( existing==null ) { // nothing there yet; easy, just add
|
|
||||||
configLookup.add(config);
|
|
||||||
configs.add(config); // track order here
|
configs.add(config); // track order here
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -346,8 +318,8 @@ public class ATNConfigSet implements Set<ATNConfig> {
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
// System.out.print("equals " + this + ", " + o+" = ");
|
// System.out.print("equals " + this + ", " + o+" = ");
|
||||||
ATNConfigSet other = (ATNConfigSet)o;
|
ATNConfigSet other = (ATNConfigSet)o;
|
||||||
boolean same = configLookup!=null &&
|
boolean same = configs!=null &&
|
||||||
configLookup.equals(other.configLookup) &&
|
configs.equals(other.configs) && // includes stack context
|
||||||
this.fullCtx == other.fullCtx &&
|
this.fullCtx == other.fullCtx &&
|
||||||
this.uniqueAlt == other.uniqueAlt &&
|
this.uniqueAlt == other.uniqueAlt &&
|
||||||
this.conflictingAlts == other.conflictingAlts &&
|
this.conflictingAlts == other.conflictingAlts &&
|
||||||
|
|
|
@ -206,7 +206,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
public int predictATN(@NotNull DFA dfa, @NotNull TokenStream input,
|
public int predictATN(@NotNull DFA dfa, @NotNull TokenStream input,
|
||||||
@Nullable ParserRuleContext<?> outerContext)
|
@Nullable ParserRuleContext<?> outerContext)
|
||||||
{
|
{
|
||||||
contextCache = new PredictionContextCache("predict ctx cache");
|
//contextCache = new PredictionContextCache("predict ctx cache");
|
||||||
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
|
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
|
||||||
if ( debug || debug_list_atn_decisions ) {
|
if ( debug || debug_list_atn_decisions ) {
|
||||||
System.out.println("predictATN decision "+dfa.decision+
|
System.out.println("predictATN decision "+dfa.decision+
|
||||||
|
@ -268,7 +268,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
||||||
boolean loopsSimulateTailRecursion = true;
|
boolean loopsSimulateTailRecursion = true;
|
||||||
boolean fullCtx = true;
|
boolean fullCtx = true;
|
||||||
contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||||
ATNConfigSet s0_closure =
|
ATNConfigSet s0_closure =
|
||||||
computeStartState(dfa.atnStartState, outerContext,
|
computeStartState(dfa.atnStartState, outerContext,
|
||||||
greedy, loopsSimulateTailRecursion,
|
greedy, loopsSimulateTailRecursion,
|
||||||
|
@ -312,7 +312,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
||||||
" at DFA state "+s.stateNumber);
|
" at DFA state "+s.stateNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
// contextCache = new PredictionContextCache("predict ctx cache built in execDFA");
|
||||||
alt = execATN(dfa, s, input, startIndex, outerContext);
|
alt = execATN(dfa, s, input, startIndex, outerContext);
|
||||||
contextCache = null;
|
contextCache = null;
|
||||||
// this adds edge even if next state is accept for
|
// this adds edge even if next state is accept for
|
||||||
|
|
|
@ -7,9 +7,9 @@ import java.util.Set;
|
||||||
/** Set impl with closed hashing (open addressing). */
|
/** Set impl with closed hashing (open addressing). */
|
||||||
public class Array2DHashSet<T> implements Set<T> {
|
public class Array2DHashSet<T> implements Set<T> {
|
||||||
|
|
||||||
public static final int INITAL_CAPACITY = 4;
|
public static final int INITAL_CAPACITY = 16; // must be power of 2
|
||||||
public static final int INITAL_BUCKET_CAPACITY = 2;
|
public static final int INITAL_BUCKET_CAPACITY = 8;
|
||||||
public static final double LOAD_FACTOR = 0.8;
|
public static final double LOAD_FACTOR = 0.75;
|
||||||
|
|
||||||
protected T[][] buckets;
|
protected T[][] buckets;
|
||||||
|
|
||||||
|
@ -19,9 +19,15 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
protected int threshold = (int)(INITAL_CAPACITY * LOAD_FACTOR); // when to expand
|
protected int threshold = (int)(INITAL_CAPACITY * LOAD_FACTOR); // when to expand
|
||||||
|
|
||||||
protected int currentPrime = 1; // jump by 4 primes each expand or whatever
|
protected int currentPrime = 1; // jump by 4 primes each expand or whatever
|
||||||
|
protected int initialBucketCapacity = INITAL_BUCKET_CAPACITY;
|
||||||
|
|
||||||
public Array2DHashSet() {
|
public Array2DHashSet() {
|
||||||
buckets = (T[][])new Object[INITAL_CAPACITY][];
|
this(INITAL_CAPACITY, INITAL_BUCKET_CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array2DHashSet(int initialCapacity, int initialBucketCapacity) {
|
||||||
|
buckets = (T[][])new Object[initialCapacity][];
|
||||||
|
this.initialBucketCapacity = initialBucketCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add o to set if not there; return existing value if already there. */
|
/** Add o to set if not there; return existing value if already there. */
|
||||||
|
@ -33,12 +39,14 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
protected T put_(T o) {
|
protected T put_(T o) {
|
||||||
int b = getBucket(o);
|
int b = getBucket(o);
|
||||||
T[] bucket = buckets[b];
|
T[] bucket = buckets[b];
|
||||||
|
// NEW BUCKET
|
||||||
if ( bucket==null ) {
|
if ( bucket==null ) {
|
||||||
buckets[b] = (T[])new Object[INITAL_BUCKET_CAPACITY];
|
buckets[b] = (T[])new Object[initialBucketCapacity];
|
||||||
buckets[b][0] = o;
|
buckets[b][0] = o;
|
||||||
n++;
|
n++;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
// LOOK FOR IT IN BUCKET
|
||||||
for (int i=0; i<bucket.length; i++) {
|
for (int i=0; i<bucket.length; i++) {
|
||||||
T existing = bucket[i];
|
T existing = bucket[i];
|
||||||
if ( existing==null ) { // empty slot; not there, add.
|
if ( existing==null ) { // empty slot; not there, add.
|
||||||
|
@ -46,14 +54,14 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
n++;
|
n++;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
if ( existing.equals(o) ) return existing;
|
if ( equals(existing,o) ) return existing; // found existing, quit
|
||||||
}
|
}
|
||||||
// full bucket, expand and add to end
|
// FULL BUCKET, expand and add to end
|
||||||
T[] old = bucket;
|
T[] old = bucket;
|
||||||
bucket = (T[])new Object[old.length * 2];
|
bucket = (T[])new Object[old.length * 2];
|
||||||
buckets[b] = bucket;
|
buckets[b] = bucket;
|
||||||
System.arraycopy(old, 0, bucket, 0, old.length);
|
System.arraycopy(old, 0, bucket, 0, old.length);
|
||||||
bucket[old.length] = o;
|
bucket[old.length] = o; // add to end
|
||||||
n++;
|
n++;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +73,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
if ( bucket==null ) return null; // no bucket
|
if ( bucket==null ) return null; // no bucket
|
||||||
for (T e : bucket) {
|
for (T e : bucket) {
|
||||||
if ( e==null ) return null; // empty slot; not there
|
if ( e==null ) return null; // empty slot; not there
|
||||||
if ( e.equals(o) ) return e;
|
if ( equals(e,o) ) return e;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +91,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
if ( bucket==null ) continue;
|
if ( bucket==null ) continue;
|
||||||
for (T o : bucket) {
|
for (T o : bucket) {
|
||||||
if ( o==null ) break;
|
if ( o==null ) break;
|
||||||
h += o.hashCode();
|
h += hashCode(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
|
@ -95,7 +103,8 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
if ( !(o instanceof Array2DHashSet) || o==null ) return false;
|
if ( !(o instanceof Array2DHashSet) || o==null ) return false;
|
||||||
Array2DHashSet<T> other = (Array2DHashSet<T>)o;
|
Array2DHashSet<T> other = (Array2DHashSet<T>)o;
|
||||||
if ( other.size() != size() ) return false;
|
if ( other.size() != size() ) return false;
|
||||||
return containsAll(other);
|
boolean same = this.containsAll(other) && other.containsAll(this);
|
||||||
|
return same;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void expand() {
|
protected void expand() {
|
||||||
|
@ -209,7 +218,7 @@ public class Array2DHashSet<T> implements Set<T> {
|
||||||
for (int i=0; i<bucket.length; i++) {
|
for (int i=0; i<bucket.length; i++) {
|
||||||
T e = bucket[i];
|
T e = bucket[i];
|
||||||
if ( e==null ) return false; // empty slot; not there
|
if ( e==null ) return false; // empty slot; not there
|
||||||
if ( e.equals(o) ) { // found it
|
if ( equals(e,(T)o) ) { // found it
|
||||||
// shift all elements to the right down one
|
// shift all elements to the right down one
|
||||||
// for (int j=i; j<bucket.length-1; j++) bucket[j] = bucket[j+1];
|
// for (int j=i; j<bucket.length-1; j++) bucket[j] = bucket[j+1];
|
||||||
System.arraycopy(bucket, i+1, bucket, i, bucket.length-i-1);
|
System.arraycopy(bucket, i+1, bucket, i, bucket.length-i-1);
|
||||||
|
|
Loading…
Reference in New Issue