diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/APersistentArray.java | 102 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArray.java | 558 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArrayList.java | 119 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashtableMap.java | 289 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentQueue.java | 27 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 49 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Tuple.java | 88 |
8 files changed, 63 insertions, 1173 deletions
diff --git a/src/jvm/clojure/lang/APersistentArray.java b/src/jvm/clojure/lang/APersistentArray.java deleted file mode 100644 index 9047296c..00000000 --- a/src/jvm/clojure/lang/APersistentArray.java +++ /dev/null @@ -1,102 +0,0 @@ -/**
- * Copyright (c) Rich Hickey. All rights reserved.
- * The use and distribution terms for this software are covered by the
- * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
- * which can be found in the file CPL.TXT at the root of this distribution.
- * By using this software in any fashion, you are agreeing to be bound by
- * the terms of this license.
- * You must not remove this notice, or any other, from this software.
- **/
-
-package clojure.lang;
-
-public abstract class APersistentArray extends Obj implements IPersistentArray, Cloneable{
-int _hash = -1;
-
-public IPersistentCollection cons(Object o){
- PersistentArrayList ret = new PersistentArrayList(this, this.count() + 10);
- ret = ret.cons(o);
- //!ret._meta = _meta;
- return ret;
-}
-
-
-public boolean equals(Object obj){
- if(obj instanceof IPersistentArray)
- {
- IPersistentArray ma = (IPersistentArray) obj;
- if(ma.count() != count() || ma.hashCode() != hashCode())
- return false;
- for(int i = 0; i < count(); i++)
- {
- if(!RT.equal(nth(i), ma.nth(i)))
- return false;
- }
- }
- else
- {
- if(!(obj instanceof Sequential))
- return false;
- ISeq ms = ((IPersistentCollection) obj).seq();
- for(int i = 0; i < count(); i++, ms = ms.rest())
- {
- if(ms == null || !RT.equal(nth(i), ms.first()))
- return false;
- }
- if(ms.rest() != null)
- return false;
- }
-
- return true;
-}
-
-public int hashCode(){
- if(_hash == -1)
- {
- int hash = 0;
- for(int i = 0; i < count(); i++)
- {
- hash = RT.hashCombine(hash, RT.hash(nth(i)));
- }
- this._hash = hash;
- }
- return _hash;
-}
-
-
-public boolean contains(Object key){
- if(!(key instanceof Number))
- return false;
- int i = ((Number) key).intValue();
- return i >= 0 && i < count();
-}
-
-public IMapEntry entryAt(Object key){
- if(key instanceof Number)
- {
- int i = ((Number) key).intValue();
- if(i >= 0 && i < count())
- return new MapEntry(key, nth(i));
- }
- return null;
-}
-
-public Associative assoc(Object key, Object val){
- if(key instanceof Number)
- {
- int i = ((Number) key).intValue();
- return (Associative) assocN(i, val);
- }
- throw new IllegalAccessError("Key must be integer");
-}
-
-public Object valAt(Object key){
- if(key instanceof Number)
- {
- int i = ((Number) key).intValue();
- if(i >= 0 && i < count())
- return nth(i);
- }
- return null;
-}
-}
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index a0e59906..69ba89ef 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -832,13 +832,13 @@ private static Expr analyzeLetFn(C context, ISeq form) throws Exception{ LocalBinding lb = new LocalBinding(baseSymbol(fsym)); lb.typeHint = typeHint(fsym); registerLocal(lb); - bindingPairs = bindingPairs.cons(new Tuple(lb, RT.cons(FN, RT.rest(bform)))); + bindingPairs = bindingPairs.cons(PersistentVector.create(lb, RT.cons(FN, RT.rest(bform)))); } PersistentArrayList bindingInits = new PersistentArrayList(4); for(int i = 0; i < bindingPairs.count(); i++) { - Tuple bpair = (Tuple) bindingPairs.nth(i); + IPersistentArray bpair = (IPersistentArray) bindingPairs.nth(i); LocalBinding lb = (LocalBinding) bpair.nth(0); FnExpr fexpr = (FnExpr) analyze(C.EXPRESSION, bpair.nth(1)); fexpr.binding = lb; diff --git a/src/jvm/clojure/lang/PersistentArray.java b/src/jvm/clojure/lang/PersistentArray.java deleted file mode 100644 index f6e6ace1..00000000 --- a/src/jvm/clojure/lang/PersistentArray.java +++ /dev/null @@ -1,558 +0,0 @@ -/** - * Copyright (c) Rich Hickey. All rights reserved. - * The use and distribution terms for this software are covered by the - * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) - * which can be found in the file CPL.TXT at the root of this distribution. - * By using this software in any fashion, you are agreeing to be bound by - * the terms of this license. - * You must not remove this notice, or any other, from this software. - **/ - -/* rich Jun 2, 2006 */ - -package clojure.lang; - -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.BitSet; -import java.util.Iterator; -import java.util.Vector; -import java.util.Random; - -/** - * Note that instances of this class are constant values - * i.e. set() returns a new array, old one is intact - * - * Multiple revisions (thread-safely) share the same master array - * - * Constant time most-recent-revision lookups - * Amortized constant-time sequential revisions (when loadFactor > 1) - * where a sequential revision is a revision of the most recent revision - * - * Non-sequential revisions are O(length), but with a small constant multiplier of 1/32 - * Worst-case O(r) lookups for oldest revs where r is number of revisions - * at index i since last (automatic or manual) isolate. If set()s are roughly evenly - * distributed, r should be approximately == loadFactor, i.e. constant - * In pathological case (all mods to same index), r == (loadFactor * length) - * - * (loadFactor * length) old values are retained, even if the array revisions aren't - * Default loadFactor is 2.1 - * When the load exceeds (loadFactor * length) the next revision is automatically isolated - * You can determine how many values are in the shared master by calling load() - * and can trim them by calling isolate() or resize(), which yield a new array with no - * sharing and no old values - * - * See Cohen for basic idea - * I added hybrid most-recent-sequential-range + shared-bitset idea, multi-thread-safety - */ - -public class PersistentArray extends APersistentArray implements Iterable { - -public Iterator iterator(){ - return new ValIter(this); -} - -public ISeq seq() { - if(length() > 0) - return new Seq(this, 0); - return null; -} - -public ISeq rseq() { - if(count() > 0) - return new RSeq(this, count()-1); - return null; -} - -static class Master{ - final Entry[] array; - final Object defaultVal; - int rev; - int load; - final int maxLoad; - final float loadFactor; - final int[] basis; - Master next; - - Master(int size,Object defaultVal, float loadFactor, int[] basis){ - this.array = new Entry[size];//new AtomicReferenceArray(size); - this.defaultVal = defaultVal; - this.rev = 0;//new AtomicInteger(0); - this.load = 0;//new AtomicInteger(0); - this.maxLoad = (int) (size * loadFactor); - this.loadFactor = loadFactor; - this.basis = basis; - next = null; - } - - Master(Master parent){ - this.array = new Entry[parent.array.length]; - this.defaultVal = parent.defaultVal; - this.rev = 0; - this.load = 0; - this.maxLoad = parent.maxLoad; - this.loadFactor = parent.loadFactor; - this.next = null; - - this.basis = new int[parent.array.length]; - } -} - -static class Entry{ - final int rev; - final Object val; - - Entry(int rev,Object val){ - this.rev = rev; - this.val = val; - } - - Entry rest(){ - return null; - } - - static Entry create(int rev,Object val,Entry rest){ - if(rest == null) - return new Entry(rev,val); - return new EntryLink(rev, val, rest); - } -} - -static class EntryLink extends Entry{ - final Entry _rest; - - EntryLink(int rev,Object val,Entry rest){ - super(rev,val); - this._rest = rest; - } - - Entry rest(){ - return _rest; - } -} - -static class Seq extends ASeq implements IndexedSeq{ - final PersistentArray p; - final int i; - - Seq(PersistentArray p, int i){ - this.p = p; - this.i = i; - } - - public Object first() { - return p.nth(i); - } - - public ISeq rest() { - if(i+1 < p.length()) - return new Seq(p, i + 1); - return null; - } - - public int index() { - return i; - } - - public int count() { - return p.count() - i; - } -} - -static class RSeq extends ASeq implements IndexedSeq{ - final PersistentArray p; - final int i; - - RSeq(PersistentArray p, int i){ - this.p = p; - this.i = i; - } - - public Object first() { - return p.nth(i); - } - - public ISeq rest() { - if(i > 0) - return new RSeq(p, i - 1); - return null; - } - - public int index() { - return i; - } - - public int count() { - return i + 1; - } -} - -static class ValIter implements Iterator{ - PersistentArray p; - int i; - - ValIter(PersistentArray p){ - this.p = p; - this.i = 0; - } - - public boolean hasNext(){ - return i < p.length(); - } - - public Object next(){ - return p.nth(i++); - } - - public void remove(){ - throw new UnsupportedOperationException(); - } -} - -static class Data{ -final Master master; -final int rev; -final int baseline; -final BitSet history; - - public Data(Master master, int rev, int baseline, BitSet history) { - this.master = master; - this.rev = rev; - this.baseline = baseline; - this.history = history; - } -} - -volatile Data data; - -public PersistentArray(int size){ - this(size, (Object)null); -} - -public PersistentArray(int size, Object defaultVal){ - this(size,defaultVal,2.1f); -} - -public PersistentArray(int size, Object defaultVal, float loadFactor){ - this.data = new Data(new Master(size, defaultVal,loadFactor,null),0,0,null); -} - -PersistentArray(Master master,int rev,int baseline, BitSet history){ - this.data = new Data(master,rev,baseline,history); -} - -public PersistentArray(int size, ISeq seq) throws Exception { - this(size); - int load = 0; - for(int i=0;seq != null && i < size;i++, seq=seq.rest()) - { - data.master.array[i] = new Entry(0,seq.first()); - ++load; - } - - data.master.load = load; -} - -public PersistentArray(IPersistentArray init) { - this(init.length()); - int load = 0; - for(int i=0;i < init.length();i++) - { - data.master.array[i] = new Entry(0,init.nth(i)); - ++load; - } - - data.master.load = load; -} - -public PersistentArray(IPersistentArray init, int size) { - this(size); - int load = 0; - for(int i=0;i < init.length() && i < size;i++) - { - data.master.array[i] = new Entry(0,init.nth(i)); - ++load; - } - - data.master.load = load; -} - -public int count(){ - return data.master.array.length; -} - -public int length(){ - return data.master.array.length; -} - -public Object nth(int i) { - Entry e = getEntry(i); - if(e != null) - return e.val; - return data.master.defaultVal; -} - -final public boolean has(int i){ - return getEntry(i) != null; -} - -final public PersistentArray resize(int newLength) { - PersistentArray ret = create(newLength, data.master.defaultVal, data.master.loadFactor); - int load = 0; - for(int i=0;i< Math.min(length(),newLength);i++) - { - Entry e = getEntry(i); - if(e != null) - { - ret.data.master.array[i] = new Entry(0,e.val); - ++load; - } - } - - ret.data.master.load = load; - - return ret; -} - -/** - * - * @return number of values (of all revisions) stored in shared array - */ -final public int load(){ - return data.master.load; -} - -final public void isolate() { - synchronized(data.master) - { - Master nextMaster = new Master(data.master); - int load = 0; - for(int i=0;i<length();i++) - { - Entry entry = getEntry(i); - if(entry != null) - { - nextMaster.array[i] = new Entry(0,entry.val); - ++load; - } - } - nextMaster.load = load; - this.data = new Data(nextMaster, 0, 0, null); - } -} - -private Entry getEntry(int i){ - for(Entry e = data.master.array[i];e != null;e = e.rest()) - { - if(e.rev <= data.rev) - { - if(e.rev >= data.baseline - || (data.history != null && data.history.get(e.rev))) - return e; - } - } - return null; -} - -public PersistentArray assocN(int i,Object val) { - synchronized(data.master){ - if(data.master.load >= data.master.maxLoad) - trim(); - PersistentArray ret = getSetArray(); - ret.doSet(i, val); - return ret; - } -} - -protected void trim(){ - //must be called inside lock of master - if(data.master.next == null) //this master has never been trimmed - { - Master nextMaster = new Master(data.master); - int load = 0; - for(int i=0;i<length();i++) - { - Entry entry = getEntry(i); - if(entry != null) - { - nextMaster.array[i] = new Entry(0,entry.val); - nextMaster.basis[i] = entry.rev; - ++load; - } - } - nextMaster.load = load; - Data nextData = new Data(nextMaster, 0, 0, null); - data.master.next = nextMaster; - data = nextData; - } - else //this master has been trimmed, but this rev is not yet propagated - { - Master nextMaster = data.master.next; - int diff = 0; - for(int i=0;i<length()/2;i++) - { - Entry e = getEntry(i); - if(e != null && e.rev != nextMaster.basis[i]) - ++diff; - } - if(diff >= length()/2 || nextMaster.load + diff > nextMaster.maxLoad) - isolate(); - else - { - Data nextData; - synchronized(nextMaster){ - int rev = ++nextMaster.rev; - for(int i=0;i<length();i++) - { - Entry e = getEntry(i); - if(e != null && e.rev != nextMaster.basis[i]) - { - nextMaster.array[i] = Entry.create(rev, e.val, nextMaster.array[i]); - ++nextMaster.load; - } - } - BitSet history = new BitSet(rev); - history.set(0); - nextData = new Data(nextMaster,rev,rev,history); - } - this.data = nextData; - } - } -} - -public boolean equals(Object key){ - if(this == key) return true; - if(key == null || !(key instanceof IPersistentArray)) return false; - - final IPersistentArray a = (IPersistentArray) key; - - if(a.length() != length()) - return false; - - for(int i = 0; i < length(); i++) - { - if(!equalKey(nth(i),a.nth(i))) - return false; - } - - return true; -} - -public int hashCode(){ - int ret = 0; - for(int i = 0; i < length(); i++) - { - Object o = nth(i); - if(o != null) - ret ^= o.hashCode(); - } - return ret; -} - -private boolean equalKey(Object k1,Object k2){ - if(k1 == null) - return k2 == null; - return k1.equals(k2); -} - -private void doSet(int i, Object val){ - //must be called inside lock of master - data.master.array[i] = Entry.create(data.rev, val, data.master.array[i]); - ++data.master.load; -} - -private PersistentArray getSetArray(){ - //must be called inside lock of master - //is this a sequential update? - if(data.master.rev == data.rev) - { - return create(data.master, ++data.master.rev, data.baseline, data.history); - } - else //gap - { - int nextRev = ++data.master.rev; - BitSet nextHistory; - if(data.history != null) - nextHistory = (BitSet) data.history.clone(); - else - nextHistory = new BitSet(data.rev+1); - nextHistory.set(data.baseline,data.rev+1); - return create(data.master, nextRev, nextRev, nextHistory); - } - -} - -protected PersistentArray create(Master master,int rev,int baseline, BitSet history){ - PersistentArray ret = new PersistentArray(data.master, rev, baseline, history); - //!ret._meta = _meta; - return ret; -} - -protected PersistentArray create(int size, Object defaultVal, float loadFactor) { - PersistentArray ret = new PersistentArray(size, defaultVal, loadFactor); - //!ret._meta = _meta; - return ret; -} - -static public void main(String[] args){ - if(args.length != 3) - { - System.err.println("Usage: PersistentArray size writes reads"); - return; - } - int size = Integer.parseInt(args[0]); - int writes = Integer.parseInt(args[1]); - int reads = Integer.parseInt(args[2]); - Vector v = new Vector(size); - v.setSize(size); - //PersistentArray p = new PersistentArray(size); - PersistentArrayList p = new PersistentArrayList(size); - - for(int i = 0; i < size; i++) - { - v.set(i, 0); - //p = p.set(i, 0); - p = p.cons(0); - } - - Random rand; - - rand = new Random(42); - long tv = 0; - System.out.println("Vector"); - long startTime = System.nanoTime(); - for(int i = 0; i < writes; i++) - { - v.set(rand.nextInt(size), i); - } - for(int i = 0; i < reads; i++) - { - tv += (Integer)v.get(rand.nextInt(size)); - } - long estimatedTime = System.nanoTime() - startTime; - System.out.println("time: " + estimatedTime/1000000); - System.out.println("PersistentArray"); - rand = new Random(42); - startTime = System.nanoTime(); - long tp = 0; - - PersistentArray oldp = p; - Random rand2 = new Random(42); - - for(int i = 0; i < writes; i++) - { - p = p.assocN(rand.nextInt(size), i); - //dummy set to force perverse branching - oldp = oldp.assocN(rand2.nextInt(size), i); - } - for(int i = 0; i < reads; i++) - { - tp += (Integer)p.nth(rand.nextInt(size)); - } - estimatedTime = System.nanoTime() - startTime; - System.out.println("time: " + estimatedTime/1000000); - System.out.println("Done: " + tv + ", " + tp); - - -} -} diff --git a/src/jvm/clojure/lang/PersistentArrayList.java b/src/jvm/clojure/lang/PersistentArrayList.java deleted file mode 100644 index d4cda3a9..00000000 --- a/src/jvm/clojure/lang/PersistentArrayList.java +++ /dev/null @@ -1,119 +0,0 @@ -/**
- * Copyright (c) Rich Hickey. All rights reserved.
- * The use and distribution terms for this software are covered by the
- * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
- * which can be found in the file CPL.TXT at the root of this distribution.
- * By using this software in any fashion, you are agreeing to be bound by
- * the terms of this license.
- * You must not remove this notice, or any other, from this software.
- **/
-
-package clojure.lang;
-
-import java.util.BitSet;
-
-public class PersistentArrayList extends PersistentArray implements IPersistentList{
-
-int _count;
-
-public PersistentArrayList(int initialCapacity){
- super(initialCapacity);
- _count = 0;
-}
-
-PersistentArrayList(Master master,int rev,int baseline, BitSet history, int count){
- super(master,rev,baseline,history);
- this._count = count;
-}
-
-PersistentArrayList(int size, Object defaultVal, float loadFactor, int count) {
- super(size, defaultVal, loadFactor);
- this._count = count;
-}
-
-public PersistentArrayList(IPersistentArray init, int initialCapacity){
- super(init,initialCapacity);
- _count = Math.min(init.count(),initialCapacity);
-}
-
-public Object nth(int i) {
- if(i >= _count)
- throw new IndexOutOfBoundsException();
-
- return super.nth(i);
-}
-
-public PersistentArrayList assocN(int i,Object val) {
- if(i >= _count)
- throw new IndexOutOfBoundsException();
-
- return (PersistentArrayList) super.assocN(i, val);
-}
-
-public int length(){
- return _count;
-}
-
-public int count(){
- return _count;
-}
-
-public int capacity(){
- return data.master.array.length;
-}
-
-public PersistentArrayList cons(Object val) {
- if(_count == data.master.array.length) //full
- {
- synchronized(data.master){
- if(_count == data.master.array.length) //still full
- grow();
- }
- }
- PersistentArrayList ret = (PersistentArrayList) super.assocN(_count, val);
- ret._count = _count + 1;
- return ret;
-}
-
-public Object peek(){
- if(_count > 0)
- return nth(_count - 1);
- return null;
-}
-
-public PersistentArrayList pop() {
- if(_count == 0)
- throw new IllegalAccessError();
- PersistentArrayList ret = new PersistentArrayList(data.master, data.rev, data.baseline, data.history, _count - 1);
- //! ret._meta = _meta;
- return ret;
-}
-
-
-private void grow() {
- //must be called inside lock of master
- if(data.master.next != null) //this master has been trimmed, but this rev is not yet propagated
- trim();
-
- Master newMaster = new Master(data.master.array.length * 2, data.master.defaultVal, data.master.loadFactor
- ,data.master.basis);
- newMaster.rev = data.master.rev;
- newMaster.load = data.master.load;
- System.arraycopy(data.master.array, 0, newMaster.array, 0, data.master.array.length);
- this.data = new Data(newMaster,data.rev,data.baseline,data.history);
- //data.master = newMaster;
-}
-
-protected PersistentArray create(Master master,int rev,int baseline, BitSet history){
- PersistentArray ret = new PersistentArrayList(data.master, rev, baseline, history,_count);
- //!ret._meta = _meta;
- return ret;
-}
-
-protected PersistentArray create(int size, Object defaultVal, float loadFactor) {
- PersistentArray ret = new PersistentArrayList(size, defaultVal, loadFactor,_count);
- //!ret._meta = _meta;
- return ret;
-}
-
-}
diff --git a/src/jvm/clojure/lang/PersistentHashtableMap.java b/src/jvm/clojure/lang/PersistentHashtableMap.java deleted file mode 100644 index 02c7265c..00000000 --- a/src/jvm/clojure/lang/PersistentHashtableMap.java +++ /dev/null @@ -1,289 +0,0 @@ -/**
- * Copyright (c) Rich Hickey. All rights reserved.
- * The use and distribution terms for this software are covered by the
- * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
- * which can be found in the file CPL.TXT at the root of this distribution.
- * By using this software in any fashion, you are agreeing to be bound by
- * the terms of this license.
- * You must not remove this notice, or any other, from this software.
- **/
-
-package clojure.lang;
-
-import java.util.Iterator;
-import java.math.BigInteger;
-
-public class PersistentHashtableMap extends APersistentMap{
-
-static final float FILL_FACTOR = 0.75f;
-
-final PersistentArray array;
-final int _count;
-final int growAtCount;
-
-public PersistentHashtableMap(int initialCapacity){
- array = new PersistentArray(calcPrimeCapacity(initialCapacity));
- _count = 0;
- this.growAtCount = (int) (this.array.length() * FILL_FACTOR);
-}
-
-/**
- * @param init {key1,val1,key2,val2,...}
- */
-public PersistentHashtableMap(Object[] init){
- //start halfway to a rehash
- PersistentArray narray = new PersistentArray(calcPrimeCapacity(init.length));
- for(int i = 0; i < init.length; i += 2)
- {
- narray = doPut(bucketFor(init[i], narray), init[i], init[i + 1], narray);
- }
- this.array = narray;
- this._count = init.length / 2; //hmmm... presumes no dupe keys in init
- this.growAtCount = (int) (this.array.length() * FILL_FACTOR);
-}
-
-PersistentHashtableMap(int count, PersistentArray array){
- this._count = count;
- this.array = array;
- this.growAtCount = (int) (this.array.length() * FILL_FACTOR);
-}
-
-PersistentHashtableMap(int count, PersistentArray array, int growAt){
- this._count = count;
- this.array = array;
- this.growAtCount = growAt;
-}
-
-int calcPrimeCapacity(int capacity){
- return BigInteger.valueOf((long) (capacity / FILL_FACTOR)).nextProbablePrime().intValue();
-}
-
-public int count(){
- return _count;
-}
-
-public boolean contains(Object key){
- IPersistentMap entries = entriesFor(key);
- return entries != null && entries.contains(key);
-}
-
-public IMapEntry entryAt(Object key){
- IPersistentMap entries = entriesFor(key);
- if(entries != null)
- return entries.entryAt(key);
- return null;
-}
-
-public IPersistentMap assocEx(Object key, Object val) throws Exception{
- if(_count > growAtCount)
- return grow().assocEx(key, val);
- int i = bucketFor(key, array);
- int incr = 1;
- PersistentArray newArray = doAdd(i, key, val, array);
- return create(_count + incr, newArray, growAtCount);
-}
-
-public IPersistentMap assoc(Object key, Object val){
- if(_count > growAtCount)
- return grow().assoc(key, val);
- int i = bucketFor(key, array);
- int incr = 1;
- PersistentArray newArray = doPut(i, key, val, array);
- if(newArray == array)
- return this;
- if(array.nth(i) != null && ((IPersistentMap) newArray.nth(i)).count() ==
- ((IPersistentMap) array.nth(i)).count()) //key already there, no growth
- incr = 0;
- return create(_count + incr, newArray, growAtCount);
-}
-
-PersistentArray doPut(int i, Object key, Object val, PersistentArray array){
- IPersistentMap entries = (IPersistentMap) array.nth(i);
- IPersistentMap newEntries;
- if(entries != null)
- {
- newEntries = entries.assoc(key, val);
- if(newEntries == entries) //already there with same value, no op
- return array;
- }
- else
- newEntries = createEntryMap(key, val);
-
- return array.assocN(i, newEntries);
-}
-
-PersistentArray doAdd(int i, Object key, Object val, PersistentArray array) throws Exception{
- IPersistentMap entries = (IPersistentMap) array.nth(i);
- IPersistentMap newEntries;
- if(entries != null)
- {
- newEntries = entries.assocEx(key, val);
- }
- else
- newEntries = createEntryMap(key, val);
-
- return array.assocN(i, newEntries);
-}
-
-public IPersistentMap without(Object key){
- int i = bucketFor(key, array);
- IPersistentMap entries = (IPersistentMap) array.nth(i);
- if(entries != null)
- {
- IPersistentMap newEntries = entries.without(key);
- if(newEntries != entries)
- return create(_count - 1, array.assocN(i, newEntries));
- }
- //not there, no op
- return this;
-}
-
-public Object valAt(Object key){
- IPersistentMap entries = entriesFor(key);
- if(entries != null)
- return entries.valAt(key);
- return null;
-}
-
-public int capacity(){
- return array.length();
-}
-
-IPersistentMap grow(){
- PersistentArray newArray = new PersistentArray(calcPrimeCapacity(_count * 2));
- for(Object o : this)
- {
- IMapEntry e = (IMapEntry) o;
- newArray = doPut(bucketFor(e.key(), newArray), e.key(), e.val(), newArray);
- }
- return create(_count, newArray);
-}
-
-public Iterator iterator(){
- return new Iter(array);
-}
-
-public ISeq seq(){
- if(count() == 0)
- return null;
- return Seq.create(array, count());
-}
-
-static class Seq extends ASeq{
- final PersistentArray buckets;
- final int b;
- final ISeq e;
- final int cnt;
-
-
- static public Seq create(PersistentArray buckets, int cnt){
- return next(buckets, -1, null, cnt);
- }
-
- static Seq next(PersistentArray buckets, int b, ISeq e, int cnt){
- if(e != null && e.rest() != null)
- return new Seq(buckets, b, e.rest(), cnt);
- for(b = b + 1; b < buckets.length(); b++)
- {
- IPersistentCollection a = (IPersistentCollection) buckets.nth(b);
- if(a != null && a.seq() != null)
- return new Seq(buckets, b, a.seq(), cnt);
- }
- return null;
- }
-
- Seq(PersistentArray buckets, int b, ISeq e, int cnt){
- this.buckets = buckets;
- this.b = b;
- this.e = e;
- this.cnt = cnt;
- }
-
- public Object first(){
- return e.first();
- }
-
- public ISeq rest(){
- return next(buckets, b, e, cnt - 1);
- }
-
- public int count(){
- return cnt;
- }
-}
-
-static class Iter implements Iterator{
- PersistentArray buckets;
- int b;
- ISeq e;
-
- Iter(PersistentArray buckets){
- this.buckets = buckets;
- this.b = -1;
- nextBucket();
- }
-
- private void nextBucket(){
- e = null;
- for(b = b + 1; b < buckets.length(); b++)
- {
- IPersistentCollection a = (IPersistentCollection) buckets.nth(b);
- if(a != null && a.seq() != null)
- {
- e = a.seq();
- break;
- }
- }
- }
-
- public boolean hasNext(){
- return e != null;
- }
-
- public Object next(){
- ISeq ret = e;
- e = e.rest();
- if(e == null)
- nextBucket();
- return ret.first();
- }
-
- public void remove(){
- throw new UnsupportedOperationException();
- }
-}
-
-final IPersistentMap entriesFor(Object key){
- return (IPersistentMap) array.nth(bucketFor(key, array));
-}
-
-static int bucketFor(Object key, PersistentArray array){
- return (RT.hash(key) & 0x7fffffff) % array.length();
-}
-
-IPersistentMap create(int capacity){
- PersistentHashtableMap ret = new PersistentHashtableMap(capacity);
- //!ret._meta = _meta;
- return ret;
-}
-
-IPersistentMap create(int count, PersistentArray array){
- PersistentHashtableMap ret = new PersistentHashtableMap(count, array);
- //!ret._meta = _meta;
- return ret;
-}
-
-IPersistentMap create(int i, PersistentArray newArray, int growAtCount){
- PersistentHashtableMap ret = new PersistentHashtableMap(i, newArray, growAtCount);
- //!ret._meta = _meta;
- return ret;
-}
-
-
-IPersistentMap createEntryMap(Object key, Object val){
- return new MapEntry(key, val);
-// return PersistentListMap.create(key,val);
-// return new PersistentArrayMap(key,val);
-}
-
-}
diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java index 93cd460d..bacaa30e 100644 --- a/src/jvm/clojure/lang/PersistentQueue.java +++ b/src/jvm/clojure/lang/PersistentQueue.java @@ -12,7 +12,7 @@ package clojure.lang; import java.util.Queue;
import java.util.LinkedList;
-import java.util.concurrent.ConcurrentLinkedQueue;
+//import java.util.concurrent.ConcurrentLinkedQueue;
/**
* conses onto rear, peeks/pops from front
@@ -27,14 +27,14 @@ final public static PersistentQueue EMPTY = new PersistentQueue(null,null,null); //*
final ISeq f;
-final PersistentArrayList r;
-static final int INITIAL_REAR_SIZE = 4;
+final PersistentVector r;
+//static final int INITIAL_REAR_SIZE = 4;
int _hash = -1;
-PersistentQueue(ISeq f, PersistentArrayList r, IPersistentMap meta) {
- this.f = f;
- this.r = r;
- //!this._meta = meta;
+PersistentQueue(ISeq f, PersistentVector r, IPersi |