From e472079ae99e4ca36a31cb563d19fdb3b2807d9e Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 10 Jun 2010 14:27:16 -0300 Subject: [cachestore] Add versioning Version the cache by checking the SHA1 of the content of all python source files. If the SHA1 hash differs, just regenerate the cache. https://bugzilla.gnome.org/show_bug.cgi?id=568842 --- giscanner/cachestore.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/giscanner/cachestore.py b/giscanner/cachestore.py index e127dda1..70ca00ad 100644 --- a/giscanner/cachestore.py +++ b/giscanner/cachestore.py @@ -1,6 +1,6 @@ # -*- Mode: Python -*- # GObject-Introspection - a framework for introspecting GObject libraries -# Copyright (C) 2008 Johan Dahlin +# Copyright (C) 2008-2010 Johan Dahlin # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -20,11 +20,25 @@ import errno import cPickle +import glob import hashlib import os import shutil +import sys import tempfile +import giscanner + +_CACHE_VERSION_FILENAME = '.cache-version' + +def _get_versionhash(): + toplevel = os.path.dirname(giscanner.__file__) + # Use pyc instead of py to avoid extra IO + sources = glob.glob(os.path.join(toplevel, '*.pyc')) + sources.append(sys.argv[0]) + # Using mtimes is a bit (5x) faster than hashing the file contents + mtimes = (str(os.stat(source).st_mtime) for source in sources) + return hashlib.sha1(''.join(mtimes)).hexdigest() def _get_cachedir(): homedir = os.environ.get('HOME') @@ -59,6 +73,35 @@ class CacheStore(object): raise self._directory = None + self._check_cache_version() + + def _check_cache_version(self): + current_hash = _get_versionhash() + version = os.path.join(self._directory, _CACHE_VERSION_FILENAME) + try: + cache_hash = open(version).read() + except IOError, e: + # File does not exist + if e.errno == errno.ENOENT: + cache_hash = 0 + else: + raise + + if current_hash == cache_hash: + return + + self._clean() + try: + fp = open(version, 'w') + except IOError, e: + # Permission denied + if e.errno == errno.EACCES: + return + else: + raise + + fp.write(current_hash) + def _get_filename(self, filename): # If we couldn't create the directory we're probably # on a read only home directory where we just disable @@ -88,6 +131,12 @@ class CacheStore(object): else: raise + def _clean(self): + for filename in os.listdir(self._directory): + if filename == _CACHE_VERSION_FILENAME: + continue + self._remove_filename(filename) + def store(self, filename, data): store_filename = self._get_filename(filename) if store_filename is None: -- cgit v1.2.1