Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

use hash consistent with equiv

  • Loading branch information...
commit b5f5ba2e15dc2f20e14e05141f7de7c6a3d91179 1 parent f006a81
Rich Hickey authored October 23, 2011
26  clojure.iml
... ...
@@ -1,29 +1,17 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2  
-<module relativePaths="true" type="JAVA_MODULE" version="4">
3  
-  <component name="FacetManager">
4  
-    <facet type="Clojure" name="Clojure">
5  
-      <configuration />
6  
-    </facet>
7  
-  </component>
8  
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
9  
-    <output url="file://$MODULE_DIR$/classes" />
10  
-    <exclude-output />
  2
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
  3
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
  4
+    <output url="file://$MODULE_DIR$/target/classes" />
  5
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
11 6
     <content url="file://$MODULE_DIR$">
  7
+      <sourceFolder url="file://$MODULE_DIR$/src/resources" isTestSource="false" />
12 8
       <sourceFolder url="file://$MODULE_DIR$/src/clj" isTestSource="false" />
  9
+      <sourceFolder url="file://$MODULE_DIR$/test/java" isTestSource="true" />
13 10
       <sourceFolder url="file://$MODULE_DIR$/src/jvm" isTestSource="false" />
  11
+      <excludeFolder url="file://$MODULE_DIR$/target" />
14 12
     </content>
15 13
     <orderEntry type="inheritedJdk" />
16 14
     <orderEntry type="sourceFolder" forTests="false" />
17  
-    <orderEntry type="library" name="asm-3.0" level="project" />
18  
-    <orderEntry type="module-library">
19  
-      <library>
20  
-        <CLASSES>
21  
-          <root url="jar://$APPLICATION_HOME_DIR$/lib/javaee.jar!/" />
22  
-        </CLASSES>
23  
-        <JAVADOC />
24  
-        <SOURCES />
25  
-      </library>
26  
-    </orderEntry>
27 15
   </component>
28 16
 </module>
29 17
 
15  src/jvm/clojure/lang/APersistentMap.java
@@ -13,7 +13,7 @@
13 13
 import java.io.Serializable;
14 14
 import java.util.*;
15 15
 
