Changed how Tags and Attribues cache and track which objects they use, as suggested in #529.

This commit is contained in:
Griatch 2014-07-05 20:32:08 +02:00
parent 169d0a78f8
commit 680e603c4d
3 changed files with 28 additions and 30 deletions

View file

@ -141,6 +141,7 @@ class CmdClimb(Command):
obj = self.caller.search(self.args.strip()) obj = self.caller.search(self.args.strip())
if not obj: if not obj:
return return
print "obj", "self.obj", obj, self
if obj != self.obj: if obj != self.obj:
self.caller.msg("Try as you might, you cannot climb that.") self.caller.msg("Try as you might, you cannot climb that.")
return return

View file

@ -70,24 +70,24 @@ class AttributeManager(models.Manager):
@_attr_pickled @_attr_pickled
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
return super(AttributeManager, self).get(*args, **kwargs) return super(AttributeManager, self).get(*args, **kwargs)
@_attr_pickled
@_attr_pickled
def filter(self,*args, **kwargs): def filter(self,*args, **kwargs):
return super(AttributeManager, self).filter(*args, **kwargs) return super(AttributeManager, self).filter(*args, **kwargs)
@_attr_pickled
@_attr_pickled
def exclude(self,*args, **kwargs): def exclude(self,*args, **kwargs):
return super(AttributeManager, self).exclude(*args, **kwargs) return super(AttributeManager, self).exclude(*args, **kwargs)
@_attr_pickled
@_attr_pickled
def values(self,*args, **kwargs): def values(self,*args, **kwargs):
return super(AttributeManager, self).values(*args, **kwargs) return super(AttributeManager, self).values(*args, **kwargs)
@_attr_pickled
@_attr_pickled
def values_list(self,*args, **kwargs): def values_list(self,*args, **kwargs):
return super(AttributeManager, self).values_list(*args, **kwargs) return super(AttributeManager, self).values_list(*args, **kwargs)
@_attr_pickled
@_attr_pickled
def exists(self,*args, **kwargs): def exists(self,*args, **kwargs):
return super(AttributeManager, self).exists(*args, **kwargs) return super(AttributeManager, self).exists(*args, **kwargs)

View file

@ -38,7 +38,7 @@ from django.db.models import Q
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from src.utils.idmapper.models import SharedMemoryModel, WeakSharedMemoryModel from src.utils.idmapper.models import SharedMemoryModel
from src.server.caches import get_prop_cache, set_prop_cache from src.server.caches import get_prop_cache, set_prop_cache
#from src.server.caches import set_attr_cache #from src.server.caches import set_attr_cache
@ -237,19 +237,18 @@ class AttributeHandler(object):
def __init__(self, obj): def __init__(self, obj):
"Initialize handler" "Initialize handler"
self.obj = obj self.obj = obj
self._model = "%s.%s" % ContentType.objects.get_for_model(obj).natural_key() self._objid = obj.id
self._model = to_str(ContentType.objects.get_for_model(obj).natural_key()[1])
self._cache = None self._cache = None
def _recache(self): def _recache(self):
if not self._attrtype: "Cache all attributes of this object"
attrtype = Q(db_attrtype=None) | Q(db_attrtype='') query = {"%s__id" % self._model : self._objid,
else: "attribute__db_attrtype" : self._attrtype}
attrtype = Q(db_attrtype=self._attrtype) attrs = [conn.attribute for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)]
self._cache = dict(("%s-%s" % (to_str(attr.db_key).lower(), self._cache = dict(("%s-%s" % (to_str(attr.db_key).lower(),
attr.db_category.lower() if attr.db_category else None), attr) attr.db_category.lower() if conn.attribute.db_category else None),
for attr in getattr(self.obj, self._m2m_fieldname).filter( attr) for attr in attrs)
db_model=self._model).filter(attrtype))
#set_attr_cache(self.obj, self._cache) # currently only for testing
def has(self, key, category=None): def has(self, key, category=None):
""" """
@ -412,7 +411,7 @@ class AttributeHandler(object):
else: else:
# create a new Attribute (no OOB handlers can be notified) # create a new Attribute (no OOB handlers can be notified)
kwargs = {"db_key" : keystr, "db_category" : category, kwargs = {"db_key" : keystr, "db_category" : category,
"db_model" : self._model, "db_attrtype" : self._attrtype, "db_attrtype" : self._attrtype,
"db_value" : None if strattr else to_pickle(new_value), "db_value" : None if strattr else to_pickle(new_value),
"db_strvalue" : value if strattr else None} "db_strvalue" : value if strattr else None}
new_attr = Attribute(**kwargs) new_attr = Attribute(**kwargs)
@ -628,19 +627,18 @@ class TagHandler(object):
and with a tagtype given by self.handlertype and with a tagtype given by self.handlertype
""" """
self.obj = obj self.obj = obj
self._model = "%s.%s" % ContentType.objects.get_for_model(obj).natural_key() self._objid = obj.id
self._model = ContentType.objects.get_for_model(obj).natural_key()[1]
self._cache = None self._cache = None
def _recache(self): def _recache(self):
"Update cache from database field" "Cache all tags of this object"
if not self._tagtype: query = {"%s__id" % self._model : self._objid,
tagtype = Q(db_tagtype='') | Q(db_tagtype__isnull=True) "tag__db_tagtype" : self._tagtype}
else: tagobjs = [conn.tag for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)]
tagtype = Q(db_tagtype=self._tagtype) self._cache = dict(("%s-%s" % (to_str(tagobj.db_key).lower(),
self._cache = dict(("%s-%s" % (tag.db_key, tag.db_category), tag) tagobj.db_category.lower() if tagobj.db_category else None),
for tag in getattr( tagobj) for tagobj in tagobjs)
self.obj, self._m2m_fieldname).filter(
db_model=self._model).filter(tagtype))
def add(self, tag=None, category=None, data=None): def add(self, tag=None, category=None, data=None):
"Add a new tag to the handler. Tag is a string or a list of strings." "Add a new tag to the handler. Tag is a string or a list of strings."
@ -656,7 +654,7 @@ class TagHandler(object):
# will overload data on an existing tag since that is not # will overload data on an existing tag since that is not
# considered part of making the tag unique) # considered part of making the tag unique)
tagobj = Tag.objects.create_tag(key=tagstr, category=category, data=data, tagobj = Tag.objects.create_tag(key=tagstr, category=category, data=data,
model=self._model, tagtype=self._tagtype) tagtype=self._tagtype)
getattr(self.obj, self._m2m_fieldname).add(tagobj) getattr(self.obj, self._m2m_fieldname).add(tagobj)
if self._cache is None: if self._cache is None:
self._recache() self._recache()
@ -709,11 +707,10 @@ class TagHandler(object):
self._recache() self._recache()
if category: if category:
category = category.strip().lower() if category is not None else None category = category.strip().lower() if category is not None else None
matches = getattr(self.obj, self._m2m_fieldname).filter(db_category=category, matches = [tag for tag in self._cache.values() if tag.db_category == category]
db_tagtype=self._tagtype,
db_model=self._model)
else: else:
matches = self._cache.values() matches = self._cache.values()
if matches: if matches:
if return_key_and_category: if return_key_and_category:
# return tuple (key, category) # return tuple (key, category)