diff options
author | Adam <Adam@anope.org> | 2013-02-15 14:22:23 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-02-15 19:01:46 -0500 |
commit | d9c18a6072521bb44418830d2ba1cda14389af20 (patch) | |
tree | 2163f6ba24b315a54a15f6419c194fc2236a1455 | |
parent | 73099b82e8619a87f894a0f787a582ee973bd177 (diff) |
Store hashes of the last commit instead of the last commit
-rw-r--r-- | include/anope.h | 12 | ||||
-rw-r--r-- | include/serialize.h | 12 | ||||
-rw-r--r-- | modules/database/db_flatfile.cpp | 9 | ||||
-rw-r--r-- | modules/database/db_sql.cpp | 36 | ||||
-rw-r--r-- | modules/database/db_sql_live.cpp | 28 | ||||
-rw-r--r-- | modules/extra/sql.h | 32 | ||||
-rw-r--r-- | src/serialize.cpp | 19 |
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() |