WIP: refactoring of properties repository

This commit is contained in:
Matthias Koefferlein 2024-12-22 14:23:07 +01:00
parent 9441024fd0
commit 6db836e405
2 changed files with 87 additions and 38 deletions

View File

@ -64,6 +64,8 @@ PropertiesRepository::operator= (const PropertiesRepository &d)
std::pair<bool, property_names_id_type> std::pair<bool, property_names_id_type>
PropertiesRepository::get_id_of_name (const tl::Variant &name) const PropertiesRepository::get_id_of_name (const tl::Variant &name) const
{ {
tl::MutexLocker locker (&m_lock);
std::map <tl::Variant, property_names_id_type>::const_iterator pi = m_propname_ids_by_name.find (name); std::map <tl::Variant, property_names_id_type>::const_iterator pi = m_propname_ids_by_name.find (name);
if (pi == m_propname_ids_by_name.end ()) { if (pi == m_propname_ids_by_name.end ()) {
return std::make_pair (false, property_names_id_type (0)); return std::make_pair (false, property_names_id_type (0));
@ -75,6 +77,8 @@ PropertiesRepository::get_id_of_name (const tl::Variant &name) const
property_names_id_type property_names_id_type
PropertiesRepository::prop_name_id (const tl::Variant &name) PropertiesRepository::prop_name_id (const tl::Variant &name)
{ {
tl::MutexLocker locker (&m_lock);
std::map <tl::Variant, property_names_id_type>::const_iterator pi = m_propname_ids_by_name.find (name); std::map <tl::Variant, property_names_id_type>::const_iterator pi = m_propname_ids_by_name.find (name);
if (pi == m_propname_ids_by_name.end ()) { if (pi == m_propname_ids_by_name.end ()) {
property_names_id_type id = m_propnames_by_id.size (); property_names_id_type id = m_propnames_by_id.size ();
@ -89,6 +93,8 @@ PropertiesRepository::prop_name_id (const tl::Variant &name)
void void
PropertiesRepository::change_properties (property_names_id_type id, const properties_set &new_props) PropertiesRepository::change_properties (property_names_id_type id, const properties_set &new_props)
{ {
tl_assert (id != 0);
// NOTE: change_properties MAY put the property map into a state where there is // NOTE: change_properties MAY put the property map into a state where there is
// more than one property ID per set. For example, 1 and 5 may be valid property // more than one property ID per set. For example, 1 and 5 may be valid property
// ids for the same set. "properties(1)" and "properties(5)" returns the same // ids for the same set. "properties(1)" and "properties(5)" returns the same
@ -96,45 +102,57 @@ PropertiesRepository::change_properties (property_names_id_type id, const proper
const properties_set &old_props = properties (id); const properties_set &old_props = properties (id);
std::map <properties_set, properties_id_type>::const_iterator pi = m_properties_ids_by_set.find (old_props); bool changed = false;
if (pi != m_properties_ids_by_set.end ()) {
// erase the id from the component table {
for (properties_set::const_iterator nv = old_props.begin (); nv != old_props.end (); ++nv) { tl::MutexLocker locker (&m_lock);
if (m_properties_component_table.find (*nv) != m_properties_component_table.end ()) {
properties_id_vector &v = m_properties_component_table [*nv]; std::map <properties_set, properties_id_type>::const_iterator pi = m_properties_ids_by_set.find (old_props);
for (size_t i = 0; i < v.size (); ) { if (pi != m_properties_ids_by_set.end ()) {
if (v[i] == id) {
v.erase (v.begin () + i); // erase the id from the component table
} else { for (properties_set::const_iterator nv = old_props.begin (); nv != old_props.end (); ++nv) {
++i; if (m_properties_component_table.find (*nv) != m_properties_component_table.end ()) {
properties_id_vector &v = m_properties_component_table [*nv];
for (size_t i = 0; i < v.size (); ) {
if (v[i] == id) {
v.erase (v.begin () + i);
} else {
++i;
}
} }
} }
} }
// and insert again
m_properties_ids_by_set.erase (old_props);
m_properties_ids_by_set.insert (std::make_pair (new_props, id));
m_properties_by_id [id] = new_props;
for (properties_set::const_iterator nv = new_props.begin (); nv != new_props.end (); ++nv) {
m_properties_component_table.insert (std::make_pair (*nv, properties_id_vector ())).first->second.push_back (id);
}
changed = true;
} }
// and insert again }
m_properties_ids_by_set.erase (old_props);
m_properties_ids_by_set.insert (std::make_pair (new_props, id));
m_properties_by_id [id] = new_props;
for (properties_set::const_iterator nv = new_props.begin (); nv != new_props.end (); ++nv) {
m_properties_component_table.insert (std::make_pair (*nv, properties_id_vector ())).first->second.push_back (id);
}
if (changed) {
// signal the change of the properties ID's. This way for example, the layer views // signal the change of the properties ID's. This way for example, the layer views
// can recompute the property selectors // can recompute the property selectors
if (mp_state_model) { if (mp_state_model) {
mp_state_model->prop_ids_changed (); mp_state_model->prop_ids_changed ();
} }
} }
} }
void void
PropertiesRepository::change_name (property_names_id_type id, const tl::Variant &new_name) PropertiesRepository::change_name (property_names_id_type id, const tl::Variant &new_name)
{ {
tl::MutexLocker locker (&m_lock);
std::map <property_names_id_type, tl::Variant>::iterator pi = m_propnames_by_id.find (id); std::map <property_names_id_type, tl::Variant>::iterator pi = m_propnames_by_id.find (id);
tl_assert (pi != m_propnames_by_id.end ()); tl_assert (pi != m_propnames_by_id.end ());
pi->second = new_name; pi->second = new_name;
@ -145,46 +163,64 @@ PropertiesRepository::change_name (property_names_id_type id, const tl::Variant
const tl::Variant & const tl::Variant &
PropertiesRepository::prop_name (property_names_id_type id) const PropertiesRepository::prop_name (property_names_id_type id) const
{ {
tl::MutexLocker locker (&m_lock);
return m_propnames_by_id.find (id)->second; return m_propnames_by_id.find (id)->second;
} }
properties_id_type properties_id_type
PropertiesRepository::properties_id (const properties_set &props) PropertiesRepository::properties_id (const properties_set &props)
{ {
std::map <properties_set, properties_id_type>::const_iterator pi = m_properties_ids_by_set.find (props); properties_id_type result;
if (pi == m_properties_ids_by_set.end ()) { bool changed = false;
properties_id_type id = 0; {
if (! m_properties_by_id.empty ()) { tl::MutexLocker locker (&m_lock);
id = (--m_properties_by_id.end ())->first + 1;
}
m_properties_ids_by_set.insert (std::make_pair (props, id));
m_properties_by_id.insert (std::make_pair (id, props));
for (properties_set::const_iterator nv = props.begin (); nv != props.end (); ++nv) {
m_properties_component_table.insert (std::make_pair (*nv, properties_id_vector ())).first->second.push_back (id);
}
std::map <properties_set, properties_id_type>::const_iterator pi = m_properties_ids_by_set.find (props);
if (pi == m_properties_ids_by_set.end ()) {
properties_id_type id = 0;
if (! m_properties_by_id.empty ()) {
id = (--m_properties_by_id.end ())->first + 1;
}
m_properties_ids_by_set.insert (std::make_pair (props, id));
m_properties_by_id.insert (std::make_pair (id, props));
for (properties_set::const_iterator nv = props.begin (); nv != props.end (); ++nv) {
m_properties_component_table.insert (std::make_pair (*nv, properties_id_vector ())).first->second.push_back (id);
}
changed = true;
result = id;
} else {
result = pi->second;
}
}
if (changed) {
// signal the change of the properties ID's. This way for example, the layer views // signal the change of the properties ID's. This way for example, the layer views
// can recompute the property selectors // can recompute the property selectors
if (mp_state_model) { if (mp_state_model) {
mp_state_model->prop_ids_changed (); mp_state_model->prop_ids_changed ();
} }
return id;
} else {
return pi->second;
} }
return result;
} }
const PropertiesRepository::properties_set & const PropertiesRepository::properties_set &
PropertiesRepository::properties (properties_id_type id) const PropertiesRepository::properties (properties_id_type id) const
{ {
static PropertiesRepository::properties_set empty_set;
if (id == 0) {
return empty_set;
}
tl::MutexLocker locker (&m_lock);
iterator p = m_properties_by_id.find (id); iterator p = m_properties_by_id.find (id);
if (p != m_properties_by_id.end ()) { if (p != m_properties_by_id.end ()) {
return p->second; return p->second;
} else { } else {
static PropertiesRepository::properties_set empty_set;
return empty_set; return empty_set;
} }
} }
@ -192,12 +228,19 @@ PropertiesRepository::properties (properties_id_type id) const
bool bool
PropertiesRepository::is_valid_properties_id (properties_id_type id) const PropertiesRepository::is_valid_properties_id (properties_id_type id) const
{ {
if (id == 0) {
return true;
}
tl::MutexLocker locker (&m_lock);
return m_properties_by_id.find (id) != m_properties_by_id.end (); return m_properties_by_id.find (id) != m_properties_by_id.end ();
} }
const PropertiesRepository::properties_id_vector & const PropertiesRepository::properties_id_vector &
PropertiesRepository::properties_ids_by_name_value (const name_value_pair &nv) const PropertiesRepository::properties_ids_by_name_value (const name_value_pair &nv) const
{ {
tl::MutexLocker locker (&m_lock);
std::map <name_value_pair, properties_id_vector>::const_iterator idv = m_properties_component_table.find (nv); std::map <name_value_pair, properties_id_vector>::const_iterator idv = m_properties_component_table.find (nv);
if (idv == m_properties_component_table.end ()) { if (idv == m_properties_component_table.end ()) {
static properties_id_vector empty; static properties_id_vector empty;
@ -210,6 +253,10 @@ PropertiesRepository::properties_ids_by_name_value (const name_value_pair &nv) c
properties_id_type properties_id_type
PropertiesRepository::translate (const PropertiesRepository &rep, properties_id_type id) PropertiesRepository::translate (const PropertiesRepository &rep, properties_id_type id)
{ {
if (id == 0) {
return id;
}
const properties_set &pset = rep.properties (id); const properties_set &pset = rep.properties (id);
// create a new set by mapping the names // create a new set by mapping the names

View File

@ -29,6 +29,7 @@
#include "dbMemStatistics.h" #include "dbMemStatistics.h"
#include "tlVariant.h" #include "tlVariant.h"
#include "tlThreads.h"
#include <vector> #include <vector>
#include <string> #include <string>
@ -237,6 +238,7 @@ private:
std::map <name_value_pair, properties_id_vector> m_properties_component_table; std::map <name_value_pair, properties_id_vector> m_properties_component_table;
db::LayoutStateModel *mp_state_model; db::LayoutStateModel *mp_state_model;
mutable tl::Mutex m_lock;
}; };
/** /**