MCPcopy Index your code
hub / github.com/clojure/clojure / findAndCacheBestMethod

Method findAndCacheBestMethod

src/jvm/clojure/lang/MultiFn.java:161–222  ·  view source on GitHub ↗
(Object dispatchVal)

Source from the content-addressed store, hash-verified

159}
160
161private IFn findAndCacheBestMethod(Object dispatchVal) {
162 rw.readLock().lock();
163 Object bestValue;
164 IPersistentMap mt = methodTable;
165 IPersistentMap pt = preferTable;
166 Object ch = cachedHierarchy;
167 try
168 {
169 Map.Entry bestEntry = null;
170 for(Object o : getMethodTable())
171 {
172 Map.Entry e = (Map.Entry) o;
173 if(isA(ch, dispatchVal, e.getKey()))
174 {
175 if(bestEntry == null || dominates(ch, e.getKey(), bestEntry.getKey()))
176 bestEntry = e;
177 if(!dominates(ch, bestEntry.getKey(), e.getKey()))
178 throw new IllegalArgumentException(
179 String.format(
180 "Multiple methods in multimethod '%s' match dispatch value: %s -> %s and %s, and neither is preferred",
181 name, dispatchVal, e.getKey(), bestEntry.getKey()));
182 }
183 }
184 if(bestEntry == null)
185 {
186 bestValue = methodTable.valAt(defaultDispatchVal);
187 if(bestValue == null)
188 return null;
189 }
190 else
191 bestValue = bestEntry.getValue();
192 }
193 finally
194 {
195 rw.readLock().unlock();
196 }
197
198
199 //ensure basis has stayed stable throughout, else redo
200 rw.writeLock().lock();
201 try
202 {
203 if( mt == methodTable &&
204 pt == preferTable &&
205 ch == cachedHierarchy &&
206 cachedHierarchy == hierarchy.deref())
207 {
208 //place in cache
209 methodCache = methodCache.assoc(dispatchVal, bestValue);
210 return (IFn) bestValue;
211 }
212 else
213 {
214 resetCache();
215 return findAndCacheBestMethod(dispatchVal);
216 }
217 }
218 finally

Callers 1

getMethodMethod · 0.95

Calls 11

getMethodTableMethod · 0.95
isAMethod · 0.95
dominatesMethod · 0.95
resetCacheMethod · 0.95
lockMethod · 0.80
formatMethod · 0.80
valAtMethod · 0.65
derefMethod · 0.65
assocMethod · 0.65
getKeyMethod · 0.45
getValueMethod · 0.45

Tested by

no test coverage detected