Changed propcache back to a simple dict. Working on content cache, not working yet.

This commit is contained in:
Griatch 2013-05-30 00:49:47 +02:00
parent fb3259be8c
commit 41235c25a2
3 changed files with 114 additions and 60 deletions

View file

@ -306,27 +306,16 @@ class ObjectDB(TypedObject):
del_field_cache(self, "sessid") del_field_cache(self, "sessid")
sessid = property(__sessid_get, __sessid_set, __sessid_del) sessid = property(__sessid_get, __sessid_set, __sessid_del)
# location property (wraps db_location) def _db_location_handler(self, new_value, old_value=None):
#@property "This handles changes to the db_location field."
def __location_get(self): print "db_location_handler:", new_value, old_value
"Getter. Allows for value = self.location."
loc = get_field_cache(self, "location")
if loc:
return _GA(loc, "typeclass")
return None
#@location.setter
def __location_set(self, location):
"Setter. Allows for self.location = location"
try: try:
old_loc = _GA(self, "location") old_loc = old_value
if ObjectDB.objects.dbref(location): # new_value can be dbref, typeclass or dbmodel
# dbref search if ObjectDB.objects.dbref(new_value, reqhash=False):
loc = ObjectDB.objects.dbref_search(location) loc = ObjectDB.objects.dbref_search(new_value)
loc = loc and _GA(loc, "dbobj") # this should not fail if new_value is valid.
elif location and type(location) != ObjectDB: loc = _GA(loc, "dbobj")
loc = _GA(location, "dbobj")
else:
loc = location
# recursive location check # recursive location check
def is_loc_loop(loc, depth=0): def is_loc_loop(loc, depth=0):
@ -340,32 +329,85 @@ class ObjectDB(TypedObject):
except RuntimeWarning: pass except RuntimeWarning: pass
# set the location # set the location
set_field_cache(self, "location", loc) _SA(self, "db_location", loc)
# update the contents of each location # update the contents of each location
if old_loc: if old_loc:
_GA(_GA(old_loc, "dbobj"), "contents_update")() _GA(_GA(old_loc, "dbobj"), "contents_update")(self, remove=True)
if loc: if loc:
_GA(loc, "contents_update")() _GA(loc, "contents_update")(self)
except RuntimeError: except RuntimeError:
string = "Cannot set location, " string = "Cannot set location, "
string += "%s.location = %s would create a location-loop." % (self.key, loc) string += "%s.location = %s would create a location-loop." % (self.key, new_value)
_GA(self, "msg")(_(string)) _GA(self, "msg")(_(string))
logger.log_trace(string) logger.log_trace(string)
raise RuntimeError(string) raise RuntimeError(string)
except Exception, e: except Exception, e:
string = "Cannot set location (%s): " % str(e) string = "Cannot set location (%s): " % str(e)
string += "%s is not a valid location." % location string += "%s is not a valid location." % new_value
_GA(self, "msg")(_(string)) _GA(self, "msg")(_(string))
logger.log_trace(string) logger.log_trace(string)
raise Exception(string) raise Exception(string)
#@location.deleter
def __location_del(self): ## location property (wraps db_location)
"Deleter. Allows for del self.location" ##@property
_GA(self, "location").contents_update() #def __location_get(self):
_SA(self, "db_location", None) # "Getter. Allows for value = self.location."
_GA(self, "save")() # loc = get_field_cache(self, "location")
del_field_cache(self, "location") # if loc:
location = property(__location_get, __location_set, __location_del) # return _GA(loc, "typeclass")
# return None
##@location.setter
#def __location_set(self, location):
# "Setter. Allows for self.location = location"
# try:
# old_loc = _GA(self, "location")
# if ObjectDB.objects.dbref(location):
# # dbref search
# loc = ObjectDB.objects.dbref_search(location)
# loc = loc and _GA(loc, "dbobj")
# elif location and type(location) != ObjectDB:
# loc = _GA(location, "dbobj")
# else:
# loc = location
# # recursive location check
# def is_loc_loop(loc, depth=0):
# "Recursively traverse the target location to make sure we are not in it."
# if depth > 10: return
# elif loc == self: raise RuntimeError
# elif loc == None: raise RuntimeWarning # just to quickly get out
# return is_loc_loop(_GA(loc, "db_location"), depth+1)
# # check so we don't create a location loop - if so, RuntimeError will be raised.
# try: is_loc_loop(loc)
# except RuntimeWarning: pass
# # set the location
# set_field_cache(self, "location", loc)
# # update the contents of each location
# if old_loc:
# _GA(_GA(old_loc, "dbobj"), "contents_update")()
# if loc:
# _GA(loc, "contents_update")()
# except RuntimeError:
# string = "Cannot set location, "
# string += "%s.location = %s would create a location-loop." % (self.key, loc)
# _GA(self, "msg")(_(string))
# logger.log_trace(string)
# raise RuntimeError(string)
# except Exception, e:
# string = "Cannot set location (%s): " % str(e)
# string += "%s is not a valid location." % location
# _GA(self, "msg")(_(string))
# logger.log_trace(string)
# raise Exception(string)
##@location.deleter
#def __location_del(self):
# "Deleter. Allows for del self.location"
# _GA(self, "location").contents_update()
# _SA(self, "db_location", None)
# _GA(self, "save")()
# del_field_cache(self, "location")
#location = property(__location_get, __location_set, __location_del)
# home property (wraps db_home) # home property (wraps db_home)
#@property #@property
@ -522,19 +564,26 @@ class ObjectDB(TypedObject):
exclude = make_iter(exclude) exclude = make_iter(exclude)
if cont == None: if cont == None:
cont = _GA(self, "contents_update")() cont = _GA(self, "contents_update")()
return [obj for obj in cont if obj not in exclude] return [obj for obj in cont.values() if obj not in exclude]
contents = property(contents_get) contents = property(contents_get)
def contents_update(self): def contents_update(self, obj=None, remove=False):
""" """
Updates the contents property of the object with a new Updates the contents property of the object
object Called by
self.location_set.
obj - add - object to add to content list
remove (true/false) - remove obj from content list remove object to remove from content list
""" """
cont = ObjectDB.objects.get_contents(self) cont = get_prop_cache(self, "_contents")
if not cont:
cont = {}
if obj:
if remove:
cont.pop(self.dbid, None)
else:
cont[self.dbid] = obj
else:
cont = dict((o.dbid, o) for o in ObjectDB.objects.get_contents(self))
set_prop_cache(self, "_contents", cont) set_prop_cache(self, "_contents", cont)
return cont return cont

