-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
This commit is contained in:
Juan Linietsky 2018-07-02 15:08:35 -03:00
parent ecee0c92ff
commit 2dc738ce27
14 changed files with 94 additions and 52 deletions

View File

@ -248,9 +248,9 @@ void ClassDB::set_current_api(APIType p_api) {
current_api = p_api; current_api = p_api;
} }
HashMap<StringName, ClassDB::ClassInfo, StringNameHasher> ClassDB::classes; HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
HashMap<StringName, StringName, StringNameHasher> ClassDB::resource_base_extensions; HashMap<StringName, StringName> ClassDB::resource_base_extensions;
HashMap<StringName, StringName, StringNameHasher> ClassDB::compat_classes; HashMap<StringName, StringName> ClassDB::compat_classes;
ClassDB::ClassInfo::ClassInfo() { ClassDB::ClassInfo::ClassInfo() {

View File

@ -114,10 +114,10 @@ public:
APIType api; APIType api;
ClassInfo *inherits_ptr; ClassInfo *inherits_ptr;
HashMap<StringName, MethodBind *, StringNameHasher> method_map; HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, int, StringNameHasher> constant_map; HashMap<StringName, int> constant_map;
HashMap<StringName, List<StringName> > enum_map; HashMap<StringName, List<StringName> > enum_map;
HashMap<StringName, MethodInfo, StringNameHasher> signal_map; HashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list; List<PropertyInfo> property_list;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
List<StringName> constant_order; List<StringName> constant_order;
@ -126,7 +126,7 @@ public:
List<MethodInfo> virtual_methods; List<MethodInfo> virtual_methods;
StringName category; StringName category;
#endif #endif
HashMap<StringName, PropertySetGet, StringNameHasher> property_setget; HashMap<StringName, PropertySetGet> property_setget;
StringName inherits; StringName inherits;
StringName name; StringName name;
@ -143,9 +143,9 @@ public:
} }
static RWLock *lock; static RWLock *lock;
static HashMap<StringName, ClassInfo, StringNameHasher> classes; static HashMap<StringName, ClassInfo> classes;
static HashMap<StringName, StringName, StringNameHasher> resource_base_extensions; static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName, StringNameHasher> compat_classes; static HashMap<StringName, StringName> compat_classes;
#ifdef DEBUG_METHODS_ENABLED #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); static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);

View File

@ -33,6 +33,8 @@
#include "math_defs.h" #include "math_defs.h"
#include "math_funcs.h" #include "math_funcs.h"
#include "node_path.h"
#include "string_db.h"
#include "typedefs.h" #include "typedefs.h"
#include "ustring.h" #include "ustring.h"
@ -131,6 +133,7 @@ static inline uint64_t make_uint64_t(T p_in) {
} }
struct HashMapHasherDefault { struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); } 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 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); } 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 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 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 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); } //static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
}; };

View File

@ -32,10 +32,7 @@
#include "print_string.h" #include "print_string.h"
uint32_t NodePath::hash() const { void NodePath::_update_hash_cache() const {
if (!data)
return 0;
uint32_t h = data->absolute ? 1 : 0; uint32_t h = data->absolute ? 1 : 0;
int pc = data->path.size(); int pc = data->path.size();
@ -49,13 +46,15 @@ uint32_t NodePath::hash() const {
h = h ^ ssn[i].hash(); h = h ^ ssn[i].hash();
} }
return h; data->hash_cache_valid = true;
data->hash_cache = h;
} }
void NodePath::prepend_period() { void NodePath::prepend_period() {
if (data->path.size() && data->path[0].operator String() != ".") { if (data->path.size() && data->path[0].operator String() != ".") {
data->path.insert(0, "."); 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) if (data->absolute != p_path.data->absolute)
return false; 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; return false;
}
if (data->subpath.size() != p_path.data->subpath.size()) int subpath_size = data->subpath.size();
if (subpath_size != p_path.data->subpath.size()) {
return false; 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();
if (data->path[i] != p_path.data->path[i]) for (int i = 0; i < path_size; i++) {
if (l_path_ptr[i] != r_path_ptr[i])
return false; 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();
if (data->subpath[i] != p_path.data->subpath[i]) for (int i = 0; i < subpath_size; i++) {
if (l_subpath_ptr[i] != r_subpath_ptr[i])
return false; return false;
} }
@ -286,6 +297,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
data->absolute = p_absolute; data->absolute = p_absolute;
data->path = p_path; data->path = p_path;
data->has_slashes = true; data->has_slashes = true;
data->hash_cache_valid = false;
} }
NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) { 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->path = p_path;
data->subpath = p_subpath; data->subpath = p_subpath;
data->has_slashes = true; data->has_slashes = true;
data->hash_cache_valid = false;
} }
void NodePath::simplify() { void NodePath::simplify() {
@ -324,6 +337,7 @@ void NodePath::simplify() {
} }
} }
} }
data->hash_cache_valid = false;
} }
NodePath NodePath::simplified() const { NodePath NodePath::simplified() const {
@ -396,6 +410,7 @@ NodePath::NodePath(const String &p_path) {
data->absolute = absolute ? true : false; data->absolute = absolute ? true : false;
data->has_slashes = has_slashes; data->has_slashes = has_slashes;
data->subpath = subpath; data->subpath = subpath;
data->hash_cache_valid = false;
if (slices == 0) if (slices == 0)
return; return;

View File

@ -47,11 +47,15 @@ class NodePath {
StringName concatenated_subpath; StringName concatenated_subpath;
bool absolute; bool absolute;
bool has_slashes; bool has_slashes;
mutable bool hash_cache_valid;
mutable uint32_t hash_cache;
}; };
Data *data; mutable Data *data;
void unref(); void unref();
void _update_hash_cache() const;
public: public:
_FORCE_INLINE_ StringName get_sname() const { _FORCE_INLINE_ StringName get_sname() const {
@ -78,7 +82,14 @@ public:
NodePath get_parent() const; 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; operator String() const;
bool is_empty() const; bool is_empty() const;

View File

@ -31,6 +31,7 @@
#ifndef OBJECT_H #ifndef OBJECT_H
#define OBJECT_H #define OBJECT_H
#include "hash_map.h"
#include "list.h" #include "list.h"
#include "map.h" #include "map.h"
#include "os/rw_lock.h" #include "os/rw_lock.h"
@ -451,7 +452,7 @@ private:
Signal() { lock = 0; } Signal() { lock = 0; }
}; };
HashMap<StringName, Signal, StringNameHasher> signal_map; HashMap<StringName, Signal> signal_map;
List<Connection> connections; List<Connection> connections;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
SafeRefCount _lock_index; SafeRefCount _lock_index;

View File

@ -225,15 +225,20 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
continue; continue;
Variant p = get(E->get().name).duplicate(true); Variant p = get(E->get().name);
if (p.get_type() == Variant::OBJECT && p_subresources) {
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; RES sr = p;
if (sr.is_valid()) if (sr.is_valid()) {
p = sr->duplicate(true); 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); return Ref<Resource>(r);

View File

@ -31,7 +31,6 @@
#ifndef STRING_DB_H #ifndef STRING_DB_H
#define STRING_DB_H #define STRING_DB_H
#include "hash_map.h"
#include "os/mutex.h" #include "os/mutex.h"
#include "safe_refcount.h" #include "safe_refcount.h"
#include "ustring.h" #include "ustring.h"
@ -168,11 +167,6 @@ public:
~StringName(); ~StringName();
}; };
struct StringNameHasher {
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string) { return p_string.hash(); }
};
StringName _scs_create(const char *p_chr); StringName _scs_create(const char *p_chr);
#endif #endif

