forked from mongodb/mongo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash.js
65 lines (53 loc) · 2.92 KB
/
hash.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
* Use _hashBSONElement to test that our hash function never changes. This test hard codes the hash
* result for various inputs. For compatibility, these hardcoded values should never change over
* time or across architectures. This is a good place to put tests for any edge cases in the hash
* function that might be prone to change because of code changes or because of differences between
* architectures.
*
* @tags: [
* # The test runs commands that are not allowed with security token: _hashBSONElement.
* not_allowed_with_signed_security_token,
* no_selinux,
* ]
*/
const hashOfMaxNumberLong = NumberLong("1136124329541638701");
const hashOfLowestNumberLong = NumberLong("5744114172487291558");
const hashOfZeroNumberLong = NumberLong("5574369198691456941");
const hashTests = [
// Hash value of a string.
{key: "hashthis", expected: NumberLong("6271151123721111923")},
// The smallest positive double that overflows a 64-bit signed int. This is a special case,
// as described in SERVER-37183.
{key: Math.pow(2, 63), expected: hashOfLowestNumberLong},
// The next biggest number. Large doubles get clamped to the max 64-bit signed value before
// being hashed.
{key: Math.pow(2, 63) + Math.pow(2, 11), expected: hashOfMaxNumberLong},
// Really large numbers and positive infinity also get clamped to the same value.
{key: Math.pow(2, 500), expected: hashOfMaxNumberLong},
{key: Infinity, expected: hashOfMaxNumberLong},
// Just under the largest double that overflows a 64-bit signed int. This value gets
// converted to a signed 64-bit int and then hashed.
{key: Math.pow(2, 63) - Math.pow(2, 10), expected: NumberLong("-3954856262017896439")},
// Lowest negative double that does not overflow a 64-bit signed int.
{key: -Math.pow(2, 63), expected: hashOfLowestNumberLong},
// Just above the lowest negative double that does not overflow a 64-bit signed int.
{key: -(Math.pow(2, 63) - Math.pow(2, 10)), expected: NumberLong("-1762411739488908479")},
// A negative overflowing double gets clamped to -2^63 before being hashed.
{key: -(Math.pow(2, 63) + Math.pow(2, 11)), expected: hashOfLowestNumberLong},
{key: -Infinity, expected: hashOfLowestNumberLong},
// NaN values get converted to 0 and then hashed.
{key: 0, expected: hashOfZeroNumberLong},
{key: NumberLong("0"), expected: hashOfZeroNumberLong},
{key: NaN, expected: hashOfZeroNumberLong},
{key: -NaN, expected: hashOfZeroNumberLong},
// Hash an object.
{key: {a: 1, b: 2}, expected: NumberLong("-7076810813311352857")},
// Hash an object with some corner-case values.
{key: {a: Math.pow(2, 63), b: NaN}, expected: NumberLong("1223292051903137684")},
];
hashTests.forEach(test => {
const hashResult = db.runCommand({_hashBSONElement: test.key, seed: 1});
assert.commandWorked(hashResult);
assert.eq(test.expected, hashResult.out, tojson(test.key));
});