summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2016-12-01 09:25:53 -0500
committerAdam <Adam@anope.org>2016-12-01 09:25:53 -0500
commitca28f9cfcbff0fbdb2afe96f1427245f83db7c47 (patch)
treeac5de801a4db01a7cb689ec670537ad74c7c53e6 /include
parent2f512281029fbf4f7ef9832e05804831ad2d9ba2 (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 'include')
-rw-r--r--include/bots.h6
-rw-r--r--include/modules/chanserv/chanaccess.h10
-rw-r--r--include/modules/nickserv/account.h2
-rw-r--r--include/opertype.h4
-rw-r--r--include/serialize.h106
-rw-r--r--include/xline.h4
6 files changed, 77 insertions, 55 deletions
diff --git a/include/bots.h b/include/bots.h
index 0fa35e8a1..928107ef3 100644
--- a/include/bots.h
+++ b/include/bots.h
@@ -133,9 +133,9 @@ class BotInfo : public Serialize::Object
{
friend class BotInfoType;
- Anope::string nick, user, host, realname;
- time_t created = 0;
- bool operonly = false;
+ Serialize::Storage<Anope::string> nick, user, host, realname;
+ Serialize::Storage<time_t> created;
+ Serialize::Storage<bool> operonly;
public:
static constexpr const char *const NAME = "botinfo";
diff --git a/include/modules/chanserv/chanaccess.h b/include/modules/chanserv/chanaccess.h
index 2d3aec96b..faaf48175 100644
--- a/include/modules/chanserv/chanaccess.h
+++ b/include/modules/chanserv/chanaccess.h
@@ -34,10 +34,10 @@ class CoreExport ChanAccess : public Serialize::Object
public:
static constexpr const char *const NAME = "access";
- Channel *channel = nullptr;
- Serialize::Object *object = nullptr;
- Anope::string creator, mask;
- time_t last_seen = 0, created = 0;
+ Serialize::Storage<Channel *> channel;
+ Serialize::Storage<Serialize::Object *> object;
+ Serialize::Storage<Anope::string> creator, mask;
+ Serialize::Storage<time_t> last_seen, created;
using Serialize::Object::Object;
@@ -131,4 +131,4 @@ class CoreExport ChanAccess : public Serialize::Object
}
};
-} // namespace ChanServ \ No newline at end of file
+} // namespace ChanServ
diff --git a/include/modules/nickserv/account.h b/include/modules/nickserv/account.h
index 511b1220f..ebe1061b6 100644
--- a/include/modules/nickserv/account.h
+++ b/include/modules/nickserv/account.h
@@ -30,7 +30,7 @@ class CoreExport Account : public Serialize::Object
public:
static constexpr const char *const NAME = "account";
-#warning "this gets lost"
+#warning "move lastmail to a field"
/* Last time an email was sent to this user */
time_t lastmail = 0;
/* Users online now logged into this account */
diff --git a/include/opertype.h b/include/opertype.h
index 2d36dfad6..46361d576 100644
--- a/include/opertype.h
+++ b/include/opertype.h
@@ -27,8 +27,8 @@ class Oper : public Serialize::Object
{
friend class OperBlockType;
- Anope::string name, password, certfp, host, vhost, type;
- bool require_oper = false;
+ Serialize::Storage<Anope::string> name, password, certfp, host, vhost, type;
+ Serialize::Storage<bool> require_oper;
public:
static constexpr const char *const NAME = "oper";
diff --git a/include/serialize.h b/include/serialize.h
index 0b420bff0..67be96c0c 100644
--- a/include/serialize.h
+++ b/include/serialize.h
@@ -36,6 +36,8 @@ namespace Serialize
template<typename, typename> class Field;
template<typename, typename> class ObjectField;
+ template<typename> class Storage;
+
template<typename T, typename> class Type;
template<typename T> class Reference;
@@ -60,7 +62,7 @@ namespace Serialize
template<typename T>
inline T New();
- extern void Clear();
+ extern void GC();
extern void Unregister(Module *);
@@ -216,16 +218,21 @@ class CoreExport Serialize::Object : public Extensible, public virtual Base
* which can unset (vs set to the default value)
*/
bool HasFieldS(const Anope::string &name);
+
+ /** Whether or not the object can be garbage collected.
+ * Should be true unless your object holds in-memory only
+ * state.
+ */
+ virtual bool CanGC() { return true; }
+
+ void Wipe();
};
class CoreExport Serialize::TypeBase : public Service
{
Anope::string name;
- /* Owner of this type. Used for placing objects of this type in separate databases
- * based on what module, if any, owns it.
- */
- Module *owner;
+ Module *owner = nullptr;
public:
static constexpr const char *NAME = "typebase";
@@ -396,6 +403,8 @@ class Serialize::FieldBase : public Service
*/
virtual void UnsetS(Object *) anope_abstract;
+ virtual void Uncache(Object *) anope_abstract;
+
virtual Anope::string GetTypeName() { return ""; }
};
@@ -426,18 +435,21 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
*/
ExtensibleItem<T> *ext = nullptr;
- /** Field pointer to storage in the TypeImpl object for
- * this field.
+ /** Storage pointer in the TypeImpl object for this field.
*/
- T TypeImpl::*field = nullptr;
+ Serialize::Storage<T> TypeImpl::*storage = nullptr;
protected:
/** Set the value of a field in storage
*/
void Set_(TypeImpl *object, const T &value)
{
- if (field != nullptr)
- object->*field = value;
+ if (storage != nullptr)
+ {
+ Serialize::Storage<T> &s = object->*storage;
+ s.t = value;
+ s.cached = true;
+ }
else if (ext != nullptr)
ext->Set(object, value);
else
@@ -448,8 +460,8 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
*/
T* Get_(TypeImpl *object)
{
- if (field != nullptr)
- return &(object->*field);
+ if (storage != nullptr)
+ return &(object->*storage).t;
else if (ext != nullptr)
return ext->Get(object);
else
@@ -460,8 +472,12 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
*/
void Unset_(TypeImpl *object)
{
- if (field != nullptr)
- object->*field = T();
+ if (storage != nullptr)
+ {
+ Serialize::Storage<T> &s = object->*storage;
+ s.t = T();
+ s.cached = false;
+ }
else if (ext != nullptr)
ext->Unset(object);
else
@@ -473,7 +489,7 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
*/
bool HasField_(TypeImpl *object)
{
- if (field != nullptr)
+ if (storage != nullptr)
return true;
else if (ext != nullptr)
return ext->HasExt(object);
@@ -481,13 +497,17 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
throw CoreException("No field or ext");
}
- public:
- CommonFieldBase(Serialize::TypeBase *t, const Anope::string &n, bool d)
- : FieldTypeBase<T>(t->GetOwner(), n, t->GetName(), d)
+ bool Cached_(TypeImpl *object)
{
- ext = new ExtensibleItem<T>(t->GetOwner(), t->GetName(), n);
+ if (storage != nullptr)
+ return (object->*storage).cached;
+ else if (ext != nullptr)
+ return ext->HasExt(object);
+ else
+ throw CoreException("No field or ext");
}
+ public:
CommonFieldBase(Module *creator, const Anope::string &n, bool d)
: FieldTypeBase<T>(creator, n, TypeImpl::NAME, d)
{
@@ -496,10 +516,10 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
CommonFieldBase(Serialize::TypeBase *t,
const Anope::string &n,
- T TypeImpl::*f,
+ Serialize::Storage<T> TypeImpl::*s,
bool d)
: FieldTypeBase<T>(t->GetOwner(), n, t->GetName(), d)
- , field(f)
+ , storage(s)
{
}
@@ -547,6 +567,11 @@ class Serialize::CommonFieldBase : public FieldTypeBase<T>
return this->HasField_(s);
}
+
+ void Uncache(Object *s)
+ {
+ Unset_(Upcast(s));
+ }
};
/** Class for all fields that aren't to other serializable objects
@@ -555,15 +580,11 @@ template<typename TypeImpl, typename T>
class Serialize::Field : public CommonFieldBase<TypeImpl, T>
{
public:
- Field(TypeBase *t, const Anope::string &n) : CommonFieldBase<TypeImpl, T>(t, n, false)
- {
- }
-
Field(Module *creator, const Anope::string &n) : CommonFieldBase<TypeImpl, T>(creator, n, false)
{
}
- Field(TypeBase *t, const Anope::string &n, T TypeImpl::*f) : CommonFieldBase<TypeImpl, T>(t, n, f, false)
+ Field(TypeBase *t, const Anope::string &n, Serialize::Storage<T> TypeImpl::*f) : CommonFieldBase<TypeImpl, T>(t, n, f, false)
{
}
@@ -571,8 +592,8 @@ class Serialize::Field : public CommonFieldBase<TypeImpl, T>
{
T* t = this->Get_(s);
- // If we have a non-default value for this field it is up to date and cached
- if (t && *t != T())
+ // If this field is cached
+ if (t && this->Cached_(s))
return *t;
// Query modules
@@ -583,19 +604,14 @@ class Serialize::Field : public CommonFieldBase<TypeImpl, T>
// module returned us data, so we unserialize it
T t2 = this->Unserialize(value);
- // should cache the default value somehow, but can't differentiate not cached from cached and default
-
- // Cache
+ // set & cache
OnSet(s, t2);
this->Set_(s, t2);
return t2;
}
- if (t)
- return *t;
-
- return T();
+ return t ? *t : T();
}
void SetFieldS(Object *s, const T &value) override
@@ -696,12 +712,12 @@ template<typename TypeImpl, typename T>
class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
{
public:
- ObjectField(TypeBase *t, const Anope::string &n, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, d)
+ ObjectField(Module *creator, const Anope::string &n) : CommonFieldBase<TypeImpl, T>(creator, n, false)
{
this->is_object = true;
}
- ObjectField(TypeBase *t, const Anope::string &n, T TypeImpl::*field, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, field, d)
+ ObjectField(TypeBase *t, const Anope::string &n, Serialize::Storage<T> TypeImpl::*field, bool d = false) : CommonFieldBase<TypeImpl, T>(t, n, field, d)
{
this->is_object = true;
}
@@ -709,7 +725,8 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
T GetField(TypeImpl *s)
{
T *t = this->Get_(s);
- if (t && *t != nullptr)
+
+ if (t && this->Cached_(s))
return *t;
Anope::string type;
@@ -732,10 +749,7 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
return t2;
}
- if (t)
- return *t;
-
- return T();
+ return t ? *t : T();
}
void SetFieldS(Object *s, const T &value) override
@@ -818,6 +832,14 @@ class Serialize::ObjectField : public CommonFieldBase<TypeImpl, T>
};
template<typename T>
+class Serialize::Storage
+{
+ public:
+ T t = T();
+ bool cached = false;
+};
+
+template<typename T>
T Serialize::GetObject()
{
std::vector<T> v = GetObjects<T>();
diff --git a/include/xline.h b/include/xline.h
index 05ddbe2d3..cc4a98d66 100644
--- a/include/xline.h
+++ b/include/xline.h
@@ -32,8 +32,8 @@ class CoreExport XLine : public Serialize::Object
friend class XLineType;
- Anope::string type, mask, by, reason, id;
- time_t created = 0, expires = 0;
+ Serialize::Storage<Anope::string> type, mask, by, reason, id;
+ Serialize::Storage<time_t> created, expires;
public:
static constexpr const char *const NAME = "xline";