summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-07-05 22:10:24 +0000
committerRich Hickey <richhickey@gmail.com>2007-07-05 22:10:24 +0000
commit7ee1a813d0c90a1bde3e8c341d3fc18ba0ad462e (patch)
tree356753ce646d759657b99122a28ff015ac62faca
parent4232de83a53e12741252d31aef9cecee5b8981da (diff)
persistent array cleanup
-rw-r--r--src/jvm/clojure/lang/APersistentArray.java102
-rw-r--r--src/jvm/clojure/lang/Compiler.java4
-rw-r--r--src/jvm/clojure/lang/PersistentArray.java558
-rw-r--r--src/jvm/clojure/lang/PersistentArrayList.java119
-rw-r--r--src/jvm/clojure/lang/PersistentHashtableMap.java289
-rw-r--r--src/jvm/clojure/lang/PersistentQueue.java27
-rw-r--r--src/jvm/clojure/lang/PersistentVector.java49
-rw-r--r--src/jvm/clojure/lang/Tuple.java88
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;