turn on local context cache.

This commit is contained in:
Terence Parr 2012-07-27 20:53:10 -07:00
parent 14372f2515
commit 8279c3da11
3 changed files with 41 additions and 60 deletions

View File

@ -144,7 +144,6 @@ import java.util.Set;
*/
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 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
use a hash table that lets us specify the equals/hashcode operation.
*/
public static class Key {
ATNState state;
int alt;
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);
public static class ConfigHashSet extends Array2DHashSet<ATNConfig> {
public ConfigHashSet() {
super(16,2);
}
@Override
public boolean equals(Object obj) {
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() {
public int hashCode(ATNConfig o) {
int hashCode = 7;
hashCode = 5 * hashCode + state.stateNumber;
hashCode = 5 * hashCode + alt;
hashCode = 5 * hashCode + semanticContext.hashCode();
hashCode = 31 * hashCode + o.state.stateNumber;
hashCode = 31 * hashCode + o.alt;
hashCode = 31 * hashCode + o.semanticContext.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) {
if ( a==null && b==null ) return true;
if ( a==null || b==null ) return false;
if ( a==b ) return true;
if ( a==null || b==null ) 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,11 +238,9 @@ public class ATNConfigSet implements Set<ATNConfig> {
if ( config.semanticContext!=SemanticContext.NONE ) {
hasSemanticContext = true;
}
Key key = new Key(config);
ATNConfig existing = configLookup.get(config);
if ( existing==null ) { // nothing there yet; easy, just add
configLookup.add(config);
configs.add(config); // track order here
ATNConfig existing = configLookup.put(config);
if ( existing==config ) { // we added this new one
configs.add(config); // track order here
return true;
}
// a previous (s,i,pi,_), merge with it and save result
@ -346,8 +318,8 @@ public class ATNConfigSet implements Set<ATNConfig> {
public boolean equals(Object o) {
// System.out.print("equals " + this + ", " + o+" = ");
ATNConfigSet other = (ATNConfigSet)o;
boolean same = configLookup!=null &&
configLookup.equals(other.configLookup) &&
boolean same = configs!=null &&
configs.equals(other.configs) && // includes stack context
this.fullCtx == other.fullCtx &&
this.uniqueAlt == other.uniqueAlt &&
this.conflictingAlts == other.conflictingAlts &&

View File

@ -206,7 +206,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
public int predictATN(@NotNull DFA dfa, @NotNull TokenStream input,
@Nullable ParserRuleContext<?> outerContext)
{
contextCache = new PredictionContextCache("predict ctx cache");
//contextCache = new PredictionContextCache("predict ctx cache");
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
if ( debug || debug_list_atn_decisions ) {
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);
boolean loopsSimulateTailRecursion = 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 =
computeStartState(dfa.atnStartState, outerContext,
greedy, loopsSimulateTailRecursion,
@ -312,7 +312,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
" 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);
contextCache = null;
// this adds edge even if next state is accept for

View File

@ -7,9 +7,9 @@ import java.util.Set;
/** Set impl with closed hashing (open addressing). */
public class Array2DHashSet<T> implements Set<T> {
public static final int INITAL_CAPACITY = 4;
public static final int INITAL_BUCKET_CAPACITY = 2;
public static final double LOAD_FACTOR = 0.8;
public static final int INITAL_CAPACITY = 16; // must be power of 2
public static final int INITAL_BUCKET_CAPACITY = 8;
public static final double LOAD_FACTOR = 0.75;
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 currentPrime = 1; // jump by 4 primes each expand or whatever
protected int initialBucketCapacity = INITAL_BUCKET_CAPACITY;
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. */
@ -33,12 +39,14 @@ public class Array2DHashSet<T> implements Set<T> {
protected T put_(T o) {
int b = getBucket(o);
T[] bucket = buckets[b];
// NEW BUCKET
if ( bucket==null ) {
buckets[b] = (T[])new Object[INITAL_BUCKET_CAPACITY];
buckets[b] = (T[])new Object[initialBucketCapacity];
buckets[b][0] = o;
n++;
return o;
}
// LOOK FOR IT IN BUCKET
for (int i=0; i<bucket.length; i++) {
T existing = bucket[i];
if ( existing==null ) { // empty slot; not there, add.
@ -46,14 +54,14 @@ public class Array2DHashSet<T> implements Set<T> {
n++;
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;
bucket = (T[])new Object[old.length * 2];
buckets[b] = bucket;
System.arraycopy(old, 0, bucket, 0, old.length);
bucket[old.length] = o;
bucket[old.length] = o; // add to end
n++;
return o;
}
@ -65,7 +73,7 @@ public class Array2DHashSet<T> implements Set<T> {
if ( bucket==null ) return null; // no bucket
for (T e : bucket) {
if ( e==null ) return null; // empty slot; not there
if ( e.equals(o) ) return e;
if ( equals(e,o) ) return e;
}
return null;
}
@ -83,7 +91,7 @@ public class Array2DHashSet<T> implements Set<T> {
if ( bucket==null ) continue;
for (T o : bucket) {
if ( o==null ) break;
h += o.hashCode();
h += hashCode(o);
}
}
return h;
@ -95,7 +103,8 @@ public class Array2DHashSet<T> implements Set<T> {
if ( !(o instanceof Array2DHashSet) || o==null ) return false;
Array2DHashSet<T> other = (Array2DHashSet<T>)o;
if ( other.size() != size() ) return false;
return containsAll(other);
boolean same = this.containsAll(other) && other.containsAll(this);
return same;
}
protected void expand() {
@ -209,7 +218,7 @@ public class Array2DHashSet<T> implements Set<T> {
for (int i=0; i<bucket.length; i++) {
T e = bucket[i];
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
// 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);