summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli/runtime/APersistentMap.cs33
-rw-r--r--src/cli/runtime/RT.cs12
-rw-r--r--src/jvm/clojure/lang/APersistentMap.java36
-rw-r--r--src/jvm/clojure/lang/RT.java12
4 files changed, 93 insertions, 0 deletions
diff --git a/src/cli/runtime/APersistentMap.cs b/src/cli/runtime/APersistentMap.cs
index 99ca0ea4..8c082d23 100644
--- a/src/cli/runtime/APersistentMap.cs
+++ b/src/cli/runtime/APersistentMap.cs
@@ -15,6 +15,7 @@ using System.Collections;
namespace clojure.lang
{
public abstract class APersistentMap : Obj, IPersistentMap{
+ int _hash = -1;
public override Obj withMeta(IPersistentMap meta)
{
@@ -25,7 +26,39 @@ public abstract class APersistentMap : Obj, IPersistentMap{
return ret;
}
+override public bool Equals(Object obj) {
+ IPersistentMap m = obj as IPersistentMap;
+ if(obj == null)
+ return false;
+
+ if(m.count() != count())
+ return false;
+ for(ISeq s = seq();s!=null;s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ IMapEntry me = m.find(e.key());
+
+ if(me == null || !RT.equal(e.val(),me.val()))
+ return false;
+ }
+
+ return true;
+}
+
+override public int GetHashCode() {
+ if(_hash == -1)
+ {
+ int hash = count();
+ for(ISeq s = seq();s!=null;s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ hash ^= RT.hashCombine(RT.hash(e.key()), RT.hash(e.val()));
+ }
+ this._hash = hash;
+ }
+ return _hash;
+}
#region IPersistentMap Members
abstract public IPersistentMap assocEx(object key, object val);
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs
index 2d7e765e..eab52dfa 100644
--- a/src/cli/runtime/RT.cs
+++ b/src/cli/runtime/RT.cs
@@ -69,6 +69,18 @@ static public bool equal(Object k1,Object k2){
// ?T:null;
// }
+static public int hash(Object o){
+ if(o == null)
+ return 0;
+ return o.GetHashCode();
+}
+
+static public int hashCombine(int seed, int hash){
+ //a la boost
+ seed ^= (int)(hash + 0x9e3779b9 + (seed << 6) + (seed >> 2));
+ return seed;
+}
+
static public ISeq seq(Object coll) {
if(coll == null || coll is ISeq)
return (ISeq) coll;
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java
index c9492c14..6a29f2d4 100644
--- a/src/jvm/clojure/lang/APersistentMap.java
+++ b/src/jvm/clojure/lang/APersistentMap.java
@@ -11,6 +11,7 @@
package clojure.lang;
public abstract class APersistentMap extends Obj implements IPersistentMap, Cloneable{
+int _hash = -1;
public Obj withMeta(IPersistentMap meta) {
if(_meta == meta)
@@ -30,4 +31,39 @@ public IPersistentCollection cons(Object o) {
IMapEntry e = (IMapEntry)o;
return assoc(e.key(), e.val());
}
+
+public boolean equals(Object obj) {
+ if(!(obj instanceof IPersistentMap))
+ return false;
+ IPersistentMap m = (IPersistentMap)obj;
+
+ if(m.count() != count())
+ return false;
+
+ for(ISeq s = seq();s!=null;s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ IMapEntry me = m.find(e.key());
+
+ if(me == null || !RT.equal(e.val(),me.val()))
+ return false;
+ }
+
+ return true;
+}
+
+public int hashCode() {
+ if(_hash == -1)
+ {
+ int hash = count();
+ for(ISeq s = seq();s!=null;s = s.rest())
+ {
+ IMapEntry e = (IMapEntry) s.first();
+ hash ^= RT.hashCombine(RT.hash(e.key()), RT.hash(e.val()));
+ }
+ this._hash = hash;
+ }
+ return _hash;
+}
+
}
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index ce89b096..3263d923 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -68,6 +68,18 @@ static public boolean equal(Object k1,Object k2){
// ?Boolean.TRUE:null;
// }
+static public int hash(Object o){
+ if(o == null)
+ return 0;
+ return o.hashCode();
+}
+
+static public int hashCombine(int seed, int hash){
+ //a la boost
+ seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ return seed;
+}
+
static public ISeq seq(Object coll) {
if(coll == null || coll instanceof ISeq)
return (ISeq) coll;