From 5e33690f40b4e4860044331fe79bec2cccc43339 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 19 Aug 2012 18:48:29 +0200 Subject: [PATCH] Optimization: Added caching of object contents. This makes obj.contents not have to hit the database at all. So far there are no regressions from this, but time will tell if there are any problems. --- src/commands/default/general.py | 3 ++- src/objects/models.py | 41 ++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/commands/default/general.py b/src/commands/default/general.py index d2614309b2..c00c469c87 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -327,7 +327,8 @@ class CmdDrop(MuxCommand): # we process the results ourselves since we want to sift out only # those in our inventory. results = [obj for obj in results if obj in caller.contents] - # now we send it into the handler. + # now we send it into the error handler (this will output consistent + # error messages if there are problems). obj = AT_SEARCH_RESULT(caller, self.args, results, False) if not obj: return diff --git a/src/objects/models.py b/src/objects/models.py index 0f66b412e4..e85a0486a8 100644 --- a/src/objects/models.py +++ b/src/objects/models.py @@ -268,6 +268,7 @@ class ObjectDB(TypedObject): def __location_set(self, location): "Setter. Allows for self.location = location" try: + old_loc = _GA(self, "location") if location == None or type(location) == ObjectDB: # location is None or a valid object loc = location @@ -281,6 +282,10 @@ class ObjectDB(TypedObject): else: loc = location.dbobj _set_cache(self, "location", loc) + # update the contents of each location + if old_loc: + old_loc.contents_update(self, remove=True) + loc.contents_update(self.typeclass) except Exception: string = "Cannot set location: " string += "%s is not a valid location." @@ -290,8 +295,9 @@ class ObjectDB(TypedObject): #@location.deleter def __location_del(self): "Deleter. Allows for del self.location" - self.db_location = None - self.save() + self.location.contents_update(self, remove=True) + _SA(self, "db_location", None) + _GA(self, "save")() _del_cache(self, "location") location = property(__location_get, __location_set, __location_del) @@ -434,16 +440,42 @@ class ObjectDB(TypedObject): return any(self.sessions) and self.player.is_superuser is_superuser = property(__is_superuser_get) + # contents + + _contents_cache = None #@property def contents_get(self, exclude=None): """ Returns the contents of this object, i.e. all objects that has this object set as its location. This should be publically available. + + exclude is one or more objects to not return """ - return ObjectDB.objects.get_contents(self, excludeobj=exclude) + if _GA(self, "_contents_cache") == None: + # create the cache + _SA(self, "_contents_cache", dict((obj.id, obj) for obj in ObjectDB.objects.get_contents(self))) + if exclude: + exclude = make_iter(exclude) + return [obj for obj in _GA(self, "_contents_cache").values() if obj not in exclude] + return _GA(self, "_contents_cache").values() + #return ObjectDB.objects.get_contents(self, excludeobj=exclude) contents = property(contents_get) + def contents_update(self, obj, remove=False): + """ + Updates the contents property of the object. Called by + self.location_set. + """ + # this creates/updates the cache + _GA(self, "contents") + # set/remove objects from contents cache + cache = _GA(self, "_contents_cache") + if remove and obj.id in cache: + del cache[obj.id] + else: + cache[obj.id] = obj + #@property def __exits_get(self): """ @@ -835,6 +867,9 @@ class ObjectDB(TypedObject): self.clear_exits() # Clear out any non-exit objects located within the object self.clear_contents() + # clear current location's content cache of this object + if self.location: + self.location.contents_update(self, remove=True) # Perform the deletion of the object super(ObjectDB, self).delete() return True