diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-07-02 15:08:35 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-07-02 15:08:35 -0300 |
commit | 2dc738ce2733757631a4ccf413a92411c4400246 (patch) | |
tree | de7d355ea5a2e90e2dbebd6044517cf2b63b090a /core | |
parent | ecee0c92ff86911fa50e745b4ab98196e0d2afe4 (diff) |
-Fixes to how hashing happened, now StringName and NodePath use default hasher, this was leading to some severe slowdown in scenarios
-Fixes to some duplication scenarios for instanced scenes
Diffstat (limited to 'core')
-rw-r--r-- | core/class_db.cpp | 6 | ||||
-rw-r--r-- | core/class_db.h | 14 | ||||
-rw-r--r-- | core/hashfuncs.h | 7 | ||||
-rw-r--r-- | core/node_path.cpp | 37 | ||||
-rw-r--r-- | core/node_path.h | 15 | ||||
-rw-r--r-- | core/object.h | 3 | ||||
-rw-r--r-- | core/resource.cpp | 17 | ||||
-rw-r--r-- | core/string_db.h | 6 | ||||
-rw-r--r-- | core/variant_op.cpp | 11 |
9 files changed, 78 insertions, 38 deletions
diff --git a/core/class_db.cpp b/core/class_db.cpp index 59b100e282..f97eaf6099 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -248,9 +248,9 @@ void ClassDB::set_current_api(APIType p_api) { current_api = p_api; } -HashMap<StringName, ClassDB::ClassInfo, StringNameHasher> ClassDB::classes; -HashMap<StringName, StringName, StringNameHasher> ClassDB::resource_base_extensions; -HashMap<StringName, StringName, StringNameHasher> ClassDB::compat_classes; +HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes; +HashMap<StringName, StringName> ClassDB::resource_base_extensions; +HashMap<StringName, StringName> ClassDB::compat_classes; ClassDB::ClassInfo::ClassInfo() { diff --git a/core/class_db.h b/core/class_db.h index 2c77ffe65f..f1d1879236 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -114,10 +114,10 @@ public: APIType api; ClassInfo *inherits_ptr; - HashMap<StringName, MethodBind *, StringNameHasher> method_map; - HashMap<StringName, int, StringNameHasher> constant_map; + HashMap<StringName, MethodBind *> method_map; + HashMap<StringName, int> constant_map; HashMap<StringName, List<StringName> > enum_map; - HashMap<StringName, MethodInfo, StringNameHasher> signal_map; + HashMap<StringName, MethodInfo> signal_map; List<PropertyInfo> property_list; #ifdef DEBUG_METHODS_ENABLED List<StringName> constant_order; @@ -126,7 +126,7 @@ public: List<MethodInfo> virtual_methods; StringName category; #endif - HashMap<StringName, PropertySetGet, StringNameHasher> property_setget; + HashMap<StringName, PropertySetGet> property_setget; StringName inherits; StringName name; @@ -143,9 +143,9 @@ public: } static RWLock *lock; - static HashMap<StringName, ClassInfo, StringNameHasher> classes; - static HashMap<StringName, StringName, StringNameHasher> resource_base_extensions; - static HashMap<StringName, StringName, StringNameHasher> compat_classes; + static HashMap<StringName, ClassInfo> classes; + static HashMap<StringName, StringName> resource_base_extensions; + static HashMap<StringName, StringName> compat_classes; #ifdef DEBUG_METHODS_ENABLED static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount); diff --git a/core/hashfuncs.h b/core/hashfuncs.h index ae99fa39c8..735e679d1e 100644 --- a/core/hashfuncs.h +++ b/core/hashfuncs.h @@ -33,6 +33,8 @@ #include "math_defs.h" #include "math_funcs.h" +#include "node_path.h" +#include "string_db.h" #include "typedefs.h" #include "ustring.h" @@ -131,6 +133,7 @@ static inline uint64_t make_uint64_t(T p_in) { } struct HashMapHasherDefault { + static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); } static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); } static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); } @@ -145,6 +148,10 @@ struct HashMapHasherDefault { static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; } static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; } static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; } + + static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); } + static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); } + //static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); } }; diff --git a/core/node_path.cpp b/core/node_path.cpp index 64983fc091..487d5ee8c6 100644 --- a/core/node_path.cpp +++ b/core/node_path.cpp @@ -32,10 +32,7 @@ #include "print_string.h" -uint32_t NodePath::hash() const { - - if (!data) - return 0; +void NodePath::_update_hash_cache() const { uint32_t h = data->absolute ? 1 : 0; int pc = data->path.size(); @@ -49,13 +46,15 @@ uint32_t NodePath::hash() const { h = h ^ ssn[i].hash(); } - return h; + data->hash_cache_valid = true; + data->hash_cache = h; } void NodePath::prepend_period() { if (data->path.size() && data->path[0].operator String() != ".") { data->path.insert(0, "."); + data->hash_cache_valid = false; } } @@ -114,21 +113,33 @@ bool NodePath::operator==(const NodePath &p_path) const { if (data->absolute != p_path.data->absolute) return false; - if (data->path.size() != p_path.data->path.size()) + int path_size = data->path.size(); + + if (path_size != p_path.data->path.size()) { return false; + } + + int subpath_size = data->subpath.size(); - if (data->subpath.size() != p_path.data->subpath.size()) + if (subpath_size != p_path.data->subpath.size()) { return false; + } - for (int i = 0; i < data->path.size(); i++) { + const StringName *l_path_ptr = data->path.ptr(); + const StringName *r_path_ptr = p_path.data->path.ptr(); + + for (int i = 0; i < path_size; i++) { - if (data->path[i] != p_path.data->path[i]) + if (l_path_ptr[i] != r_path_ptr[i]) return false; } - for (int i = 0; i < data->subpath.size(); i++) { + const StringName *l_subpath_ptr = data->subpath.ptr(); + const StringName *r_subpath_ptr = p_path.data->subpath.ptr(); + + for (int i = 0; i < subpath_size; i++) { - if (data->subpath[i] != p_path.data->subpath[i]) + if (l_subpath_ptr[i] != r_subpath_ptr[i]) return false; } @@ -286,6 +297,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) { data->absolute = p_absolute; data->path = p_path; data->has_slashes = true; + data->hash_cache_valid = false; } NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) { @@ -301,6 +313,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p data->path = p_path; data->subpath = p_subpath; data->has_slashes = true; + data->hash_cache_valid = false; } void NodePath::simplify() { @@ -324,6 +337,7 @@ void NodePath::simplify() { } } } + data->hash_cache_valid = false; } NodePath NodePath::simplified() const { @@ -396,6 +410,7 @@ NodePath::NodePath(const String &p_path) { data->absolute = absolute ? true : false; data->has_slashes = has_slashes; data->subpath = subpath; + data->hash_cache_valid = false; if (slices == 0) return; diff --git a/core/node_path.h b/core/node_path.h index 288f39721f..71235029af 100644 --- a/core/node_path.h +++ b/core/node_path.h @@ -47,11 +47,15 @@ class NodePath { StringName concatenated_subpath; bool absolute; bool has_slashes; + mutable bool hash_cache_valid; + mutable uint32_t hash_cache; }; - Data *data; + mutable Data *data; void unref(); + void _update_hash_cache() const; + public: _FORCE_INLINE_ StringName get_sname() const { @@ -78,7 +82,14 @@ public: NodePath get_parent() const; - uint32_t hash() const; + _FORCE_INLINE_ uint32_t hash() const { + if (!data) + return 0; + if (!data->hash_cache_valid) { + _update_hash_cache(); + } + return data->hash_cache; + } operator String() const; bool is_empty() const; diff --git a/core/object.h b/core/object.h index badb432885..8dc3426d1d 100644 --- a/core/object.h +++ b/core/object.h @@ -31,6 +31,7 @@ #ifndef OBJECT_H #define OBJECT_H +#include "hash_map.h" #include "list.h" #include "map.h" #include "os/rw_lock.h" @@ -451,7 +452,7 @@ private: Signal() { lock = 0; } }; - HashMap<StringName, Signal, StringNameHasher> signal_map; + HashMap<StringName, Signal> signal_map; List<Connection> connections; #ifdef DEBUG_ENABLED SafeRefCount _lock_index; diff --git a/core/resource.cpp b/core/resource.cpp index 4cca73be5d..87ff4d3c2a 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -225,15 +225,20 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) continue; - Variant p = get(E->get().name).duplicate(true); - if (p.get_type() == Variant::OBJECT && p_subresources) { + Variant p = get(E->get().name); + + if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) { + p = p.duplicate(p_subresources); //does not make a long of sense but should work? + } else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) { RES sr = p; - if (sr.is_valid()) - p = sr->duplicate(true); - } + if (sr.is_valid()) { + r->set(E->get().name, sr->duplicate(p_subresources)); + } + } else { - r->set(E->get().name, p); + r->set(E->get().name, p); + } } return Ref<Resource>(r); diff --git a/core/string_db.h b/core/string_db.h index 01d1ca4033..965385b136 100644 --- a/core/string_db.h +++ b/core/string_db.h @@ -31,7 +31,6 @@ #ifndef STRING_DB_H #define STRING_DB_H -#include "hash_map.h" #include "os/mutex.h" #include "safe_refcount.h" #include "ustring.h" @@ -168,11 +167,6 @@ public: ~StringName(); }; -struct StringNameHasher { - - static _FORCE_INLINE_ uint32_t hash(const StringName &p_string) { return p_string.hash(); } -}; - StringName _scs_create(const char *p_chr); #endif diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 621af2dfb7..983c3e18bc 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -3417,8 +3417,15 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { Variant Variant::duplicate(bool deep) const { switch (type) { - // case OBJECT: - // return operator Object *()->duplicate(); + case OBJECT: { + if (deep && !_get_obj().ref.is_null()) { + Ref<Resource> resource = _get_obj().ref; + if (resource.is_valid()) { + return resource->duplicate(true); + } + } + return *this; + } break; case DICTIONARY: return operator Dictionary().duplicate(deep); case ARRAY: |