From 8279c3da11fce5343b440dd4d969faebb1cf43cf Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Fri, 27 Jul 2012 20:53:10 -0700 Subject: [PATCH] turn on local context cache. --- .../antlr/v4/runtime/atn/ATNConfigSet.java | 62 +++++-------------- .../v4/runtime/atn/ParserATNSimulator.java | 6 +- .../antlr/v4/runtime/misc/Array2DHashSet.java | 33 ++++++---- 3 files changed, 41 insertions(+), 60 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java index f43a4574e..68396b246 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java @@ -144,7 +144,6 @@ import java.util.Set; */ public class ATNConfigSet implements Set { - // 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 { 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 { + 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 { - 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 { 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 { 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 && diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index 850b0115d..822c1d318 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -206,7 +206,7 @@ public class ParserATNSimulator 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 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 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 diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/Array2DHashSet.java b/runtime/Java/src/org/antlr/v4/runtime/misc/Array2DHashSet.java index b431c2366..ca5fcfbe4 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/Array2DHashSet.java +++ b/runtime/Java/src/org/antlr/v4/runtime/misc/Array2DHashSet.java @@ -7,9 +7,9 @@ import java.util.Set; /** Set impl with closed hashing (open addressing). */ public class Array2DHashSet implements Set { - 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 implements Set { 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 implements Set { 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 implements Set { 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 implements Set { 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 implements Set { 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 implements Set { if ( !(o instanceof Array2DHashSet) || o==null ) return false; Array2DHashSet other = (Array2DHashSet)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 implements Set { for (int i=0; i