mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Update hash mixing behavior - address #889
Try to have better behavior when mixing sub-hashes that are not uniform and randomly distributed. Premultiply by a large prime before mixing to "spread entropy" if it is concentrated in a certain subset of bits.
This commit is contained in:
parent
4dc281a05f
commit
545c09e202
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@ -50,5 +50,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
files: |
|
files: |
|
||||||
|
./dist/*.zip
|
||||||
./*.zip
|
./*.zip
|
||||||
./*.msi
|
./*.msi
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## Unreleased - ???
|
||||||
|
- Update hash function.
|
||||||
|
|
||||||
## 1.19.1 - 2021-12-04
|
## 1.19.1 - 2021-12-04
|
||||||
- Add an optional `prefix` paramater to `debug/stacktrace` to allow printing prettier error messages.
|
- Add an optional `prefix` parameter to `debug/stacktrace` to allow printing prettier error messages.
|
||||||
- Remove appveyor for CI pipeline
|
- Remove appveyor for CI pipeline
|
||||||
- Fixed a bug that prevented sending threaded abstracts over threaded channels.
|
- Fixed a bug that prevented sending threaded abstracts over threaded channels.
|
||||||
- Fix bug in the `map` function with arity at least 3.
|
- Fix bug in the `map` function with arity at least 3.
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
project('janet', 'c',
|
project('janet', 'c',
|
||||||
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
||||||
version : '1.19.1')
|
version : '1.19.2')
|
||||||
|
|
||||||
# Global settings
|
# Global settings
|
||||||
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
#define JANET_VERSION_MAJOR 1
|
#define JANET_VERSION_MAJOR 1
|
||||||
#define JANET_VERSION_MINOR 19
|
#define JANET_VERSION_MINOR 19
|
||||||
#define JANET_VERSION_PATCH 1
|
#define JANET_VERSION_PATCH 2
|
||||||
#define JANET_VERSION_EXTRA ""
|
#define JANET_VERSION_EXTRA "-dev"
|
||||||
#define JANET_VERSION "1.19.1"
|
#define JANET_VERSION "1.19.2-dev"
|
||||||
|
|
||||||
/* #define JANET_BUILD "local" */
|
/* #define JANET_BUILD "local" */
|
||||||
|
|
||||||
|
@ -224,13 +224,16 @@ int32_t janet_string_calchash(const uint8_t *str, int32_t len) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint32_t janet_hash_mix(uint32_t input, uint32_t more) {
|
||||||
|
return input ^ ((more * 2119589369u) + 0x9e3779b9 + (input << 6) + (input >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
/* Computes hash of an array of values */
|
/* Computes hash of an array of values */
|
||||||
int32_t janet_array_calchash(const Janet *array, int32_t len) {
|
int32_t janet_array_calchash(const Janet *array, int32_t len) {
|
||||||
const Janet *end = array + len;
|
const Janet *end = array + len;
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 33;
|
||||||
while (array < end) {
|
while (array < end) {
|
||||||
uint32_t elem = janet_hash(*array++);
|
hash = janet_hash_mix(hash, janet_hash(*array++));
|
||||||
hash ^= elem + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
|
||||||
}
|
}
|
||||||
return (int32_t) hash;
|
return (int32_t) hash;
|
||||||
}
|
}
|
||||||
@ -238,10 +241,10 @@ int32_t janet_array_calchash(const Janet *array, int32_t len) {
|
|||||||
/* Computes hash of an array of values */
|
/* Computes hash of an array of values */
|
||||||
int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len) {
|
int32_t janet_kv_calchash(const JanetKV *kvs, int32_t len) {
|
||||||
const JanetKV *end = kvs + len;
|
const JanetKV *end = kvs + len;
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 33;
|
||||||
while (kvs < end) {
|
while (kvs < end) {
|
||||||
hash ^= janet_hash(kvs->key) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
hash = janet_hash_mix(hash, janet_hash(kvs->key));
|
||||||
hash ^= janet_hash(kvs->value) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
hash = janet_hash_mix(hash, janet_hash(kvs->value));
|
||||||
kvs++;
|
kvs++;
|
||||||
}
|
}
|
||||||
return (int32_t) hash;
|
return (int32_t) hash;
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Utils */
|
/* Utils */
|
||||||
|
uint32_t janet_hash_mix(uint32_t input, uint32_t more);
|
||||||
#define janet_maphash(cap, hash) ((uint32_t)(hash) & (cap - 1))
|
#define janet_maphash(cap, hash) ((uint32_t)(hash) & (cap - 1))
|
||||||
int janet_valid_utf8(const uint8_t *str, int32_t len);
|
int janet_valid_utf8(const uint8_t *str, int32_t len);
|
||||||
int janet_is_symbol_char(uint8_t c);
|
int janet_is_symbol_char(uint8_t c);
|
||||||
|
Loading…
Reference in New Issue
Block a user