diff options
-rw-r--r-- | src/jvm/clojure/runtime/ArrayMap.java | 169 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/HashtableMap.java | 280 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/IMap.java | 31 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/IdentityArrayMap.java | 27 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/IdentityHashtableMap.java | 38 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/ListMap.java | 252 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/PersistentHashMap.java | 101 | ||||
-rw-r--r-- | src/jvm/clojure/runtime/RBTree.java | 759 |
8 files changed, 0 insertions, 1657 deletions
diff --git a/src/jvm/clojure/runtime/ArrayMap.java b/src/jvm/clojure/runtime/ArrayMap.java deleted file mode 100644 index 49dec167..00000000 --- a/src/jvm/clojure/runtime/ArrayMap.java +++ /dev/null @@ -1,169 +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 org.clojure.runtime;
-
-import java.util.Iterator;
-
-/**
- * Simple implementation of persistent map on an array
-
- * Note that instances of this class are constant values
- * i.e. add/remove etc return new values
- *
- * Copies array on every change, so only appropriate for _very_small_ maps
- *
- * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find
- */
-
-public class ArrayMap implements IMap {
-
-final Object[] array;
-
-public ArrayMap(){
- this.array = RT.EMPTY_ARRAY;
-}
-
-/**
- * This ctor captures/aliases the passed array, so do not modify later
- * @param init {key1,val1,key2,val2,...}
- */
-public ArrayMap(Object[] init){
- this.array = init;
-}
-
-public int count() {
- return array.length/2;
-}
-
-public boolean contains(Object key){
- return indexOf(key) >= 0;
-}
-
-public IMapEntry find(Object key) {
- int i = indexOf(key);
- if(i >= 0)
- return new Iter(array,i);
- return null;
-}
-
-public IMap add(Object key) {
-
- return put(key,null);
-}
-
-public IMap put(Object key, Object val) {
- int i = indexOf(key);
- Object[] newArray;
- if(i >= 0) //already have key, same-sized replacement
- {
- if(array[i+1] == val) //no change, no op
- return this;
- newArray = array.clone();
- newArray[i+1] = val;
- }
- else //didn't have key, grow
- {
- newArray = new Object[array.length + 2];
- if(array.length > 0)
- System.arraycopy(array,0,newArray,2,array.length);
- newArray[0] = key;
- newArray[1] = val;
- }
- return new ArrayMap(newArray);
-}
-
-public IMap remove(Object key) {
- int i = indexOf(key);
- if(i >= 0) //have key, will remove
- {
- Object[] newArray = new Object[array.length - 2];
- for(int s=0,d=0;s<array.length;s += 2)
- {
- if(!equalKey(array[s],key)) //skip removal key
- {
- newArray[d] = array[s];
- newArray[d+1] = array[s+1];
- d += 2;
- }
- }
- return new ArrayMap(newArray);
- }
- //don't have key, no op
- return this;
-}
-
-public Object get(Object key) {
- int i = indexOf(key);
- if(i >= 0)
- return array[i + 1];
- return null;
-}
-
-public int capacity() {
- return count();
-}
-
-int indexOf(Object key){
- for(int i=0;i<array.length;i+=2)
- {
- if(equalKey(array[i],key))
- return i;
- }
- return -1;
-}
-
-boolean equalKey(Object k1,Object k2){
- if(k1 == null)
- return k2 == null;
- return k1.equals(k2);
-}
-
-public Iterator iterator() {
- return new Iter(array);
-}
-
-static class Iter implements Iterator,IMapEntry{
- Object[] array;
- int i;
-
- //for iterator
- Iter(Object[] array){
- this(array,-2);
- }
-
- //for find
- Iter(Object[] array, int i){
- this.array = array;
- this.i = i;
- }
-
- public boolean hasNext() {
- return i < array.length - 2;
- }
-
- public Object next() {
- i+=2;
- return this;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public Object key() {
- return array[i];
- }
-
- public Object val() {
- return array[i+1];
- }
-}
-}
diff --git a/src/jvm/clojure/runtime/HashtableMap.java b/src/jvm/clojure/runtime/HashtableMap.java deleted file mode 100644 index a96a9761..00000000 --- a/src/jvm/clojure/runtime/HashtableMap.java +++ /dev/null @@ -1,280 +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 org.clojure.runtime;
-
-import java.util.Iterator;
-import java.math.BigInteger;
-
-public class HashtableMap implements IMap, Iterable {
-
-static final float FILL_FACTOR = 0.75f;
-
-final PersistentArray array;
-final int _count;
-final int growAtCount;
-
-public HashtableMap(int initialCapacity) {
- array = new PersistentArray(calcPrimeCapacity(initialCapacity));
- _count = 0;
- this.growAtCount = (int) (this.array.length()*FILL_FACTOR);
-}
-
-/**
- * @param init {key1,val1,key2,val2,...}
- */
-public HashtableMap(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);
-}
-
-HashtableMap(int count,PersistentArray array) {
- this._count = count;
- this.array = array;
- this.growAtCount = (int) (this.array.length()*FILL_FACTOR);
-}
-
-HashtableMap(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) {
- IMap entries = entriesFor(key);
- return entries != null && entries.contains(key);
-}
-
-public IMapEntry find(Object key) {
- IMap entries = entriesFor(key);
- if(entries != null)
- return entries.find(key);
- return null;
-}
-
-public IMap add(Object key) {
- return put(key, null);
-}
-
-public IMap put(Object key, Object val) {
- if(_count > growAtCount)
- return grow().put(key, val);
- int i = bucketFor(key,array);
- int incr = 1;
- PersistentArray newArray = doPut(i, key, val, array);
- if(newArray == array)
- return this;
- if(array.get(i) != null && ((IMap)newArray.get(i)).count() == ((IMap)array.get(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){
- IMap entries = (IMap) array.get(i);
- IMap newEntries;
- if (entries != null)
- {
- newEntries = entries.put(key, val);
- if(newEntries == entries) //already there with same value, no op
- return array;
- }
- else
- newEntries = createListMap(key, val);
- //newEntries = createArrayMap(new Object[]{key, val});
-
- return array.set(i, newEntries);
-}
-
-public IMap remove(Object key) {
- int i = bucketFor(key,array);
- IMap entries = (IMap) array.get(i);
- if (entries != null)
- {
- IMap newEntries = entries.remove(key);
- if (newEntries != entries)
- return create(_count - 1, array.set(i, newEntries));
- }
- //not there, no op
- return this;
-}
-
-public Object get(Object key) {
- IMap entries = entriesFor(key);
- if(entries != null)
- return entries.get(key);
- return null;
-}
-
-public int capacity() {
- return array.length();
-}
-
-public Iterator<IMapEntry> iterator() {
- return new Iter(array);
-}
-
-
-IMap 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);
-}
-
-/*
-static class Iter implements Iterator, IMapEntry{
- PersistentArray buckets;
-
- int b;
-
- Object[] nextEntries;
-
- int nextE;
-
- Object[] entries;
-
- int e;
-
- Iter(PersistentArray buckets){
- this.buckets = buckets;
- this.b = -1;
- nextBucket();
- }
-
- private void nextBucket() {
- nextEntries = null;
- nextE = 0;
- for(b = b+1;b<buckets.length();b++)
- {
- ArrayMap a = (ArrayMap) buckets.get(b);
- if(a != null)
- {
- nextEntries = a.array;
- break;
- }
- }
- }
-
- public boolean hasNext() {
- return nextEntries != null;
- }
-
- public Object next() {
- entries = nextEntries;
- e = nextE;
- nextE += 2;
- if(nextE >= nextEntries.length)
- nextBucket();
- return this;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public Object key() {
- return entries[e];
- }
-
- public Object val() {
- return entries[e+1];
- }
-
-}
-*/
-static class Iter implements Iterator{
- PersistentArray buckets;
- int b;
- ListMap e;
-
- Iter(PersistentArray buckets){
- this.buckets = buckets;
- this.b = -1;
- nextBucket();
- }
-
- private void nextBucket() {
- e = null;
- for(b = b+1;b<buckets.length();b++)
- {
- ListMap a = (ListMap) buckets.get(b);
- if(a != null && a != ListMap.EMPTY)
- {
- e = a;
- break;
- }
- }
- }
-
- public boolean hasNext() {
- return e != null;
- }
-
- public Object next() {
- ListMap ret = e;
- e = e.rest();
- if(e == ListMap.EMPTY)
- nextBucket();
- return ret;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-}
-
-final IMap entriesFor(Object key){
- return (IMap) array.get(bucketFor(key,array));
-}
-
-static int bucketFor(Object key, PersistentArray array) {
- return (key.hashCode() & 0x7fffffff)%array.length();
-}
-
-IMap create(int capacity) {
- return new HashtableMap(capacity);
-}
-
-IMap create(int count,PersistentArray array) {
- return new HashtableMap(count, array);
-}
-
-private IMap create(int i, PersistentArray newArray, int growAtCount){
- return new HashtableMap(i, newArray, growAtCount);
-}
-
-
-IMap createArrayMap(Object[] init) {
- return new ArrayMap(init);
-}
-
-private IMap createListMap(Object key, Object val){
- return ListMap.create(key,val);
-}
-
-}
diff --git a/src/jvm/clojure/runtime/IMap.java b/src/jvm/clojure/runtime/IMap.java deleted file mode 100644 index 015df00d..00000000 --- a/src/jvm/clojure/runtime/IMap.java +++ /dev/null @@ -1,31 +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 org.clojure.runtime;
-
-
-public interface IMap extends Iterable {
-
-int count();
-
-boolean contains(Object key);
-
-IMapEntry find(Object key);
-
-IMap add(Object key);
-
-IMap put(Object key, Object val);
-
-IMap remove(Object key);
-
-Object get(Object key);
-
-int capacity();
-}
diff --git a/src/jvm/clojure/runtime/IdentityArrayMap.java b/src/jvm/clojure/runtime/IdentityArrayMap.java deleted file mode 100644 index ed0c7106..00000000 --- a/src/jvm/clojure/runtime/IdentityArrayMap.java +++ /dev/null @@ -1,27 +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 org.clojure.runtime;
-
-/**
- * ArrayMap using identity (==) comparison instead of equals
- */
-public class IdentityArrayMap extends ArrayMap{
-public IdentityArrayMap() {
-}
-
-public IdentityArrayMap(Object[] init) {
- super(init);
-}
-
-boolean equalKey(Object k1, Object k2) {
- return k1 == k2;
-}
-}
diff --git a/src/jvm/clojure/runtime/IdentityHashtableMap.java b/src/jvm/clojure/runtime/IdentityHashtableMap.java deleted file mode 100644 index 71d93eeb..00000000 --- a/src/jvm/clojure/runtime/IdentityHashtableMap.java +++ /dev/null @@ -1,38 +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 org.clojure.runtime;
-
-public class IdentityHashtableMap extends HashtableMap{
-
-public IdentityHashtableMap(int initialCapacity) {
- super(initialCapacity);
-}
-
-public IdentityHashtableMap(Object[] init) {
- super(init);
-}
-
-IdentityHashtableMap(int count, PersistentArray array) {
- super(count, array);
-}
-
-IMap create(int capacity) {
- return new IdentityHashtableMap(capacity);
-}
-
-IMap create(int count, PersistentArray array) {
- return new IdentityHashtableMap(count, array);
-}
-
-IMap createArrayMap(Object[] init) {
- return new IdentityArrayMap(init);
-}
-}
diff --git a/src/jvm/clojure/runtime/ListMap.java b/src/jvm/clojure/runtime/ListMap.java deleted file mode 100644 index 16c77e9c..00000000 --- a/src/jvm/clojure/runtime/ListMap.java +++ /dev/null @@ -1,252 +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 6, 2006 */ - -package org.clojure.runtime; - -import java.util.Iterator; - -/** - * Immplementation of persistent map on a linked list - - * Note that instances of this class are constant values - * i.e. add/remove etc return new values - * - * Lookups/changes are linear, so only appropriate for _very_small_ maps - * ArrayMap is generally faster, but this class avoids the double allocation, - * and so is better/faster as a bucket for hash tables - * - * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find - */ -public class ListMap implements IMap, IMapEntry -{ - -static public ListMap EMPTY = new ListMap(); - -static public ListMap create(Object key, Object val){ - return new Tail(key, val); -} - -public Object key(){ - return null; -} - -public Object val(){ - return null; -} - -ListMap rest(){ - return this; - } - -public int count(){ - return 0; -} - -public boolean contains(Object key){ - return false; -} - -public IMapEntry find(Object key){ - return null; -} - -public IMap add(Object key){ - return put(key, null); -} - -public ListMap put(Object key, Object val){ - return new Tail(key, val); -} - -public ListMap remove(Object key){ - return this; -} - -public Object get(Object key){ - return null; -} - -public int capacity(){ - return 0; -} - -static class Iter implements Iterator{ - ListMap e; - - Iter(ListMap e) - { - this.e = e; - } - - public boolean hasNext(){ - return e != EMPTY; - } - - public Object next(){ - ListMap ret = e; - e = e.rest(); - return ret; - } - - public void remove(){ - throw new UnsupportedOperationException(); - } -} - -public Iterator iterator(){ - return new Iter(this); -} - -static class Tail extends ListMap{ - final Object _key; - final Object _val; - - Tail(Object key,Object val){ - this._key = key; - this._val = val; - } - - ListMap rest(){ - return EMPTY; - } - - public int count(){ - return 1; - } - - public Object get(Object key){ - if(equalKey(key,_key)) - return _val; - return null; - } - - public int capacity(){ - return 1; - } - - public Object key(){ - return _key; - } - - public Object val(){ - return _val; - } - - public boolean contains(Object key){ - return equalKey(key,_key); - } - - public IMapEntry find(Object key){ - if(equalKey(key,_key)) - return this; - return null; - } - - public ListMap put(Object key, Object val){ - if(equalKey(key,_key)) //replace - { - if(val == _val) - return this; - return new Tail(key,val); - } - return new Link(key,val,this); - } - - public ListMap remove(Object key){ - if(equalKey(key,_key)) - return EMPTY; - return this; - } -} - -static class Link extends ListMap{ - final Object _key; - final Object _val; - final ListMap _rest; - - Link(Object key,Object val,ListMap rest){ - this._key = key; - this._val = val; - this._rest = rest; - } - - public Object key(){ - return _key; - } - - public Object val(){ - return _val; - } - - ListMap rest(){ - return _rest; - } - - public int count(){ - return 1 + _rest.count(); - } - - public boolean contains(Object key){ - return find(key) != null; - } - - public IMapEntry find(Object key){ - if(equalKey(key,_key)) - return this; - return _rest.find(key); - } - - public ListMap put(Object key, Object val){ - IMapEntry e = find(key); - if(e != null) - { - if(e.val() == val) - return this; - return create(_key,_val,remove(key)); - } - return new Link(key,val,this); - } - - public ListMap remove(Object key){ - if(equalKey(key,_key)) - return _rest; - ListMap r = _rest.remove(key); - if(r == _rest) //not there - return this; - return create(_key,_val,r); - } - - public Object get(Object key){ - IMapEntry e = find(key); - if(e != null) - return e.val(); - return null; - } - - public int capacity(){ - return count(); - } - - ListMap create(Object k,Object v,ListMap r){ - if(r == EMPTY) - return new Tail(k,v); - return new Link(k, v, r); - } - -} - -boolean equalKey(Object k1,Object k2){ - if(k1 == null) - return k2 == null; - return k1.equals(k2); -} -} diff --git a/src/jvm/clojure/runtime/PersistentHashMap.java b/src/jvm/clojure/runtime/PersistentHashMap.java deleted file mode 100644 index f4ac6330..00000000 --- a/src/jvm/clojure/runtime/PersistentHashMap.java +++ /dev/null @@ -1,101 +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 org.clojure.runtime;
-
-import java.util.Iterator;
-
-public class PersistentHashMap implements IMap, Iterable{
-
-IMap impl;
-static final int CAPACITY_THRESHOLD = 42;
-
-public PersistentHashMap(Object[] init){
- if(init.length/2 < CAPACITY_THRESHOLD)
- impl = createArrayMap(init);
- impl = createHashtableMap(init);
-}
-
-public PersistentHashMap(int initialCapacity){
- if(initialCapacity < CAPACITY_THRESHOLD)
- impl = createArrayMap();
- else
- impl = createHashtableMap(initialCapacity);
-}
-
-PersistentHashMap(IMap impl){
- this.impl = impl;
-}
-
-public int count() {
- return impl.count();
-}
-
-public boolean contains(Object key) {
- return impl.contains(key);
-}
-
-public IMapEntry find(Object key) {
- return impl.find(key);
-}
-
-public IMap add(Object key) {
- return put(key, null);
-}
-
-public IMap put(Object key, Object val) {
- IMap newImpl = impl.put(key,val);
- if(newImpl.capacity() == CAPACITY_THRESHOLD)
- {
- newImpl = createHashtableMap(((ArrayMap)newImpl).array);
- }
- return create(newImpl);
-}
-
-public IMap remove(Object key) {
- IMap newImpl = impl.remove(key);
- if(newImpl != impl)
- return create(newImpl);
- return this;
-}
-
-public Object get(Object key) {
- return impl.get(key);
-}
-
-public int capacity() {
- return impl.capacity();
-}
-
-public Iterator iterator() {
- return ((Iterable)impl).iterator();
-}
-
-public IMap create(IMap impl) {
- return new PersistentHashMap(impl);
-}
-
-public ArrayMap createArrayMap(Object[] init) {
- return new ArrayMap(init);
-}
-
-private IMap createArrayMap() {
- return new ArrayMap();
-}
-
-private IMap createHashtableMap(Object[] init) {
- return new HashtableMap(init);
-}
-
-private IMap createHashtableMap(int initialCapacity) {
- return new HashtableMap(initialCapacity);
-}
-
-}
diff --git a/src/jvm/clojure/runtime/RBTree.java b/src/jvm/clojure/runtime/RBTree.java deleted file mode 100644 index 6aec53e2..00000000 --- a/src/jvm/clojure/runtime/RBTree.java +++ /dev/null @@ -1,759 +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 May 20, 2006 */ - -package org.clojure.runtime; - -import java.util.*; - -/** - * Persistent Red Black Tree - * Note that instances of this class are constant values - * i.e. add/remove etc return new values - * <p/> - * See Okasaki, Kahrs, Larsen et al - */ - -public class RBTree implements Iterable, IMap { - -public final Comparator comp; -public final Node tree; -public final int _count; - -public RBTree(){ - this(null); -} - -public RBTree(Comparator comp){ - this.comp = comp; - tree = null; - _count = 0; -} - -public boolean contains(Object key){ - return find(key) != null; -} - -public RBTree add(Object key){ - return put(key, null); -} - -public RBTree put(Object key, Object val){ - Box found = new Box(null); - Node t = add(tree, key, val, found); - if(t == null) //null == already contains key - { - Node foundNode = (Node) found.val; - if(foundNode.val() == val) //note only get same collection on identity of val, not equals() - return this; - return new RBTree(comp, replace(tree, key, val), _count); - } - return new RBTree(comp, t.blacken(), _count + 1); -} - - -public RBTree remove(Object key){ - Box found = new Box(null); - Node t = remove(tree, key, found); - if(t == null) - { - if(found.val == null)//null == doesn't contain key - return this; - //empty - return new RBTree(comp); - } - return new RBTree(comp, t.blacken(), _count - 1); -} - - -public NodeIterator iterator(){ - return new NodeIterator(tree, true); -} - -public NodeIterator reverseIterator(){ - return new NodeIterator(tree, false); -} - -public Iterator keys(){ - return keys(iterator()); -} - -public Iterator vals(){ - return vals(iterator()); -} - -public Iterator keys(NodeIterator it){ - return new KeyIterator(it); -} - -public Iterator vals(NodeIterator it){ - return new ValIterator(it); -} - -public Object minKey(){ - Node t = min(); - return t!=null?t.key:null; -} - -public Node min(){ - Node t = tree; - if(t != null) - { - while(t.left() != null) - t = t.left(); - } - return t; -} - -public Object maxKey(){ - Node t = max(); - return t!=null?t.key:null; -} - -public Node max(){ - Node t = tree; - if(t != null) - { - while(t.right() != null) - t = t.right(); - } - return t; -} - -public int depth(){ - return depth(tree); -} - -int depth(Node t){ - if(t == null) - return 0; - return 1 + Math.max(depth(t.left()), depth(t.right())); -} - -public Object get(Object key){ - Node n = find(key); - return (n != null) ? n.val() : null; -} - -public int capacity() { - return _count; -} - -public int count() { - return _count; -} - -public Node find(Object key){ - Node t = tree; - while(t != null) - { - int c = compare(key, t.key); - if(c == 0) - return t; - else if(c < 0) - t = t.left(); - else - t = t.right(); - } - return t; -} - -int compare(Object k1, Object k2){ - if(comp != null) - return comp.compare(k1, k2); - return ((Comparable) k1).compareTo(k2); -} - -Node add(Node t, Object key, Object val, Box found){ - if(t == null) - { - if(val == null) - return new Red(key); - return new RedVal(key, val); - } - int c = compare(key, t.key); - if(c == 0) - { - found.val = t; - return null; - } - Node ins = c < 0 ? add(t.left(), key, val, found) : add(t.right(), key, val, found); - if(ins == null) //found below - return null; - if(c < 0) - return t.addLeft(ins); - return t.addRight(ins); -} - -Node remove(Node t, Object key, Box found){ - if(t == null) - return null; //not found indicator - int c = compare(key, t.key); - if(c == 0) - { - found.val = t; - return append(t.left(), t.right()); - } - Node del = c < 0 ? remove(t.left(), key, found) : remove(t.right(), key, found); - if(del == null && found.val == null) //not found below - return null; - if(c < 0) - { - if(t.left() instanceof Black) - return balanceLeftDel(t.key, t.val(), del, t.right()); - else - return red(t.key, t.val(), del, t.right()); - } - if(t.right() instanceof Black) - return balanceRightDel(t.key, t.val(), t.left(), del); - return red(t.key, t.val(), t.left(), del); -// return t.removeLeft(del); -// return t.removeRight(del); -} - -static Node append(Node left, Node right){ - if(left == null) - return right; - else if(right == null) - return left; - else if(left instanceof Red) - { - if(right instanceof Red) - { - Node app = append(left.right(), right.left()); - if(app instanceof Red) - return red(app.key, app.val(), - red(left.key, left.val(), left.left(), app.left()), - red(right.key, right.val(), app.right(), right.right())); - else - return red(left.key, left.val(), left.left(), red(right.key, right.val(), app, right.right())); - } - else - return red(left.key, left.val(), left.left(), append(left.right(), right)); - } - else if(right instanceof Red) - return red(right.key, right.val(), append(left, right.left()), right.right()); - else //black/black - { - Node app = append(left.right(), right.left()); - if(app instanceof Red) - return red(app.key, app.val(), - black(left.key, left.val(), left.left(), app.left()), - black(right.key, right.val(), app.right(), right.right())); - else - return balanceLeftDel(left.key, left.val(), left.left(), black(right.key, right.val(), app, right.right())); - } -} - -static Node balanceLeftDel(Object key, Object val, Node del, Node right){ - if(del instanceof Red) - return red(key, val, del.blacken(), right); - else if(right instanceof Black) - return rightBalance(key, val, del, right.redden()); - else if(right instanceof Red && right.left() instanceof Black) - return red(right.left().key, right.left().val(), - black(key, val, del, right.left().left()), - rightBalance(right.key, right.val(), right.left().right(), right.right().redden())); - else - throw new UnsupportedOperationException("Invariant violation"); -} - -static Node balanceRightDel(Object key, Object val, Node left, Node del){ - if(del instanceof Red) - return red(key, val, lef |