summaryrefslogtreecommitdiff
path: root/src/org/clojure/runtime/ListMap.java
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-06-07 16:10:47 +0000
committerRich Hickey <richhickey@gmail.com>2006-06-07 16:10:47 +0000
commite26f6aee5713bfef08d8b68959672896b44bbd2d (patch)
tree0dd2b041674ec2ef405db8f7ccc44afbc8d6ec48 /src/org/clojure/runtime/ListMap.java
parent380dab4620630c099e59e364371c8d64b7050916 (diff)
perf tweaks
Diffstat (limited to 'src/org/clojure/runtime/ListMap.java')
-rw-r--r--src/org/clojure/runtime/ListMap.java34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/org/clojure/runtime/ListMap.java b/src/org/clojure/runtime/ListMap.java
index a87a699a..16c77e9c 100644
--- a/src/org/clojure/runtime/ListMap.java
+++ b/src/org/clojure/runtime/ListMap.java
@@ -14,6 +14,18 @@ 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
{
@@ -194,16 +206,14 @@ static class Link extends ListMap{
}
public ListMap put(Object key, Object val){
- if(equalKey(key,_key))
+ IMapEntry e = find(key);
+ if(e != null)
{
- if(val == _val)
+ if(e.val() == val)
return this;
- return new Link(key,val,_rest);
+ return create(_key,_val,remove(key));
}
- ListMap r = _rest.put(key,val);
- if(r == _rest) //already there with same value
- return this;
- return new Link(_key,_val,r);
+ return new Link(key,val,this);
}
public ListMap remove(Object key){
@@ -212,9 +222,7 @@ static class Link extends ListMap{
ListMap r = _rest.remove(key);
if(r == _rest) //not there
return this;
- if(r == EMPTY)
- return new Tail(_key,_val);
- return new Link(_key, _val, r);
+ return create(_key,_val,r);
}
public Object get(Object key){
@@ -228,6 +236,12 @@ static class Link extends ListMap{
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){