diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2012-01-04 00:31:27 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2012-01-04 22:34:20 +0100 |
commit | 4f4bce5301ffd8c12aed1b108affa1a75feefb67 (patch) | |
tree | 1607accd70a2c37a9b996f7b42ec926b014cfe5b /buildtools/wafadmin/3rdparty/lru_cache.py | |
parent | 1b45f2aed86dda9fda6e6bcf1c9c7cbdc471c18d (diff) | |
download | samba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.tar.gz samba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.tar.bz2 samba-4f4bce5301ffd8c12aed1b108affa1a75feefb67.zip |
Include waf as an extracted source directory, rather than as a one-in-a-file script.
Diffstat (limited to 'buildtools/wafadmin/3rdparty/lru_cache.py')
-rw-r--r-- | buildtools/wafadmin/3rdparty/lru_cache.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/buildtools/wafadmin/3rdparty/lru_cache.py b/buildtools/wafadmin/3rdparty/lru_cache.py new file mode 100644 index 0000000000..5b00abc29b --- /dev/null +++ b/buildtools/wafadmin/3rdparty/lru_cache.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2011 + +import os, shutil, re +import Options, Build, Logs + +""" +Apply a least recently used policy to the Waf cache. + +For performance reasons, it is called after the build is complete. + +We assume that the the folders are written atomically + +Do export WAFCACHE=/tmp/foo-xyz where xyz represents the cache size in megabytes +If missing, the default cache size will be set to 10GB +""" + +re_num = re.compile('[a-zA-Z_]+(\d+)') + +CACHESIZE = 10*1024*1024*1024 # in bytes +CLEANRATIO = 0.8 +DIRSIZE = 4096 + +def compile(self): + if Options.cache_global and not Options.options.nocache: + try: + os.makedirs(Options.cache_global) + except: + pass + + try: + self.raw_compile() + finally: + if Options.cache_global and not Options.options.nocache: + self.sweep() + +def sweep(self): + global CACHESIZE + CACHEDIR = Options.cache_global + + # get the cache max size from the WAFCACHE filename + re_num = re.compile('[a-zA-Z_]+(\d+)') + val = re_num.sub('\\1', os.path.basename(Options.cache_global)) + try: + CACHESIZE = int(val) + except: + pass + + # map folder names to timestamps + flist = {} + for x in os.listdir(CACHEDIR): + j = os.path.join(CACHEDIR, x) + if os.path.isdir(j) and len(x) == 32: # dir names are md5 hexdigests + flist[x] = [os.stat(j).st_mtime, 0] + + for (x, v) in flist.items(): + cnt = DIRSIZE # each entry takes 4kB + d = os.path.join(CACHEDIR, x) + for k in os.listdir(d): + cnt += os.stat(os.path.join(d, k)).st_size + flist[x][1] = cnt + + total = sum([x[1] for x in flist.values()]) + Logs.debug('lru: Cache size is %r' % total) + + if total >= CACHESIZE: + Logs.debug('lru: Trimming the cache since %r > %r' % (total, CACHESIZE)) + + # make a list to sort the folders by timestamp + lst = [(p, v[0], v[1]) for (p, v) in flist.items()] + lst.sort(key=lambda x: x[1]) # sort by timestamp + lst.reverse() + + while total >= CACHESIZE * CLEANRATIO: + (k, t, s) = lst.pop() + p = os.path.join(CACHEDIR, k) + v = p + '.del' + try: + os.rename(p, v) + except: + # someone already did it + pass + else: + try: + shutil.rmtree(v) + except: + # this should not happen, but who knows? + Logs.warn('If you ever see this message, report it (%r)' % v) + total -= s + del flist[k] + Logs.debug('lru: Total at the end %r' % total) + +Build.BuildContext.raw_compile = Build.BuildContext.compile +Build.BuildContext.compile = compile +Build.BuildContext.sweep = sweep + |