diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-01-09 02:59:57 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-01-09 02:59:57 +0000 |
commit | 2a12d40a8e26af95b614fa420591039a37f06626 (patch) | |
tree | cfdb2f8b069d7a6c7ef45bac06d8ffa59dfa20e6 /src | |
parent | f7c87e059355badcfbc8d80c2ed6ab8acb3c1d73 (diff) |
added construct, resultset-seq, keyword fn, vars in namespace tables
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 23 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentStructMap.java | 89 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 24 |
3 files changed, 96 insertions, 40 deletions
diff --git a/src/boot.clj b/src/boot.clj index 6ac33e35..7c9b8b5a 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -95,6 +95,10 @@ ([name] (. clojure.lang.Symbol (intern name))) ([ns name] (. clojure.lang.Symbol (intern ns name)))) +(defn keyword + ([name] (. clojure.lang.Keyword (intern nil name))) + ([ns name] (. clojure.lang.Keyword (intern ns name)))) + (defn gensym ([] (thisfn "G__")) ([prefix-string] (. clojure.lang.Symbol (intern (strcat prefix-string (str (. clojure.lang.RT (nextID)))))))) @@ -952,6 +956,9 @@ (defn struct [s & inits] (. clojure.lang.PersistentStructMap (create s inits))) +(defn construct [s & vals] + (. clojure.lang.PersistentStructMap (construct s vals))) + (defn accessor [s key] (. clojure.lang.PersistentStructMap (getAccessor s key))) @@ -964,6 +971,17 @@ (defn load [rdr] (. clojure.lang.Compiler (load rdr))) +(defn resultset-seq [#^java.sql.ResultSet rs] + (let [rsmeta (. rs (getMetaData)) + idxs (range 1 (inc (. rsmeta (getColumnCount)))) + keys (map (comp keyword (memfn toLowerCase)) + (map (fn [i] (. rsmeta (getColumnName i))) idxs)) + row-struct (apply create-struct keys) + row-values (fn [] (map (fn [#^Integer i] (. rs (getObject i))) idxs)) + rows (fn [] + (when (. rs (next)) + (fnseq (apply construct row-struct (row-values)) thisfn)))] + (rows))) (def *exports* '(clojure @@ -983,7 +1001,7 @@ scan touch key val line-seq sort sort-by comparator - rseq sym name namespace locking .. -> + rseq sym keyword name namespace locking .. -> defmulti defmethod remove-method binding find-var ref deref commute alter set ensure sync ! @@ -1009,9 +1027,10 @@ max min bit-shift-left bit-shift-right bit-and bit-or bit-xor bit-not - defstruct struct accessor create-struct + defstruct struct accessor create-struct construct subvec false? true? *warn-on-reflection* + resultset-seq )) diff --git a/src/jvm/clojure/lang/PersistentStructMap.java b/src/jvm/clojure/lang/PersistentStructMap.java index 3ceba52c..28d46426 100644 --- a/src/jvm/clojure/lang/PersistentStructMap.java +++ b/src/jvm/clojure/lang/PersistentStructMap.java @@ -17,52 +17,71 @@ import java.util.Map; public class PersistentStructMap extends APersistentMap{ -final IPersistentMap keyslots; +public static class Def{ + final ISeq keys; + final IPersistentMap keyslots; + + Def(ISeq keys, IPersistentMap keyslots){ + this.keys = keys; + this.keyslots = keyslots; + } +} + +final Def def; final Object[] vals; final IPersistentMap ext; -static public IPersistentMap createSlotMap(ISeq keys){ +static public Def createSlotMap(ISeq keys){ if(keys == null) throw new IllegalArgumentException("Must supply keys"); - PersistentHashMap temp = PersistentHashMap.EMPTY; - for(ISeq s = keys; s != null; s = s.rest()) - { - temp = (PersistentHashMap) temp.assoc(s.first(), null); - } - int i = 0; PersistentHashMap ret = PersistentHashMap.EMPTY; - for(ISeq s = RT.keys(temp); s != null; s = s.rest(), i++) + int i=0; + for(ISeq s = keys; s != null; s = s.rest(),i++) + { ret = (PersistentHashMap) ret.assoc(s.first(), i); - return ret; + } + return new Def(keys,ret); } -static public PersistentStructMap create(IPersistentMap keyslots, ISeq init){ - Object[] vals = new Object[keyslots.count()]; +static public PersistentStructMap create(Def def, ISeq keyvals){ + Object[] vals = new Object[def.keyslots.count()]; IPersistentMap ext = PersistentHashMap.EMPTY; - for(; init != null; init = init.rest().rest()) + for(; keyvals != null; keyvals = keyvals.rest().rest()) { - if(init.rest() == null) - throw new IllegalArgumentException(String.format("No value supplied for key: %s", init.first())); - Object k = init.first(); - Object v = RT.second(init); - Map.Entry e = keyslots.entryAt(k); + if(keyvals.rest() == null) + throw new IllegalArgumentException(String.format("No value supplied for key: %s", keyvals.first())); + Object k = keyvals.first(); + Object v = RT.second(keyvals); + Map.Entry e = def.keyslots.entryAt(k); if(e != null) vals[(Integer) e.getValue()] = v; else ext = ext.assoc(k, v); } - return new PersistentStructMap(null, keyslots, vals, ext); + return new PersistentStructMap(null, def, vals, ext); +} + +static public PersistentStructMap construct(Def def, ISeq valseq){ + Object[] vals = new Object[def.keyslots.count()]; + IPersistentMap ext = PersistentHashMap.EMPTY; + for(int i=0;i<vals.length && valseq != null; valseq = valseq.rest(),i++) + { + vals[i] = valseq.first(); + } + if(valseq != null) + throw new IllegalArgumentException("Too many arguments to struct constructor"); + return new PersistentStructMap(null, def, vals, ext); } -static public IFn getAccessor(final IPersistentMap keyslots, Object key){ - Map.Entry e = keyslots.entryAt(key); +static public IFn getAccessor(final Def def, Object key){ + Map.Entry e = def.keyslots.entryAt(key); if(e != null) { final int i = (Integer) e.getValue(); return new AFn(){ public Object invoke(Object arg1) throws Exception{ PersistentStructMap m = (PersistentStructMap) arg1; - if(m.keyslots != keyslots) + if(m.def != def) throw new Exception("Accessor/struct mismatch"); return m.vals[i]; } @@ -71,10 +90,10 @@ static public IFn getAccessor(final IPersistentMap keyslots, Object key){ throw new IllegalArgumentException("Not a key of struct"); } -PersistentStructMap(IPersistentMap meta, IPersistentMap keys, Object[] vals, IPersistentMap ext){ +PersistentStructMap(IPersistentMap meta, Def def, Object[] vals, IPersistentMap ext){ super(meta); this.ext = ext; - this.keyslots = keys; + this.def = def; this.vals = vals; } @@ -82,15 +101,15 @@ PersistentStructMap(IPersistentMap meta, IPersistentMap keys, Object[] vals, IPe public Obj withMeta(IPersistentMap meta){ if(meta == _meta) return this; - return new PersistentStructMap(meta, keyslots, vals, ext); + return new PersistentStructMap(meta, def, vals, ext); } public boolean containsKey(Object key){ - return keyslots.containsKey(key) || ext.containsKey(key); + return def.keyslots.containsKey(key) || ext.containsKey(key); } public IMapEntry entryAt(Object key){ - Map.Entry e = keyslots.entryAt(key); + Map.Entry e = def.keyslots.entryAt(key); if(e != null) { return new MapEntry(key, vals[(Integer) e.getValue()]); @@ -99,19 +118,19 @@ public IMapEntry entryAt(Object key){ } public IPersistentMap assoc(Object key, Object val){ - Map.Entry e = keyslots.entryAt(key); + Map.Entry e = def.keyslots.entryAt(key); if(e != null) { int i = (Integer) e.getValue(); Object[] newVals = vals.clone(); newVals[i] = val; - return new PersistentStructMap(_meta, keyslots, newVals, ext); + return new PersistentStructMap(_meta, def, newVals, ext); } - return new PersistentStructMap(_meta, keyslots, vals, ext.assoc(key, val)); + return new PersistentStructMap(_meta, def, vals, ext.assoc(key, val)); } public Object valAt(Object key){ - Map.Entry e = keyslots.entryAt(key); + Map.Entry e = def.keyslots.entryAt(key); if(e != null) { return vals[(Integer) e.getValue()]; @@ -120,7 +139,7 @@ public Object valAt(Object key){ } public Object valAt(Object key, Object notFound){ - Map.Entry e = keyslots.entryAt(key); + Map.Entry e = def.keyslots.entryAt(key); if(e != null) { return vals[(Integer) e.getValue()]; @@ -135,13 +154,13 @@ public IPersistentMap assocEx(Object key, Object val) throws Exception{ } public IPersistentMap without(Object key) throws Exception{ - Map.Entry e = keyslots.entryAt(key); + Map.Entry e = def.keyslots.entryAt(key); if(e != null) throw new Exception("Can't remove struct key"); IPersistentMap newExt = ext.without(key); if(newExt == ext) return this; - return new PersistentStructMap(_meta, keyslots, vals, newExt); + return new PersistentStructMap(_meta, def, vals, newExt); } public Iterator iterator(){ @@ -154,7 +173,7 @@ public int count(){ } public ISeq seq(){ - return new Seq(null, RT.keys(keyslots), vals, 0, ext); + return new Seq(null, def.keys, vals, 0, ext); } static class Seq extends ASeq{ diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java index 3c1dd3f4..36ebd915 100644 --- a/src/jvm/clojure/lang/Var.java +++ b/src/jvm/clojure/lang/Var.java @@ -50,13 +50,17 @@ final public Symbol sym; boolean macroFlag = false; Symbol tag; -static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>(); +static ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>> namespaces = + new ConcurrentHashMap<String, ConcurrentHashMap<Symbol, Var>>(); + +//static ConcurrentHashMap<Symbol, Var> table = new ConcurrentHashMap<Symbol, Var>(); public static Var intern(Symbol sym, Object root){ return intern(sym, root, true); } public static Var intern(Symbol sym, Object root, boolean replaceRoot){ + ConcurrentHashMap<Symbol, Var> table = table(sym); Var dvout = table.get(sym); boolean present = dvout != null; @@ -79,6 +83,7 @@ public String toString(){ } public static Var intern(Symbol sym){ + ConcurrentHashMap<Symbol, Var> table = table(sym); Var dvout = table.get(sym); if(dvout != null) return dvout; @@ -90,13 +95,26 @@ public static Var intern(Symbol sym){ } public static void unintern(Symbol sym){ - table.remove(sym); + table(sym).remove(sym); } public static Var find(Symbol sym){ - return table.get(sym); + return table(sym).get(sym); +} + +static ConcurrentHashMap<Symbol, Var> table(Symbol sym){ + String name = sym.ns; + if(name == null) + throw new IllegalArgumentException("Var names must have namespace"); + ConcurrentHashMap<Symbol, Var> ns = namespaces.get(name); + if(ns != null) + return ns; + ConcurrentHashMap<Symbol, Var> newns = new ConcurrentHashMap<Symbol, Var>(); + ns = namespaces.putIfAbsent(name,newns); + return ns == null?newns:ns; } + public static Var create(){ return new Var(null); } |