summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--changelog.md11
-rw-r--r--lib/pure/hashes.nim68
-rw-r--r--tests/int/tints.nim2
-rw-r--r--tests/js/ttypedarray.nim2
-rw-r--r--tests/parallel/tsendtwice.nim21
-rw-r--r--tests/stdlib/thashes.nim17
-rw-r--r--tests/stdlib/tjson.nim2
-rw-r--r--tests/stdlib/trandom.nim2
-rw-r--r--tests/stdlib/tstrutils.nim2
-rw-r--r--tests/stdlib/ttimes.nim2
-rw-r--r--tests/system/tdollars.nim2
11 files changed, 75 insertions, 56 deletions
diff --git a/changelog.md b/changelog.md
index 92abb2614..d2332dd57 100644
--- a/changelog.md
+++ b/changelog.md
@@ -30,7 +30,7 @@
 [//]: # "Additions:"
 
 - Added `newStringUninit` to system, which creates a new string of length `len` like `newString` but with uninitialized content.
-- Added `setLenUninit` to system, which doesn't initalize
+- Added `setLenUninit` to system, which doesn't initialize
 slots when enlarging a sequence.
 - Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
 - Added Viewport API for the JavaScript targets in the `dom` module.
@@ -39,9 +39,12 @@ slots when enlarging a sequence.
   objects the cyclic collector did free. If the number is zero that is a strong indicator that you can use `--mm:arc`
   instead of `--mm:orc`.
 - A `$` template is provided for `Path` in `std/paths`.
-- `nimPreviewHashFarm` has been added to `lib/pure/hashes.nim` to default to a
-64-bit string `Hash` (based upon Google's Farm Hash) which is also faster than
-the present one.  At present, this is incompatible with `--jsbigint=off` mode.
+- `std/hashes.hash(x:string)` changed to produce a 64-bit string `Hash` (based
+on Google's Farm Hash) which is also often faster than the present one.  Define
+`nimStringHash2` to get the old values back.  `--jsbigint=off` mode always only
+produces the old values.  This may impact your automated tests if they depend
+on hash order in some obvious or indirect way.  Using `sorted` or `OrderedTable`
+is often an easy workaround.
 
 [//]: # "Deprecations:"
 
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim
index 9e16cea9e..14d027107 100644
--- a/lib/pure/hashes.nim
+++ b/lib/pure/hashes.nim
@@ -518,6 +518,19 @@ proc hashFarm(s: openArray[byte]): uint64 {.inline.} =
   swap z, x
   len16 len16(v[0],w[0],mul) + shiftMix(y)*k0 + z, len16(v[1],w[1],mul) + x, mul
 
+template jsNoInt64: untyped =
+  when defined js:
+    when compiles(compileOption("jsbigint64")):
+      when not compileOption("jsbigint64"): true
+      else: false
+    else: false
+  else: false
+const sHash2 = (when defined(nimStringHash2) or jsNoInt64(): true else: false)
+
+template maybeFailJS_Number =
+  when jsNoInt64() and not defined(nimStringHash2):
+    {.error: "Must use `-d:nimStringHash2` when using `--jsbigint64:off`".}
+
 proc hash*(x: string): Hash =
   ## Efficient hashing of strings.
   ##
@@ -526,13 +539,13 @@ proc hash*(x: string): Hash =
   ## * `hashIgnoreCase <#hashIgnoreCase,string>`_
   runnableExamples:
     doAssert hash("abracadabra") != hash("AbracadabrA")
-
-  when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+  maybeFailJS_Number()
+  when not sHash2:
     result = cast[Hash](hashFarm(toOpenArrayByte(x, 0, x.high)))
   else:
-    when nimvm:
-      result = hashVmImpl(x, 0, high(x))
-    else:
+    #when nimvm:
+    #  result = hashVmImpl(x, 0, high(x))
+    when true:
       result = murmurHash(toOpenArrayByte(x, 0, high(x)))
 
 proc hash*(x: cstring): Hash =
@@ -542,21 +555,22 @@ proc hash*(x: cstring): Hash =
     doAssert hash(cstring"AbracadabrA") == hash("AbracadabrA")
     doAssert hash(cstring"abracadabra") != hash(cstring"AbracadabrA")
 
-  when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+  maybeFailJS_Number()
+  when not sHash2:
     when defined js:
       let xx = $x
       result = cast[Hash](hashFarm(toOpenArrayByte(xx, 0, xx.high)))
     else:
       result = cast[Hash](hashFarm(toOpenArrayByte(x, 0, x.high)))
   else:
-    when nimvm:
-      hashVmImpl(x, 0, high(x))
-    else:
+    #when nimvm:
+    #  result = hashVmImpl(x, 0, high(x))
+    when true:
       when not defined(js):
-        murmurHash(toOpenArrayByte(x, 0, x.high))
+        result = murmurHash(toOpenArrayByte(x, 0, x.high))
       else:
         let xx = $x
-        murmurHash(toOpenArrayByte(xx, 0, high(xx)))
+        result = murmurHash(toOpenArrayByte(xx, 0, high(xx)))
 
 proc hash*(sBuf: string, sPos, ePos: int): Hash =
   ## Efficient hashing of a string buffer, from starting
@@ -567,7 +581,8 @@ proc hash*(sBuf: string, sPos, ePos: int): Hash =
     var a = "abracadabra"
     doAssert hash(a, 0, 3) == hash(a, 7, 10)
 
-  when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+  maybeFailJS_Number()
+  when not sHash2:
     result = cast[Hash](hashFarm(toOpenArrayByte(sBuf, sPos, ePos)))
   else:
     murmurHash(toOpenArrayByte(sBuf, sPos, ePos))
@@ -705,17 +720,17 @@ proc hash*[A](x: openArray[A]): Hash =
   ## Efficient hashing of arrays and sequences.
   ## There must be a `hash` proc defined for the element type `A`.
   when A is byte:
-    when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+    when not sHash2:
       result = cast[Hash](hashFarm(x))
     else:
       result = murmurHash(x)
   elif A is char:
-    when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+    when not sHash2:
       result = cast[Hash](hashFarm(toOpenArrayByte(x, 0, x.high)))
     else:
-      when nimvm:
-        result = hashVmImplChar(x, 0, x.high)
-      else:
+      #when nimvm:
+      #  result = hashVmImplChar(x, 0, x.high)
+      when true:
         result = murmurHash(toOpenArrayByte(x, 0, x.high))
   else:
     result = 0
@@ -732,22 +747,23 @@ proc hash*[A](aBuf: openArray[A], sPos, ePos: int): Hash =
   runnableExamples:
     let a = [1, 2, 5, 1, 2, 6]
     doAssert hash(a, 0, 1) == hash(a, 3, 4)
-
   when A is byte:
-    when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+    maybeFailJS_Number()
+    when not sHash2:
       result = cast[Hash](hashFarm(toOpenArray(aBuf, sPos, ePos)))
     else:
-      when nimvm:
-        result = hashVmImplByte(aBuf, sPos, ePos)
-      else:
+      #when nimvm:
+      #  result = hashVmImplByte(aBuf, sPos, ePos)
+      when true:
         result = murmurHash(toOpenArray(aBuf, sPos, ePos))
   elif A is char:
-    when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
+    maybeFailJS_Number()
+    when not sHash2:
       result = cast[Hash](hashFarm(toOpenArrayByte(aBuf, sPos, ePos)))
     else:
-      when nimvm:
-        result = hashVmImplChar(aBuf, sPos, ePos)
-      else:
+      #when nimvm:
+      #  result = hashVmImplChar(aBuf, sPos, ePos)
+      when true:
         result = murmurHash(toOpenArrayByte(aBuf, sPos, ePos))
   else:
     for i in sPos .. ePos:
diff --git a/tests/int/tints.nim b/tests/int/tints.nim
index df72ec80a..773e8ccad 100644
--- a/tests/int/tints.nim
+++ b/tests/int/tints.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
+  matrix: "; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
   output: '''
 0 0
 0 0
diff --git a/tests/js/ttypedarray.nim b/tests/js/ttypedarray.nim
index 08b5fcdde..4807cb103 100644
--- a/tests/js/ttypedarray.nim
+++ b/tests/js/ttypedarray.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "--jsbigint64:off; --jsbigint64:on"
+  matrix: "--jsbigint64:off -d:nimStringHash2; --jsbigint64:on"
 """
 
 import std/private/jsutils
diff --git a/tests/parallel/tsendtwice.nim b/tests/parallel/tsendtwice.nim
index 6bf5e5ebb..9f4a2e06e 100644
--- a/tests/parallel/tsendtwice.nim
+++ b/tests/parallel/tsendtwice.nim
@@ -1,18 +1,10 @@
 discard """
-  output: '''ob2 @[]
-ob @[]
-ob3 @[]
-3
-ob2 @[]
-ob @[]
-ob3 @[]
-'''
   matrix: "--mm:refc"
 """
 
 # bug #4776
 
-import tables
+import tables, algorithm
 
 type
   Base* = ref object of RootObj
@@ -35,20 +27,21 @@ globalTable.add("ob", d)
 globalTable.add("ob2", d)
 globalTable.add("ob3", d)
 
+proc `<`(x, y: seq[int]): bool = x.len < y.len
+proc kvs(t: TableRef[string, Base]): seq[(string, seq[int])] =
+  for k, v in t.pairs: result.add (k, v.someSeq)
+  result.sort
+
 proc testThread(channel: ptr TableChannel) {.thread.} =
   globalTable = channel[].recv()
-  for k, v in pairs globaltable:
-    echo k, " ", v.someSeq
   var myObj: Base
   deepCopy(myObj, globalTable["ob"])
   myObj.someSeq = newSeq[int](100)
   let table = channel[].recv() # same table
-  echo table.len
-  for k, v in mpairs table:
-    echo k, " ", v.someSeq
   assert(table.contains("ob")) # fails!
   assert(table.contains("ob2")) # fails!
   assert(table.contains("ob3")) # fails!
+  assert table.kvs == globalTable.kvs # Last to see above spot checks first
 
 var channel: TableChannel
 
diff --git a/tests/stdlib/thashes.nim b/tests/stdlib/thashes.nim
index f7a1db232..4555fbcb3 100644
--- a/tests/stdlib/thashes.nim
+++ b/tests/stdlib/thashes.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off; --backend:c -d:nimPreviewHashFarm; --backend:cpp -d:nimPreviewHashFarm; --backend:js -d:nimPreviewHashFarm"
+  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:on; --backend:c -d:nimStringHash2; --backend:cpp -d:nimStringHash2; --backend:js -d:nimStringHash2"
 """
 
 import std/hashes
@@ -46,10 +46,18 @@ block hashes:
     else:
       doAssert hashWangYi1(456) == -6421749900419628582
 
+template jsNoInt64: untyped =
+  when defined js:
+    when compiles(compileOption("jsbigint64")):
+      when not compileOption("jsbigint64"): true
+      else: false
+    else: false
+  else: false
+const sHash2 = (when defined(nimStringHash2) or jsNoInt64(): true else: false)
+
 block empty:
   const emptyStrHash = # Hash=int=4B on js even w/--jsbigint64:on => cast[Hash]
-    when defined nimPreviewHashFarm: cast[Hash](-7286425919675154353i64)
-    else: 0
+    when sHash2: 0 else: cast[Hash](-7286425919675154353i64)
   var
     a = ""
     b = newSeq[char]()
@@ -96,8 +104,7 @@ block largeSize: # longer than 4 characters
 proc main() =
   doAssert hash(0.0) == hash(0)
   # bug #16061
-  when defined nimPreviewHashFarm: # Default switched -> `not nimStringHash2`
-    # Hash=int=4B on js even w/--jsbigint64:on => cast[Hash]
+  when not sHash2: # Hash=int=4B on js even w/--jsbigint64:on => cast[Hash]
     doAssert hash(cstring"abracadabra") == cast[Hash](-1119910118870047694i64)
   else:
     doAssert hash(cstring"abracadabra") == 97309975
diff --git a/tests/stdlib/tjson.nim b/tests/stdlib/tjson.nim
index f0e8c8bb7..e425501f6 100644
--- a/tests/stdlib/tjson.nim
+++ b/tests/stdlib/tjson.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
+  matrix: "; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
 """
 
 
diff --git a/tests/stdlib/trandom.nim b/tests/stdlib/trandom.nim
index 2e61312fd..bec75c1eb 100644
--- a/tests/stdlib/trandom.nim
+++ b/tests/stdlib/trandom.nim
@@ -1,6 +1,6 @@
 discard """
   joinable: false # to avoid messing with global rand state
-  matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
+  matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
 """
 import std/[assertions, formatfloat]
 import std/[random, math, stats, sets, tables]
diff --git a/tests/stdlib/tstrutils.nim b/tests/stdlib/tstrutils.nim
index 9937126f9..35f6bc669 100644
--- a/tests/stdlib/tstrutils.nim
+++ b/tests/stdlib/tstrutils.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
+  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
 """
 
 import std/strutils
diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim
index e01ab3a4f..602552f95 100644
--- a/tests/stdlib/ttimes.nim
+++ b/tests/stdlib/ttimes.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off"
+  matrix: "--mm:refc; --mm:orc; --backend:js --jsbigint64:on; --backend:js --jsbigint64:off -d:nimStringHash2"
 """
 
 import times, strutils, unittest
diff --git a/tests/system/tdollars.nim b/tests/system/tdollars.nim
index 61aa18534..eabee81b3 100644
--- a/tests/system/tdollars.nim
+++ b/tests/system/tdollars.nim
@@ -1,5 +1,5 @@
 discard """
-  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off; --backend:js --jsbigint64:on"
+  matrix: "--mm:refc; --mm:orc; --backend:cpp; --backend:js --jsbigint64:off -d:nimStringHash2; --backend:js --jsbigint64:on"
 """
 
 #[