Fix day filter
[cds-indico.git] / indico / util / caching.py
blobc89f37fc98e9a56fabf32f325e9f74b5838b1e19
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from functools import wraps
19 from flask import has_request_context, g, current_app
22 def make_hashable(obj):
23 if isinstance(obj, list):
24 return tuple(obj)
25 elif isinstance(obj, dict):
26 return frozenset((k, make_hashable(v)) for k, v in obj.iteritems())
27 elif hasattr(obj, 'getId'):
28 return obj.__class__.__name__, obj.getId()
29 return obj
32 # http://wiki.python.org/moin/PythonDecoratorLibrary#Alternate_memoize_as_nested_functions
33 # Not thread-safe. Don't use it in places where thread-safety is important!
34 def memoize(obj):
35 cache = {}
37 @wraps(obj)
38 def memoizer(*args, **kwargs):
39 key = (make_hashable(args), make_hashable(kwargs))
40 if key not in cache:
41 cache[key] = obj(*args, **kwargs)
42 return cache[key]
43 return memoizer
46 def memoize_request(f):
47 """Memoizes a function during the current request"""
48 @wraps(f)
49 def memoizer(*args, **kwargs):
50 if not has_request_context() or current_app.config['TESTING']:
51 # No memoization outside request context
52 return f(*args, **kwargs)
54 try:
55 cache = g.memoize_cache
56 except AttributeError:
57 g.memoize_cache = cache = {}
59 key = (f.__name__, make_hashable(args), make_hashable(kwargs))
60 if key not in cache:
61 cache[key] = f(*args, **kwargs)
62 return cache[key]
64 return memoizer