From 98c23fd9701273876c1f64a67689daa8168bbffc Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Sun, 4 Mar 2012 22:25:38 -0500 Subject: [PATCH] added a memcached option. It's really slow though. don't use it. --- overviewer.py | 2 ++ overviewer_core/cache.py | 28 +++++++++++++++++++++++++++ overviewer_core/settingsDefinition.py | 4 ++++ overviewer_core/world.py | 8 ++++---- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/overviewer.py b/overviewer.py index e90f386..c04afdc 100755 --- a/overviewer.py +++ b/overviewer.py @@ -350,6 +350,8 @@ dir but you forgot to put quotes around the directory, since it contains spaces. # Set up the cache objects to use caches = [] caches.append(cache.LRUCache(size=100)) + if config.get("memcached_host", False): + caches.append(cache.Memcached(config['memcached_host'])) # TODO: optionally more caching layers here renders = config['renders'] diff --git a/overviewer_core/cache.py b/overviewer_core/cache.py index b2f867d..fb6d8be 100644 --- a/overviewer_core/cache.py +++ b/overviewer_core/cache.py @@ -22,6 +22,7 @@ attribute. """ import functools import logging +import cPickle class LRUCache(object): """A simple, generic, in-memory LRU cache that implements the standard @@ -124,3 +125,30 @@ class LRUCache(object): cache[key] = link +# memcached is an option, but unless your IO costs are really high, it just +# ends up adding overhead and isn't worth it. +try: + import memcache +except ImportError: + class Memcached(object): + def __init__(*args): + raise ImportError("No module 'memcache' found. Please install python-memcached") +else: + class Memcached(object): + def __init__(self, conn='127.0.0.1:11211'): + self.conn = conn + self.mc = memcache.Client([conn], debug=0, pickler=cPickle.Pickler, unpickler=cPickle.Unpickler) + + def __getstate__(self): + return self.conn + def __setstate__(self, conn): + self.__init__(conn) + + def __getitem__(self, key): + v = self.mc.get(key) + if not v: + raise KeyError() + return v + + def __setitem__(self, key, value): + self.mc.set(key, value) diff --git a/overviewer_core/settingsDefinition.py b/overviewer_core/settingsDefinition.py index fded558..e0c876f 100644 --- a/overviewer_core/settingsDefinition.py +++ b/overviewer_core/settingsDefinition.py @@ -86,3 +86,7 @@ worlds = Setting(required=True, validator=make_dictValidator(validateStr, valida outputdir = Setting(required=True, validator=validateOutputDir, default=None) processes = Setting(required=True, validator=int, default=-1) + +# memcached is an option, but unless your IO costs are really high, it just +# ends up adding overhead and isn't worth it. +memcached_host = Setting(required=False, validator=str, default=None) diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 43b11d8..12a5d0a 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -18,6 +18,7 @@ import os import os.path from glob import glob import logging +import hashlib import numpy @@ -581,14 +582,13 @@ class CachedRegionSet(RegionSetWrapper): s += obj.regiondir logging.debug("Initializing a cache with key '%s'", s) - if len(s) > 32: - import hashlib - s = hashlib.md5(s).hexdigest() + + s = hashlib.md5(s).hexdigest() self.key = s def get_chunk(self, x, z): - key = (self.key, x, z) + key = hashlib.md5(repr((self.key, x, z))).hexdigest() for i, cache in enumerate(self.caches): try: retval = cache[key]