view src/clojure/lang/MethodImplCache.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line source
1 /**
2 * Copyright (c) Rich Hickey. All rights reserved.
3 * The use and distribution terms for this software are covered by the
4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 * which can be found in the file epl-v10.html at the root of this distribution.
6 * By using this software in any fashion, you are agreeing to be bound by
7 * the terms of this license.
8 * You must not remove this notice, or any other, from this software.
9 **/
11 /* rich Nov 8, 2009 */
13 package clojure.lang;
15 public final class MethodImplCache{
17 static public class Entry{
18 final public Class c;
19 final public IFn fn;
21 public Entry(Class c, IFn fn){
22 this.c = c;
23 this.fn = fn;
24 }
25 }
27 public final IPersistentMap protocol;
28 public final Keyword methodk;
29 public final int shift;
30 public final int mask;
31 public final Object[] table; //[class, entry. class, entry ...]
33 volatile Entry mre = null;
35 public MethodImplCache(IPersistentMap protocol, Keyword methodk){
36 this(protocol, methodk, 0, 0, RT.EMPTY_ARRAY);
37 }
39 public MethodImplCache(IPersistentMap protocol, Keyword methodk, int shift, int mask, Object[] table){
40 this.protocol = protocol;
41 this.methodk = methodk;
42 this.shift = shift;
43 this.mask = mask;
44 this.table = table;
45 }
47 public IFn fnFor(Class c){
48 Entry last = mre;
49 if(last != null && last.c == c)
50 return last.fn;
51 return findFnFor(c);
52 }
54 IFn findFnFor(Class c){
55 int idx = ((Util.hash(c) >> shift) & mask) << 1;
56 if(idx < table.length && table[idx] == c)
57 {
58 Entry e = ((Entry) table[idx + 1]);
59 mre = e;
60 return e != null ? e.fn : null;
61 }
62 return null;
63 }
66 }