View file

@ -2,6 +2,8 @@
Central caching module. Central caching module.
""" """
from collections import defaultdict
from django.dispatch import Signal from django.dispatch import Signal
from django.core.cache import get_cache from django.core.cache import get_cache
#from django.db.models.signals import pre_save, pre_delete, post_init #from django.db.models.signals import pre_save, pre_delete, post_init
@ -18,12 +20,13 @@ _DA = object.__delattr__
_FIELD_CACHE = get_cache("field_cache") _FIELD_CACHE = get_cache("field_cache")
_ATTR_CACHE = get_cache("attr_cache") _ATTR_CACHE = get_cache("attr_cache")
_PROP_CACHE = get_cache("prop_cache") #_PROP_CACHE = get_cache("prop_cache")
_PROP_CACHE = defaultdict(dict)
# make sure caches are empty at startup # make sure caches are empty at startup
_FIELD_CACHE.clear() _FIELD_CACHE.clear()
_ATTR_CACHE.clear() _ATTR_CACHE.clear()
_PROP_CACHE.clear() #_PROP_CACHE.clear()
#------------------------------------------------------------ #------------------------------------------------------------
# Cache key hash generation # Cache key hash generation
@ -106,7 +109,7 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
old_value = _FIELD_CACHE.get(hid) if hid else None old_value = _FIELD_CACHE.get(hid) if hid else None
# the handler may modify the stored value in various ways # the handler may modify the stored value in various ways
# don't catch exceptions, the handler must work! # don't catch exceptions, the handler must work!
new_value = handler(instance, new_value, oldval=old_value) new_value = handler(new_value, old_value=old_value)
# we re-assign this to the field, save() will pick it up from there # we re-assign this to the field, save() will pick it up from there
_SA(instance, fieldname, new_value) _SA(instance, fieldname, new_value)
if hid: if hid:
@ -170,24 +173,28 @@ def get_prop_cache(obj, propname):
hid = hashid(obj, "-%s" % propname) hid = hashid(obj, "-%s" % propname)
if hid: if hid:
#print "get_prop_cache", hid, propname, _PROP_CACHE.get(hid, None) #print "get_prop_cache", hid, propname, _PROP_CACHE.get(hid, None)
return _PROP_CACHE.get(hid, None) return _PROP_CACHE[hid].get(propname, None)
def set_prop_cache(obj, propname, propvalue): def set_prop_cache(obj, propname, propvalue):
"Set property cache" "Set property cache"
hid = hashid(obj, "-%s" % propname) hid = hashid(obj, "-%s" % propname)
if hid: if hid:
#print "set_prop_cache", propname, propvalue #print "set_prop_cache", propname, propvalue
_PROP_CACHE.set(hid, propvalue) _PROP_CACHE[hid][propname] = propvalue
#_PROP_CACHE.set(hid, propvalue)
def del_prop_cache(obj, propname): def del_prop_cache(obj, propname):
"Delete element from property cache" "Delete element from property cache"
hid = hashid(obj, "-%s" % propname) hid = hashid(obj, "-%s" % propname)
if hid: if hid and propname in _PROP_CACHE[hid]:
_PROP_CACHE.delete(hid) del _PROP_CACHE[hid][propname]
#_PROP_CACHE.delete(hid)
def flush_prop_cache(): def flush_prop_cache():
"Clear property cache" "Clear property cache"
_PROP_CACHE.clear() global _PROP_CACHE
_PROP_CACHE = defaultdict(dict)
#_PROP_CACHE.clear()
#_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE #_ENABLE_LOCAL_CACHES = settings.GAME_CACHE_TYPE
@ -491,7 +498,7 @@ def del_field_cache(obj, name):
#def set_attr_cache(obj, attrname, attrobj): #def set_attr_cache(obj, attrname, attrobj):
# pass # pass
#def del_attr_cache(obj, attrname): #def del_attr_cache(obj, attrname):
# pass # passk
#def flush_attr_cache(obj=None): #def flush_attr_cache(obj=None):
# pass # pass

