From c318f7c60e4cff91b0591d1e9dc8bee63c716404 Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Sat, 5 Aug 2006 22:39:38 +0000 Subject: added equals and hashcode to maps --- src/cli/runtime/APersistentMap.cs | 33 +++++++++++++++++++++++++++++++++ src/cli/runtime/RT.cs | 12 ++++++++++++ 2 files changed, 45 insertions(+) (limited to 'src/cli/runtime') 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; -- cgit v1.2.3-70-g09d2