-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;
}
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() {

View file

@ -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);

View file

@ -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); }
};

View file

@ -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;
}
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;
}
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;
}
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;
}
@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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:

View file

@ -137,7 +137,7 @@ class VisualScriptEditor : public ScriptEditorBase {
Vector<Pair<Variant::Type, String> > args;
};
HashMap<StringName, Ref<StyleBox>, StringNameHasher> node_styles;
HashMap<StringName, Ref<StyleBox> > node_styles;
StringName edited_func;
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;
if (name.begins_with("nodes/")) {
String node_name = name.get_slicec('/', 1);
String what = name.get_slicec('/', 2);

View file

@ -202,12 +202,12 @@ private:
NodePath focus_next;
NodePath focus_prev;
HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override;
HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override;
HashMap<StringName, Ref<StyleBox>, StringNameHasher> style_override;
HashMap<StringName, Ref<Font>, StringNameHasher> font_override;
HashMap<StringName, Color, StringNameHasher> color_override;
HashMap<StringName, int, StringNameHasher> constant_override;
HashMap<StringName, Ref<Texture> > icon_override;
HashMap<StringName, Ref<Shader> > shader_override;
HashMap<StringName, Ref<StyleBox> > style_override;
HashMap<StringName, Ref<Font> > font_override;
HashMap<StringName, Color> color_override;
HashMap<StringName, int> constant_override;
Map<Ref<Font>, int> font_refcount;
} 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) {
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());
}
} else {

View file

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