summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/anope.h12
-rw-r--r--include/serialize.h12
-rw-r--r--modules/database/db_flatfile.cpp9
-rw-r--r--modules/database/db_sql.cpp36
-rw-r--r--modules/database/db_sql_live.cpp28
-rw-r--r--modules/extra/sql.h32
-rw-r--r--src/serialize.cpp19
7 files changed, 75 insertions, 73 deletions
diff --git a/include/anope.h b/include/anope.h
index 1b978a8ba..6878a333c 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -308,7 +308,7 @@ namespace Anope
inline const string operator+(const char *_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
inline const string operator+(const std::string &_str, const string &str) { string tmp(_str); tmp += str; return tmp; }
- struct hash
+ struct hash_ci
{
inline size_t operator()(const string &s) const
{
@@ -316,6 +316,14 @@ namespace Anope
}
};
+ struct hash_cs
+ {
+ inline size_t operator()(const string &s) const
+ {
+ return std::tr1::hash<std::string>()(s.str());
+ }
+ };
+
struct compare
{
inline bool operator()(const string &s1, const string &s2) const
@@ -325,7 +333,7 @@ namespace Anope
};
template<typename T> class map : public std::map<string, T, ci::less> { };
- template<typename T> class hash_map : public std::tr1::unordered_map<string, T, hash, compare> { };
+ template<typename T> class hash_map : public std::tr1::unordered_map<string, T, hash_ci, compare> { };
static const char *const compiled = __TIME__ " " __DATE__;
diff --git a/include/serialize.h b/include/serialize.h
index f495cdd73..23c865688 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -33,8 +33,7 @@ namespace Serialize
virtual std::iostream& operator[](const Anope::string &key) = 0;
virtual std::set<Anope::string> KeySet() const { throw CoreException("Not supported"); }
-
- virtual bool IsEqual(Data *other) { throw CoreException("Not supported"); }
+ virtual size_t Hash() const { throw CoreException("Not supported"); }
virtual void SetType(const Anope::string &key, Type t) { }
virtual Type GetType(const Anope::string &key) const { return DT_TEXT; }
@@ -65,12 +64,11 @@ class CoreExport Serializable : public virtual Base
private:
/* Iterator into serializable_items */
std::list<Serializable *>::iterator s_iter;
- /* The last serialized form of this object commited to the database */
- Serialize::Data *last_commit;
+ /* The hash of the last serialized form of this object commited to the database */
+ size_t last_commit;
/* The last time this object was commited to the database */
time_t last_commit_time;
- Serializable();
protected:
Serializable(const Anope::string &serialize_type);
Serializable(const Serializable &);
@@ -87,8 +85,8 @@ class CoreExport Serializable : public virtual Base
*/
void QueueUpdate();
- bool IsCached(Serialize::Data *);
- void UpdateCache(Serialize::Data *);
+ bool IsCached(Serialize::Data &);
+ void UpdateCache(Serialize::Data &);
bool IsTSCached();
void UpdateTS();
diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp
index a2db7c1b4..848356574 100644
--- a/modules/database/db_flatfile.cpp
+++ b/modules/database/db_flatfile.cpp
@@ -71,6 +71,15 @@ class LoadData : public Serialize::Data
keys.insert(it->first);
return keys;
}
+
+ size_t Hash() const anope_override
+ {
+ size_t hash = 0;
+ for (std::map<Anope::string, Anope::string>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ if (!it->second.empty())
+ hash ^= Anope::hash_cs()(it->second);
+ return hash;
+ }
void Reset()
{
diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp
index 74166d6dc..3bb0efde2 100644
--- a/modules/database/db_sql.cpp
+++ b/modules/database/db_sql.cpp
@@ -104,14 +104,11 @@ class DBSQL : public Module, public Pipe
if (this->sql)
{
- Data *data = new Data();
- obj->Serialize(*data);
+ Data data;
+ obj->Serialize(data);
if (obj->IsCached(data))
- {
- delete data;
continue;
- }
obj->UpdateCache(data);
@@ -119,12 +116,18 @@ class DBSQL : public Module, public Pipe
if (!s_type)
continue;
- std::vector<Query> create = this->sql->CreateTable(this->prefix + s_type->GetName(), *data);
+ std::vector<Query> create = this->sql->CreateTable(this->prefix + s_type->GetName(), data);
for (unsigned i = 0; i < create.size(); ++i)
this->RunBackground(create[i]);
- Query insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, *data);
- this->RunBackground(insert, new ResultSQLSQLInterface(this, obj));
+ Query insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, data);
+ if (this->loaded)
+ this->RunBackground(insert, new ResultSQLSQLInterface(this, obj));
+ else
+ /* If we aren't loading these objects then we are importing them, so don't do asynchronous
+ * queries in case for some reason the core has to shut down, it will cut short the import
+ */
+ this->sql->RunQuery(insert);
}
}
@@ -209,13 +212,13 @@ class DBSQL : public Module, public Pipe
for (int j = 0; j < res.Rows(); ++j)
{
- Data *data = new Data();
+ Data data;
const std::map<Anope::string, Anope::string> &row = res.Row(j);
for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
- (*data)[rit->first] << rit->second;
+ data[rit->first] << rit->second;
- Serializable *obj = sb->Unserialize(NULL, *data);
+ Serializable *obj = sb->Unserialize(NULL, data);
try
{
if (obj)
@@ -227,9 +230,14 @@ class DBSQL : public Module, public Pipe
}
if (obj)
- obj->UpdateCache(data); /* We know this is the most up to date copy */
- else
- delete data;
+ {
+ Data data2;
+ /* The Unserialize operation is destructive so rebuild the data for UpdateCache */
+ for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
+ if (rit->first != "id" && rit->first != "timestamp")
+ data2[rit->first] << rit->second;
+ obj->UpdateCache(data2); /* We know this is the most up to date copy */
+ }
}
}
};
diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp
index d50653912..9a2ebd0b7 100644
--- a/modules/database/db_sql_live.cpp
+++ b/modules/database/db_sql_live.cpp
@@ -89,14 +89,11 @@ class DBMySQL : public Module, public Pipe
if (obj && this->SQL)
{
- Data *data = new Data();
- obj->Serialize(*data);
+ Data data;
+ obj->Serialize(data);
if (obj->IsCached(data))
- {
- delete data;
continue;
- }
obj->UpdateCache(data);
@@ -104,11 +101,11 @@ class DBMySQL : public Module, public Pipe
if (!s_type)
continue;
- std::vector<Query> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), *data);
+ std::vector<Query> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), data);
for (unsigned i = 0; i < create.size(); ++i)
this->RunQueryResult(create[i]);
- Result res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, *data));
+ Result res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, data));
if (res.GetID() && obj->id != res.GetID())
{
/* In this case obj is new, so place it into the object map */
@@ -199,17 +196,17 @@ class DBMySQL : public Module, public Pipe
}
else
{
- Data *data = new Data();
+ Data data;
for (std::map<Anope::string, Anope::string>::const_iterator it = row.begin(), it_end = row.end(); it != it_end; ++it)
- (*data)[it->first] << it->second;
+ data[it->first] << it->second;
Serializable *s = NULL;
std::map<unsigned int, Serializable *>::iterator it = obj->objects.find(id);
if (it != obj->objects.end())
s = it->second;
- Serializable *new_s = obj->Unserialize(s, *data);
+ Serializable *new_s = obj->Unserialize(s, data);
if (new_s)
{
// If s == new_s then s->id == new_s->id
@@ -217,14 +214,17 @@ class DBMySQL : public Module, public Pipe
{
new_s->id = id;
obj->objects[id] = new_s;
- new_s->UpdateCache(data); /* We know this is the most up to date copy */
+
+ Data data2;
+ /* The Unserialize operation is destructive so rebuild the data for UpdateCache */
+ for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit)
+ if (rit->first != "id" && rit->first != "timestamp")
+ data2[rit->first] << rit->second;
+ new_s->UpdateCache(data2); /* We know this is the most up to date copy */
}
- else
- delete data;
}
else
{
- delete data;
delete s;
}
}
diff --git a/modules/extra/sql.h b/modules/extra/sql.h
index a62f2fba3..1c8fdd3aa 100644
--- a/modules/extra/sql.h
+++ b/modules/extra/sql.h
@@ -31,45 +31,31 @@ namespace SQL
std::set<Anope::string> KeySet() const anope_override
{
std::set<Anope::string> keys;
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
keys.insert(it->first);
return keys;
}
- bool IsEqual(Serialize::Data *other) anope_override
+ size_t Hash() const anope_override
{
- try
- {
- Data *o = anope_dynamic_static_cast<Data *>(other);
-
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = o->data.begin(), it_end = o->data.end(); it != it_end; ++it)
- if (!this->data.count(it->first) || it->second->str() != this->data[it->first]->str())
- return false;
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
- if (!o->data.count(it->first) || it->second->str() != o->data[it->first]->str())
- return false;
-
- return true;
- }
- catch (const CoreException &ex)
- {
- Log(LOG_DEBUG) << ex.GetReason();
- }
-
- return false;
+ size_t hash = 0;
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ if (!it->second->str().empty())
+ hash ^= Anope::hash_cs()(it->second->str());
+ return hash;
}
std::map<Anope::string, std::iostream *> GetData() const
{
std::map<Anope::string, std::iostream *> d;
- for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
d[it->first] = it->second;
return d;
}
void Clear()
{
- for (std::map<Anope::string, std::stringstream *>::iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
+ for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it)
delete it->second;
this->data.clear();
}
diff --git a/src/serialize.cpp b/src/serialize.cpp
index 8828965b5..ee300a441 100644
--- a/src/serialize.cpp
+++ b/src/serialize.cpp
@@ -35,12 +35,7 @@ void Serialize::RegisterTypes()
memo("Memo", Memo::Unserialize), xline("XLine", XLine::Unserialize);
}
-Serializable::Serializable() : last_commit(NULL), last_commit_time(0), id(0)
-{
- throw CoreException("Default Serializable constructor?");
-}
-
-Serializable::Serializable(const Anope::string &serialize_type) : last_commit(NULL), last_commit_time(0), id(0)
+Serializable::Serializable(const Anope::string &serialize_type) : last_commit(0), last_commit_time(0), id(0)
{
if (SerializableItems == NULL)
SerializableItems = new std::list<Serializable *>();
@@ -54,7 +49,7 @@ Serializable::Serializable(const Anope::string &serialize_type) : last_commit(NU
FOREACH_MOD(I_OnSerializableConstruct, OnSerializableConstruct(this));
}
-Serializable::Serializable(const Serializable &other) : last_commit(NULL), last_commit_time(0), id(0)
+Serializable::Serializable(const Serializable &other) : last_commit(0), last_commit_time(0), id(0)
{
SerializableItems->push_back(this);
this->s_iter = SerializableItems->end();
@@ -70,7 +65,6 @@ Serializable::~Serializable()
FOREACH_MOD(I_OnSerializableDestruct, OnSerializableDestruct(this));
SerializableItems->erase(this->s_iter);
- delete last_commit;
}
Serializable &Serializable::operator=(const Serializable &)
@@ -87,15 +81,14 @@ void Serializable::QueueUpdate()
FOREACH_MOD(I_OnSerializeCheck, OnSerializeCheck(this->GetSerializableType()));
}
-bool Serializable::IsCached(Serialize::Data *data)
+bool Serializable::IsCached(Serialize::Data &data)
{
- return this->last_commit && this->last_commit->IsEqual(data);
+ return this->last_commit == data.Hash();
}
-void Serializable::UpdateCache(Serialize::Data *data)
+void Serializable::UpdateCache(Serialize::Data &data)
{
- delete this->last_commit;
- this->last_commit = data;
+ this->last_commit = data.Hash();
}
bool Serializable::IsTSCached()