View file

@ -474,34 +474,32 @@ class TypedObject(SharedMemoryModel):
#@property #@property
def __name_get(self): def __name_get(self):
"Getter. Allows for value = self.name" "Getter. Allows for value = self.name"
return get_field_cache(self, "key") return self.key
#@name.setter #@name.sette
def __name_set(self, value): def __name_set(self, value):
"Setter. Allows for self.name = value" "Setter. Allows for self.name = value"
set_field_cache(self, "key", value) self.key = value
#@name.deleter #@name.deleter
def __name_del(self): def __name_del(self):
"Deleter. Allows for del self.name" "Deleter. Allows for del self.name"
raise Exception("Cannot delete name!") raise Exception("Cannot delete name!")
name = property(__name_get, __name_set, __name_del) name = property(__name_get, __name_set, __name_del)
# typeclass_path property # typeclass_path property - we don't cache this.
#@property #@property
def __typeclass_path_get(self): def __typeclass_path_get(self):
"Getter. Allows for value = self.typeclass_path" "Getter. Allows for value = self.typeclass_path"
return get_field_cache(self, "typeclass_path") return _GA(self, "db_typeclass_path")#get_field_cache(self, "typeclass_path")
#@typeclass_path.setter #@typeclass_path.setter
def __typeclass_path_set(self, value): def __typeclass_path_set(self, value):
"Setter. Allows for self.typeclass_path = value" "Setter. Allows for self.typeclass_path = value"
set_field_cache(self, "typeclass_path", value) _SA(self, "db_typeclass_path", value)
_SA(self, "_cached_typeclass", None) _GA(self, "save")(update_fields=["db_typeclass_path"])
#@typeclass_path.deleter #@typeclass_path.deleter
def __typeclass_path_del(self): def __typeclass_path_del(self):
"Deleter. Allows for del self.typeclass_path" "Deleter. Allows for del self.typeclass_path"
self.db_typeclass_path = "" self.db_typeclass_path = ""
self.save() _GA(self, "save")(update_fields=["db_typeclass_path"])
del_field_cache(self, "typeclass_path")
_SA(self, "_cached_typeclass", None)
typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del) typeclass_path = property(__typeclass_path_get, __typeclass_path_set, __typeclass_path_del)
# date_created property # date_created property