UninterpretedBytes.st
branchjv
changeset 20398 8cb53f870d39
parent 20205 03e626304d06
parent 20373 bce89424b82a
child 20600 222ed6c9364e
--- a/UninterpretedBytes.st	Mon Sep 19 08:39:59 2016 +0100
+++ b/UninterpretedBytes.st	Mon Sep 19 08:46:27 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1993 by Claus Gittinger
               All Rights Reserved
@@ -14,10 +16,10 @@
 "{ NameSpace: Smalltalk }"
 
 ArrayedCollection subclass:#UninterpretedBytes
-        instanceVariableNames:''
-        classVariableNames:'IsBigEndian'
-        poolDictionaries:''
-        category:'Collections-Abstract'
+	instanceVariableNames:''
+	classVariableNames:'IsBigEndian'
+	poolDictionaries:''
+	category:'Collections-Abstract'
 !
 
 !UninterpretedBytes primitiveDefinitions!
@@ -743,7 +745,7 @@
 longLongAt:index
     "return the 8-bytes starting at index as a signed Integer.
      The index is a smalltalk index (i.e. 1-based).
-     The value is retrieved in the machineÄs natural byte order.
+     The value is retrieved in the machineÄs natural byte order.
      This may be worth a primitive."
 
     ^ self signedInt64At:index MSB:IsBigEndian
@@ -4388,13 +4390,17 @@
 !UninterpretedBytes methodsFor:'hashing'!
 
 computeXorHashFrom:startIndex to:endIndex
-    "compute and answer the SmallInteger-Hash of the bytes
+    "compute and answer the 32bit SmallInteger-Hash of the bytes
      from startIndex to endIndex.
      If endindex = 0 or endIndex > size, hash up the size.
 
      NOTE: startIndex and endIndex are only hints about what should be hashed.
            In fact, more bytes could be involved in hashing.
-           SO ARRAYS MUST BE EQUAL TO HASH TO THE SAME VALUE"
+           SO ARRAYS MUST BE EQUAL TO HASH TO THE SAME VALUE.
+
+    Also NOTE:
+        used to return a 32bit hash on 32bit machines and a 64bit integer on 64bit cpus.
+        changed to return the same for all (in case hash values are used for other purposes)."
 
     |w|
 
@@ -4407,8 +4413,13 @@
         if (cp) {
             INT sidx = ((unsigned INT)__smallIntegerVal(startIndex)) - 1;
             INT eidx = ((unsigned INT)__smallIntegerVal(endIndex)) - 1;
+// #           define H_INT INT            
+// #           define _MAX_H_INT _MAX_INT;
+#           define H_INT int            
+#           define _MAX_H_INT 0x3FFFFFFF
+
             unsigned char *ep;
-            unsigned INT hash = 0, hash2 = 0, carry;
+            unsigned H_INT hash = 0, hash2 = 0, carry;
             int i;
 
             if (eidx < 0 || eidx >= sz) eidx = sz - 1;
@@ -4427,37 +4438,39 @@
              * if the same bytes are at different positions
              */
 
-            if ((INT)cp & (sizeof(INT)-1)) {
+            if ((H_INT)cp & (sizeof(H_INT)-1)) {
                 /* not aligned */
 
                 for (i=0; cp <= ep; cp++) {
                     hash2 = (hash2 << 8) | *cp;
-                    if (++i == sizeof(INT)) {
+                    if (++i == sizeof(H_INT)) {
                         hash ^= hash2;
                         i = hash2 = 0;
                     }
                 }
             } else {
                 /* aligned */
-                for (; cp+sizeof(INT) <= ep; cp += sizeof(INT)) {
-                    hash ^= *(unsigned INT *)cp;
+                for (; cp+sizeof(H_INT) <= ep; cp += sizeof(H_INT)) {
+                    hash ^= *(unsigned H_INT *)cp;
                 }
                 for (; cp <= ep; cp++) {
                     hash2 = (hash2 << 8) | *cp;
                 }
             }
 #else
-            for (i=0; cp <= ep-sizeof(INT); cp += sizeof(INT)) {
+            for (i=0; cp <= ep-sizeof(H_INT); cp += sizeof(H_INT)) {
                 hash2 = cp[0];
                 hash2 = (hash2 << 8) | cp[1];
                 hash2 = (hash2 << 8) | cp[2];
                 hash2 = (hash2 << 8) | cp[3];
-#if __POINTER_SIZE__ == 8
-                hash2 = (hash2 << 8) | cp[4];
-                hash2 = (hash2 << 8) | cp[5];
-                hash2 = (hash2 << 8) | cp[6];
-                hash2 = (hash2 << 8) | cp[7];
-#endif
+# if 0
+                if (sizeof(H_INT) == 8) {
+                    hash2 = (hash2 << 8) | cp[4];
+                    hash2 = (hash2 << 8) | cp[5];
+                    hash2 = (hash2 << 8) | cp[6];
+                    hash2 = (hash2 << 8) | cp[7];
+                }
+# endif
                 /*
                  * multiply by large prime to scramble bits and
                  * to avoid a 0 result from
@@ -4472,11 +4485,11 @@
             hash ^= (hash * 31415821) ^ hash2;
 
             /*
-             * fold the high bits not fitting into a SmallInteger
+             * fold the high bits not fitting into a H_INT
              */
-            carry = hash & ~_MAX_INT;
+            carry = hash & ~_MAX_H_INT;
             if (carry) {
-                hash = (hash & _MAX_INT) ^ (carry >> 8);
+                hash = (hash & _MAX_H_INT) ^ (carry >> 8);
             }
 
             RETURN(__mkSmallInteger(hash));
@@ -4492,7 +4505,7 @@
      #[1 2 3 4] computeXorHashFrom:1 to:0.
      #[1 2 3 4 5] computeXorHashFrom:1 to:4.
      #[1 2 3 4 1 2 3 4] computeXorHashFrom:1 to:8.
-     #[1 2 3 4 5 6 7 8] computeXorHashFrom:2 to:8.
+     #[1 2 3 4 5 6 7 8] computeXorHashFrom:2 to:8. 
      #[2 3 4 5 6 7 8] computeXorHashFrom:1 to:7.
      #[2 3 4 5 6 7 8] computeXorHashFrom:1 to:8.
     "