6 import Options
, Build
, Logs
9 Apply a least recently used policy to the Waf cache.
11 For performance reasons, it is called after the build is complete.
13 We assume that the the folders are written atomically
15 Do export WAFCACHE=/tmp/foo-xyz where xyz represents the cache size in megabytes
16 If missing, the default cache size will be set to 10GB
19 re_num
= re
.compile('[a-zA-Z_]+(\d+)')
21 CACHESIZE
= 10*1024*1024*1024 # in bytes
26 if Options
.cache_global
and not Options
.options
.nocache
:
28 os
.makedirs(Options
.cache_global
)
35 if Options
.cache_global
and not Options
.options
.nocache
:
40 CACHEDIR
= Options
.cache_global
42 # get the cache max size from the WAFCACHE filename
43 re_num
= re
.compile('[a-zA-Z_]+(\d+)')
44 val
= re_num
.sub('\\1', os
.path
.basename(Options
.cache_global
))
50 # map folder names to timestamps
52 for x
in os
.listdir(CACHEDIR
):
53 j
= os
.path
.join(CACHEDIR
, x
)
54 if os
.path
.isdir(j
) and len(x
) == 32: # dir names are md5 hexdigests
55 flist
[x
] = [os
.stat(j
).st_mtime
, 0]
57 for (x
, v
) in flist
.items():
58 cnt
= DIRSIZE
# each entry takes 4kB
59 d
= os
.path
.join(CACHEDIR
, x
)
60 for k
in os
.listdir(d
):
61 cnt
+= os
.stat(os
.path
.join(d
, k
)).st_size
64 total
= sum([x
[1] for x
in flist
.values()])
65 Logs
.debug('lru: Cache size is %r' % total
)
67 if total
>= CACHESIZE
:
68 Logs
.debug('lru: Trimming the cache since %r > %r' % (total
, CACHESIZE
))
70 # make a list to sort the folders by timestamp
71 lst
= [(p
, v
[0], v
[1]) for (p
, v
) in flist
.items()]
72 lst
.sort(key
=lambda x
: x
[1]) # sort by timestamp
75 while total
>= CACHESIZE
* CLEANRATIO
:
77 p
= os
.path
.join(CACHEDIR
, k
)
82 # someone already did it
88 # this should not happen, but who knows?
89 Logs
.warn('If you ever see this message, report it (%r)' % v
)
92 Logs
.debug('lru: Total at the end %r' % total
)
94 Build
.BuildContext
.raw_compile
= Build
.BuildContext
.compile
95 Build
.BuildContext
.compile = compile
96 Build
.BuildContext
.sweep
= sweep