Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions core/string/node_path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,30 @@

#include "node_path.h"

#include "core/templates/hashfuncs.h"
#include "core/variant/variant.h"

void NodePath::_update_hash_cache() const {
uint32_t h = data->absolute ? 1 : 0;
int pc = data->path.size();
const StringName *sn = data->path.ptr();
uint32_t hash_mixed = h;
for (int i = 0; i < pc; i++) {
h = h ^ sn[i].hash();
uint32_t string_hash = sn[i].hash();
h = h ^ string_hash;
hash_mixed = hash_djb2_one_32(string_hash, hash_mixed); // Don't change to murmur3 because StringName uses djb2!
}
int spc = data->subpath.size();
const StringName *ssn = data->subpath.ptr();
for (int i = 0; i < spc; i++) {
h = h ^ ssn[i].hash();
uint32_t string_hash = ssn[i].hash();
h = h ^ string_hash;
hash_mixed = hash_djb2_one_32(string_hash, hash_mixed);
}

data->hash_cache_valid = true;
data->hash_cache = h;
data->hash_mixed_cache = hash_fmix32(hash_mixed);
}

void NodePath::prepend_period() {
Expand Down
11 changes: 11 additions & 0 deletions core/string/node_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class NodePath {
bool absolute;
mutable bool hash_cache_valid;
mutable uint32_t hash_cache;
mutable uint32_t hash_mixed_cache;
};

mutable Data *data = nullptr;
Expand Down Expand Up @@ -78,6 +79,16 @@ class NodePath {
return data->hash_cache;
}

_FORCE_INLINE_ uint32_t hash_mixed() const {
if (!data) {
return 0;
}
if (!data->hash_cache_valid) {
_update_hash_cache();
}
return data->hash_mixed_cache;
}

operator String() const;
bool is_empty() const;

Expand Down
30 changes: 21 additions & 9 deletions core/string/string_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,16 @@ StringName::StringName(const char *p_name, bool p_static) {
}

const uint32_t hash = String::hash(p_name);
const uint32_t idx = hash & STRING_TABLE_MASK;
const uint32_t hash_mixed = hash_fmix32(hash);

const uint32_t idx = hash_mixed & STRING_TABLE_MASK;

MutexLock lock(mutex);
_data = _table[idx];

while (_data) {
// compare hash first
if (_data->hash == hash && _data->operator==(p_name)) {
if (_data->hash_mixed == hash_mixed && _data->operator==(p_name)) {
break;
}
_data = _data->next;
Expand Down Expand Up @@ -305,6 +307,7 @@ StringName::StringName(const char *p_name, bool p_static) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
_data->hash_mixed = hash_mixed;

#ifdef DEBUG_ENABLED
if (unlikely(debug_stringname)) {
Expand All @@ -327,14 +330,16 @@ StringName::StringName(const StaticCString &p_static_string, bool p_static) {
ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]);

const uint32_t hash = String::hash(p_static_string.ptr);
const uint32_t idx = hash & STRING_TABLE_MASK;
const uint32_t hash_mixed = hash_fmix32(hash);

const uint32_t idx = hash_mixed & STRING_TABLE_MASK;

MutexLock lock(mutex);
_data = _table[idx];

while (_data) {
// compare hash first
if (_data->hash == hash && _data->operator==(p_static_string.ptr)) {
if (_data->hash_mixed == hash_mixed && _data->operator==(p_static_string.ptr)) {
break;
}
_data = _data->next;
Expand Down Expand Up @@ -362,6 +367,8 @@ StringName::StringName(const StaticCString &p_static_string, bool p_static) {
_data->cname = p_static_string.ptr;
_data->next = _table[idx];
_data->prev = nullptr;

_data->hash_mixed = hash_mixed;
#ifdef DEBUG_ENABLED
if (unlikely(debug_stringname)) {
// Keep in memory, force static.
Expand All @@ -385,13 +392,14 @@ StringName::StringName(const String &p_name, bool p_static) {
}

const uint32_t hash = p_name.hash();
const uint32_t idx = hash & STRING_TABLE_MASK;
const uint32_t hash_mixed = hash_fmix32(hash);
const uint32_t idx = hash_mixed & STRING_TABLE_MASK;

MutexLock lock(mutex);
_data = _table[idx];

while (_data) {
if (_data->hash == hash && _data->operator==(p_name)) {
if (_data->hash_mixed == hash_mixed && _data->operator==(p_name)) {
break;
}
_data = _data->next;
Expand Down Expand Up @@ -419,6 +427,7 @@ StringName::StringName(const String &p_name, bool p_static) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
_data->hash_mixed = hash_mixed;
#ifdef DEBUG_ENABLED
if (unlikely(debug_stringname)) {
// Keep in memory, force static.
Expand All @@ -441,10 +450,11 @@ StringName StringName::search(const char *p_name) {
return StringName();
}

const uint32_t hash = String::hash(p_name);
const uint32_t hash = hash_fmix32(String::hash(p_name));
const uint32_t idx = hash & STRING_TABLE_MASK;

MutexLock lock(mutex);

_Data *_data = _table[idx];

while (_data) {
Expand Down Expand Up @@ -476,10 +486,11 @@ StringName StringName::search(const char32_t *p_name) {
return StringName();
}

const uint32_t hash = String::hash(p_name);
const uint32_t hash = hash_fmix32(String::hash(p_name));
const uint32_t idx = hash & STRING_TABLE_MASK;

MutexLock lock(mutex);

_Data *_data = _table[idx];

while (_data) {
Expand All @@ -500,10 +511,11 @@ StringName StringName::search(const char32_t *p_name) {
StringName StringName::search(const String &p_name) {
ERR_FAIL_COND_V(p_name.is_empty(), StringName());

const uint32_t hash = p_name.hash();
const uint32_t hash = hash_fmix32(p_name.hash());
const uint32_t idx = hash & STRING_TABLE_MASK;

MutexLock lock(mutex);

_Data *_data = _table[idx];

while (_data) {
Expand Down
11 changes: 11 additions & 0 deletions core/string/string_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class StringName {
bool operator!=(const char *p_name) const;

int idx = 0;
uint32_t hash_mixed = 0;
uint32_t hash = 0;
_Data *prev = nullptr;
_Data *next = nullptr;
Expand Down Expand Up @@ -145,6 +146,16 @@ class StringName {
return get_empty_hash();
}
}

// Used by HashMapHasherDefault. Don`t use it as seed to create other hash.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Used by HashMapHasherDefault. Don`t use it as seed to create other hash.
// Returns the hash finalized by mixing. To combine this StringName into a hash, use `hash()` instead.

_FORCE_INLINE_ uint32_t hash_mixed() const {
if (unlikely(_data == nullptr)) {
return get_empty_hash();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not have to be mixed? It should return a plain djb2 hash, no?

}

return _data->hash_mixed;
}

_FORCE_INLINE_ const void *data_unique_pointer() const {
return (void *)_data;
}
Expand Down
9 changes: 9 additions & 0 deletions core/templates/hash_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,12 @@ bool _hashmap_variant_less_than(const Variant &p_left, const Variant &p_right) {
}
return res;
}

// Explicit instantiation.
template class HashMap<int, int>;
template class HashMap<String, int>;
template class HashMap<StringName, bool>;
template class HashMap<StringName, StringName>;
template class HashMap<StringName, String>;
template class HashMap<StringName, Variant>;
template class HashMap<StringName, int>;
Comment on lines +45 to +52
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe explicit HashMap instantiation is out of scope for this PR.
(even though it may be a good idea)

Loading