View File

@ -3417,8 +3417,15 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
Variant Variant::duplicate(bool deep) const { Variant Variant::duplicate(bool deep) const {
switch (type) { switch (type) {
// case OBJECT: case OBJECT: {
// return operator Object *()->duplicate(); 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: case DICTIONARY:
return operator Dictionary().duplicate(deep); return operator Dictionary().duplicate(deep);
case ARRAY: case ARRAY:

View File

@ -137,7 +137,7 @@ class VisualScriptEditor : public ScriptEditorBase {
Vector<Pair<Variant::Type, String> > args; Vector<Pair<Variant::Type, String> > args;
}; };
HashMap<StringName, Ref<StyleBox>, StringNameHasher> node_styles; HashMap<StringName, Ref<StyleBox> > node_styles;
StringName edited_func; StringName edited_func;
void _update_graph_connections(); void _update_graph_connections();

View File

@ -1036,6 +1036,7 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
String name = p_name; String name = p_name;
if (name.begins_with("nodes/")) { if (name.begins_with("nodes/")) {
String node_name = name.get_slicec('/', 1); String node_name = name.get_slicec('/', 1);
String what = name.get_slicec('/', 2); String what = name.get_slicec('/', 2);

View File

@ -202,12 +202,12 @@ private:
NodePath focus_next; NodePath focus_next;
NodePath focus_prev; NodePath focus_prev;
HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override; HashMap<StringName, Ref<Texture> > icon_override;
HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override; HashMap<StringName, Ref<Shader> > shader_override;
HashMap<StringName, Ref<StyleBox>, StringNameHasher> style_override; HashMap<StringName, Ref<StyleBox> > style_override;
HashMap<StringName, Ref<Font>, StringNameHasher> font_override; HashMap<StringName, Ref<Font> > font_override;
HashMap<StringName, Color, StringNameHasher> color_override; HashMap<StringName, Color> color_override;
HashMap<StringName, int, StringNameHasher> constant_override; HashMap<StringName, int> constant_override;
Map<Ref<Font>, int> font_refcount; Map<Ref<Font>, int> font_refcount;
} data; } data;

View File

@ -1934,8 +1934,9 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) { if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) {
Resource *res = Object::cast_to<Resource>(value); Resource *res = Object::cast_to<Resource>(value);
if (res) // Duplicate only if it's a resource if (res) { // Duplicate only if it's a resource
current_node->set(name, res->duplicate()); current_node->set(name, res->duplicate());
}
} else { } else {

View File

@ -55,12 +55,12 @@ class Theme : public Resource {
void _unref_font(Ref<Font> p_sc); void _unref_font(Ref<Font> p_sc);
void _emit_theme_changed(); void _emit_theme_changed();
HashMap<StringName, HashMap<StringName, Ref<Texture>, StringNameHasher>, StringNameHasher> icon_map; HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map;
HashMap<StringName, HashMap<StringName, Ref<StyleBox>, StringNameHasher>, StringNameHasher> style_map; HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map;
HashMap<StringName, HashMap<StringName, Ref<Font>, StringNameHasher>, StringNameHasher> font_map; HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map;
HashMap<StringName, HashMap<StringName, Ref<Shader>, StringNameHasher>, StringNameHasher> shader_map; HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map;
HashMap<StringName, HashMap<StringName, Color, StringNameHasher>, StringNameHasher> color_map; HashMap<StringName, HashMap<StringName, Color> > color_map;
HashMap<StringName, HashMap<StringName, int, StringNameHasher>, StringNameHasher> constant_map; HashMap<StringName, HashMap<StringName, int> > constant_map;
protected: protected:
bool _set(const StringName &p_name, const Variant &p_value); bool _set(const StringName &p_name, const Variant &p_value);