makes new hash the default, with an opt-out (& js-no-big-int) define.
Also update changelog (& fix one typo).

Only really expect the chronos hash-order sensitive test to fail until
they merge that PR and tag a new release.
This commit is contained in:
c-blake
2024-07-07 10:51:42 +00:00
committed by GitHub
parent 1dcc364cd2
commit 4faa15f3ad
11 changed files with 75 additions and 56 deletions

View File

@@ -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:"

View File

@@ -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:

View File

@@ -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

View File

@@ -1,5 +1,5 @@
discard """
matrix: "--jsbigint64:off; --jsbigint64:on"
matrix: "--jsbigint64:off -d:nimStringHash2; --jsbigint64:on"
"""
import std/private/jsutils

View File

@@ -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

View File

@@ -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

View File

@@ -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"
"""

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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"
"""
#[