diff options
author | Adam <Adam@anope.org> | 2016-12-01 09:25:53 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2016-12-01 09:25:53 -0500 |
commit | ca28f9cfcbff0fbdb2afe96f1427245f83db7c47 (patch) | |
tree | ac5de801a4db01a7cb689ec670537ad74c7c53e6 /src | |
parent | 2f512281029fbf4f7ef9832e05804831ad2d9ba2 (diff) |
Allow objects to opt out of gc, don't gc accounts with users logged in
Also store cached state with the field by using Serialize::Storage for
field storage
Diffstat (limited to 'src')
-rw-r--r-- | src/serialize.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/src/serialize.cpp b/src/serialize.cpp index 8f9b91d75..4717c5948 100644 --- a/src/serialize.cpp +++ b/src/serialize.cpp @@ -42,13 +42,25 @@ Object *Serialize::GetID(ID id) return nullptr; } -void Serialize::Clear() +void Serialize::GC() { - std::unordered_map<ID, Object *> o; - objects.swap(o); + for (auto it = objects.begin(); it != objects.end();) + { + Object *o = it->second; - for (const std::pair<ID, Object *> &p : o) - delete p.second; + if (!o->CanGC()) + { + // Wipe internal storage to force refetch + o->Wipe(); + ++it; + continue; + } + + Log(LOG_DEBUG_2) << "garbage collected object " << o->id; + + it = objects.erase(it); + delete o; + } } void Serialize::Unregister(Module *m) @@ -62,6 +74,14 @@ void Serialize::Unregister(Module *m) field->Unregister(); } +void Serialize::Object::Wipe() +{ + for (Serialize::FieldBase *base : s_type->GetFields()) + { + base->Uncache(this); + } +} + std::vector<Edge> Object::GetEdges(TypeBase *type) { std::vector<Edge> refs; @@ -125,8 +145,8 @@ Object::~Object() Log(LOG_DEBUG_2) << "Destructing object id #" << id << " address " << static_cast<void *>(this) << " type " << s_type->GetName(); /* Remove in memory edges */ - cont: - for (const std::pair<TypeBase *, std::vector<Edge>> &p : edges) + std::map<TypeBase *, std::vector<Edge>> copy = edges; + for (const std::pair<TypeBase *, std::vector<Edge>> &p : copy) for (const Edge &edge : p.second) { if (!edge.direction) @@ -139,7 +159,6 @@ Object::~Object() Log(LOG_DEBUG_2) << "Removing edge to object id #" << edge.other->id << " type " << edge.other->GetSerializableType()->GetName() << " on field " << edge.field->serialize_name; this->RemoveEdge(edge.other, edge.field); } - goto cont; } objects.erase(id); @@ -193,12 +212,18 @@ void Object::RemoveEdge(Object *other, FieldBase *field) else Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " -> #" << other->id << " type " << other->GetSerializableType()->GetName(); + if (myedges.empty()) + this->edges.erase(other->GetSerializableType()); + std::vector<Edge> &theiredges = other->edges[this->GetSerializableType()]; it = std::find(theiredges.begin(), theiredges.end(), Edge(this, field, false)); if (it != theiredges.end()) theiredges.erase(it); else Log(LOG_DEBUG_2) << "Unable to locate edge for removal on #" << this->id << " type " << s_type->GetName() << " <- #" << other->id << " type " << other->GetSerializableType()->GetName(); + + if (theiredges.empty()) + other->edges.erase(this->GetSerializableType()); } TypeBase::TypeBase(Module *o, const Anope::string &n) : Service(o, TypeBase::NAME, n), name(n), owner(o) |