16  
-public abstract class APersistentMap extends AFn implements IPersistentMap, Map, Iterable, Serializable, MapEquivalence {
  16
+public abstract class APersistentMap extends AFn implements IPersistentMap, Map, Iterable, Serializable, MapEquivalence, IHashEq {
17 17
 int _hash = -1;
18 18
 
19 19
 public String toString(){
@@ -54,7 +54,7 @@ static public boolean mapEquals(IPersistentMap m1, Object obj){
54 54
 		return false;
55 55
 	Map m = (Map) obj;
56 56
 
57  
-	if(m.size() != m1.count() || m.hashCode() != m1.hashCode())
  57
+	if(m.size() != m1.count())
58 58
 		return false;
59 59
 
60 60
 	for(ISeq s = m1.seq(); s != null; s = s.next())
@@ -110,6 +110,17 @@ static public int mapHash(IPersistentMap m){
110 110
 	return hash;
111 111
 }
112 112
 
  113
+public int hasheq(){
  114
+	int hash = 0;
  115
+	for(ISeq s = this.seq(); s != null; s = s.next())
  116
+		{
  117
+		Map.Entry e = (Map.Entry) s.first();
  118
+		hash += Util.hasheq(e.getKey()) ^
  119
+				Util.hasheq(e.getValue());
  120
+		}
  121
+	return hash;
  122
+}
  123
+
113 124
 static public class KeySeq extends ASeq{
114 125
 	ISeq seq;
115 126
 
12  src/jvm/clojure/lang/APersistentSet.java
@@ -17,7 +17,7 @@
17 17
 import java.util.Iterator;
18 18
 import java.util.Set;
19 19
 
20  
-public abstract class APersistentSet extends AFn implements IPersistentSet, Collection, Set, Serializable {
  20
+public abstract class APersistentSet extends AFn implements IPersistentSet, Collection, Set, Serializable, IHashEq {
21 21
 int _hash = -1;
22 22
 final IPersistentMap impl;
23 23
 
@@ -92,6 +92,16 @@ public int hashCode(){
92 92
 	return _hash;
93 93
 }
94 94
 
  95
+public int hasheq(){
  96
+	int hash = 0;
  97
+	for(ISeq s = seq(); s != null; s = s.next())
  98
+		{
  99
+		Object e = s.first();
  100
+		hash +=  Util.hasheq(e);
  101
+		}
  102
+	return hash;
  103
+}
  104
+
95 105
 public Object[] toArray(){
96 106
 	return RT.seqToArray(seq());
97 107
 }
13  src/jvm/clojure/lang/APersistentVector.java
@@ -18,7 +18,7 @@
18 18
 public abstract class APersistentVector extends AFn implements IPersistentVector, Iterable,
19 19
                                                                List,
20 20
                                                                RandomAccess, Comparable,
21  
-                                                               Serializable {
  21
+                                                               Serializable, IHashEq {
22 22
 int _hash = -1;
23 23
 
24 24
 public String toString(){
@@ -152,6 +152,17 @@ public int hashCode(){
152 152
 	return _hash;
153 153
 }
154 154
 
  155
+public int hasheq(){
  156
+	int hash = 1;
  157
+	Iterator i = iterator();
  158
+	while(i.hasNext())
  159
+		{
  160
+		Object obj = i.next();
  161
+		hash = 31 * hash + Util.hasheq(obj);
  162
+		}
  163
+	return hash;
  164
+}
  165
+
155 166
 public Object get(int index){
156 167
 	return nth(index);
157 168
 }
11  src/jvm/clojure/lang/ASeq.java
@@ -13,7 +13,7 @@
13 13
 import java.io.Serializable;
14 14
 import java.util.*;
15 15
 
16  
-public abstract class ASeq extends Obj implements ISeq, Sequential, List, Serializable {
  16
+public abstract class ASeq extends Obj implements ISeq, Sequential, List, Serializable, IHashEq {
17 17
 transient int _hash = -1;
18 18
 
19 19
 public String toString(){
@@ -73,6 +73,15 @@ public int hashCode(){
73 73
 	return _hash;
74 74
 }
75 75
 
  76
+public int hasheq(){
  77
+	int hash = 1;
  78
+	for(ISeq s = seq(); s != null; s = s.next())
  79
+		{
  80
+		hash = 31 * hash + Util.hasheq(s.first());
  81
+		}
  82
+	return hash;
  83
+}
  84
+
76 85
 
77 86
 //public Object reduce(IFn f) {
78 87
 //	Object ret = first();
17  src/jvm/clojure/lang/IHashEq.java
... ...
@@ -0,0 +1,17 @@
  1
+/**
  2
+ *   Copyright (c) Rich Hickey. All rights reserved.
  3
+ *   The use and distribution terms for this software are covered by the
  4
+ *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
  5
+ *   which can be found in the file epl-v10.html at the root of this distribution.
  6
+ *   By using this software in any fashion, you are agreeing to be bound by
  7
+ * 	 the terms of this license.
  8
+ *   You must not remove this notice, or any other, from this software.
  9
+ **/
  10
+
  11
+/* rich 10/23/11 */
  12
+
  13
+package clojure.lang;
  14
+
  15
+public interface IHashEq{
  16
+int hasheq();
  17
+}
9  src/jvm/clojure/lang/LazySeq.java
@@ -14,7 +14,7 @@
14 14
 
15 15
 import java.util.*;
16 16
 
17  
-public final class LazySeq extends Obj implements ISeq, Sequential, List, IPending{
  17
+public final class LazySeq extends Obj implements ISeq, Sequential, List, IPending, IHashEq{
18 18
 
19 19
 private IFn fn;
20 20
 private Object sv;
@@ -118,6 +118,13 @@ public int hashCode(){
118 118
 	return Util.hash(seq());
119 119
 }
120 120
 
  121
+public int hasheq(){
  122
+	ISeq s = seq();
  123
+	if(s == null)
  124
+		return 1;
  125
+	return Util.hasheq(seq());
  126
+}
  127
+
121 128
 public boolean equals(Object o){
122 129
 	ISeq s = seq();
123 130
 	if(s != null)
18  src/jvm/clojure/lang/Numbers.java
@@ -941,11 +941,11 @@ public Number dec(Number x){
941 941
 static Ops ops(Object x){
942 942
 	Class xc = x.getClass();
943 943
 
944  
-	if(xc == Integer.class)
  944
+	if(xc == Long.class)
945 945
 		return LONG_OPS;
946 946
 	else if(xc == Double.class)
947 947
 		return DOUBLE_OPS;
948  
-	else if(xc == Long.class)
  948
+	else if(xc == Integer.class)
949 949
 		return LONG_OPS;
950 950
 	else if(xc == Float.class)
951 951
 		return DOUBLE_OPS;
@@ -961,6 +961,20 @@ else if(xc == BigDecimal.class)
961 961
 		return LONG_OPS;
962 962
 }
963 963
 
  964
+static int hasheq(Number x){
  965
+	Class xc = x.getClass();
  966
+
  967
+	if(xc == Long.class
  968
+		|| xc == Integer.class
  969
+		|| xc == Short.class
  970
+		|| xc == Byte.class)
  971
+		{
  972
+		long lpart = x.longValue();
  973
+		return (int) (lpart ^ (lpart >>> 32));
  974
+		}
  975
+	return x.hashCode();
  976
+}
  977
+
964 978
 static Category category(Object x){
965 979
 	Class xc = x.getClass();
966 980
 
28  src/jvm/clojure/lang/PersistentHashMap.java
@@ -117,16 +117,20 @@ public PersistentHashMap(IPersistentMap meta, int count, INode root, boolean has
117 117
 	this.nullValue = nullValue;
118 118
 }
119 119
 
  120
+static int hash(Object k){
  121
+	return Util.hasheq(k);
  122
+}
  123
+
120 124
 public boolean containsKey(Object key){
121 125
 	if(key == null)
122 126
 		return hasNull;
123  
-	return (root != null) ? root.find(0, Util.hash(key), key, NOT_FOUND) != NOT_FOUND : false;
  127
+	return (root != null) ? root.find(0, hash(key), key, NOT_FOUND) != NOT_FOUND : false;
124 128
 }
125 129
 
126 130
 public IMapEntry entryAt(Object key){
127 131
 	if(key == null)
128 132
 		return hasNull ? new MapEntry(null, nullValue) : null;
129  
-	return (root != null) ? root.find(0, Util.hash(key), key) : null;
  133
+	return (root != null) ? root.find(0, hash(key), key) : null;
130 134
 }
131 135
 
132 136
 public IPersistentMap assoc(Object key, Object val){
@@ -137,7 +141,7 @@ public IPersistentMap assoc(Object key, Object val){
137 141
 	}
138 142
 	Box addedLeaf = new Box(null);
139 143
 	INode newroot = (root == null ? BitmapIndexedNode.EMPTY : root) 
140  
-			.assoc(0, Util.hash(key), key, val, addedLeaf);
  144
+			.assoc(0, hash(key), key, val, addedLeaf);
141 145
 	if(newroot == root)
142 146
 		return this;
143 147
 	return new PersistentHashMap(meta(), addedLeaf.val == null ? count : count + 1, newroot, hasNull, nullValue);
@@ -146,7 +150,7 @@ public IPersistentMap assoc(Object key, Object val){
146 150
 public Object valAt(Object key, Object notFound){
147 151
 	if(key == null)
148 152
 		return hasNull ? nullValue : notFound;
149  
-	return root != null ? root.find(0, Util.hash(key), key, notFound) : notFound;
  153
+	return root != null ? root.find(0, hash(key), key, notFound) : notFound;
150 154
 }
151 155
 
152 156
 public Object valAt(Object key){
@@ -164,7 +168,7 @@ public IPersistentMap without(Object key){
164 168
 		return hasNull ? new PersistentHashMap(meta(), count - 1, root, false, null) : this;
165 169
 	if(root == null)
166 170
 		return this;
167  
-	INode newroot = root.without(0, Util.hash(key), key);
  171
+	INode newroot = root.without(0, hash(key), key);
168 172
 	if(newroot == root)
169 173
 		return this;
170 174
 	return new PersistentHashMap(meta(), count - 1, newroot, hasNull, nullValue); 
@@ -238,7 +242,7 @@ ITransientMap doAssoc(Object key, Object val) {
238 242
 //		Box leafFlag = new Box(null);
239 243
 		leafFlag.val = null;
240 244
 		INode n = (root == null ? BitmapIndexedNode.EMPTY : root)
241  
-			.assoc(edit, 0, Util.hash(key), key, val, leafFlag);
  245
+			.assoc(edit, 0, hash(key), key, val, leafFlag);
242 246
 		if (n != this.root)
243 247
 			this.root = n; 
244 248
 		if(leafFlag.val != null) this.count++;
@@ -256,7 +260,7 @@ ITransientMap doWithout(Object key) {
256 260
 		if (root == null) return this;
257 261
 //		Box leafFlag = new Box(null);
258 262
 		leafFlag.val = null;
259  
-		INode n = root.without(edit, 0, Util.hash(key), key, leafFlag);
  263
+		INode n = root.without(edit, 0, hash(key), key, leafFlag);
260 264
 		if (n != root)
261 265
 			this.root = n;
262 266
 		if(leafFlag.val != null) this.count--;
@@ -276,7 +280,7 @@ Object doValAt(Object key, Object notFound) {
276 280
 				return notFound;
277 281
 		if (root == null)
278 282
 			return null;
279  
-		return root.find(0, Util.hash(key), key, notFound);
  283
+		return root.find(0, hash(key), key, notFound);
280 284
 	}
281 285
 
282 286
 	int doCount() {
@@ -525,7 +529,7 @@ public INode assoc(int shift, int hash, Object key, Object val, Box addedLeaf){
525 529
 						if (array[j] == null)
526 530
 							nodes[i] = (INode) array[j+1];
527 531
 						else
528  
-							nodes[i] = EMPTY.assoc(shift + 5, Util.hash(array[j]), array[j], array[j+1], addedLeaf);
  532
+							nodes[i] = EMPTY.assoc(shift + 5, hash(array[j]), array[j], array[j+1], addedLeaf);
529 533
 						j += 2;
530 534
 					}
531 535
 				return new ArrayNode(null, n + 1, nodes);
@@ -670,7 +674,7 @@ public INode assoc(AtomicReference<Thread> edit, int shift, int hash, Object key
670 674
 						if (array[j] == null)
671 675
 							nodes[i] = (INode) array[j+1];
672 676
 						else
673  
-							nodes[i] = EMPTY.assoc(edit, shift + 5, Util.hash(array[j]), array[j], array[j+1], addedLeaf);
  677
+							nodes[i] = EMPTY.assoc(edit, shift + 5, hash(array[j]), array[j], array[j+1], addedLeaf);
674 678
 						j += 2;
675 679
 					}
676 680
 				return new ArrayNode(edit, n + 1, nodes);
@@ -976,7 +980,7 @@ public static void main(String[] args){
976 980
 }
977 981
 
978 982
 private static INode createNode(int shift, Object key1, Object val1, int key2hash, Object key2, Object val2) {
979  
-	int key1hash = Util.hash(key1);
  983
+	int key1hash = hash(key1);
980 984
 	if(key1hash == key2hash)
981 985
 		return new HashCollisionNode(null, key1hash, 2, new Object[] {key1, val1, key2, val2});
982 986
 	Box _ = new Box(null);
@@ -987,7 +991,7 @@ private static INode createNode(int shift, Object key1, Object val1, int key2has
987 991
 }
988 992
 
989 993
 private static INode createNode(AtomicReference<Thread> edit, int shift, Object key1, Object val1, int key2hash, Object key2, Object val2) {
990  
-	int key1hash = Util.hash(key1);
  994
+	int key1hash = hash(key1);
991 995
 	if(key1hash == key2hash)
992 996
 		return new HashCollisionNode(null, key1hash, 2, new Object[] {key1, val1, key2, val2});
993 997
 	Box _ = new Box(null);
10  src/jvm/clojure/lang/Util.java
@@ -116,6 +116,16 @@ static public int hash(Object o){
116 116
 	return o.hashCode();
117 117
 }
118 118
 
  119
+static public int hasheq(Object o){
  120
+	if(o == null)
  121
+		return 0;
  122
+	if(o instanceof Number)
  123
+		return Numbers.hasheq((Number)o);
  124
+	else if(o instanceof IHashEq)
  125
+		return ((IHashEq)o).hasheq();
  126
+	return o.hashCode();
  127
+}
  128
+
119 129
 static public int hashCombine(int seed, int hash){
120 130
 	//a la boost
121 131
 	seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);

0 notes on commit b5f5ba2

Please sign in to comment.
Something went wrong with that request. Please try again.