Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lrucache.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #if !defined(__LRUCACHE_H)
20 #define __LRUCACHE_H
21 
22 #include <mitsuba/mitsuba.h>
23 #include <boost/bimap.hpp>
24 #include <boost/bimap/list_of.hpp>
25 #include <boost/bimap/set_of.hpp>
26 #include <boost/function.hpp>
27 
29 
30 /**
31  * \brief Generic LRU cache implementation
32  *
33  * Based on the bimap implementation by Tim Day
34  * (http://timday.bitbucket.org/lru.html).
35  *
36  * This cache does not support multithreading out of the box -- it
37  * will need to be protected using some form of locking mechanism.
38  *
39  * The original code is under the following license:
40  *
41  * <pre>
42  * Copyright (c) 2010, Tim Day <timday@timday.com>
43  * Permission to use, copy, modify, and/or distribute this software for any
44  * purpose with or without fee is hereby granted, provided that the above
45  * copyright notice and this permission notice appear in all copies.
46  *
47  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
48  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
49  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
50  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
51  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
52  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
53  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54  * </pre>
55  *
56  * \tparam K Key data type
57  * \tparam KComp Key comparator
58  * \tparam V Value data type
59  * \ingroup libcore
60  */
61 template <typename K, typename KComp, typename V> struct LRUCache : public Object {
62 public:
63  typedef int dummy_type;
64 
65  // Bimap with key access on left view, key access
66  // history on right view, and associated value.
67  typedef boost::bimaps::bimap<
68  boost::bimaps::set_of<K, KComp>,
69  boost::bimaps::list_of<dummy_type>,
70  boost::bimaps::with_info<V> > cache_type;
71 
72  LRUCache() { }
73 
74  // Constuctor specifies the cached function and
75  // the maximum number of records to be stored.
76  LRUCache(size_t capacity,
77  const boost::function<V(const K&)>& generatorFunction,
78  const boost::function<void (const V&)>& cleanupFunction = NULL)
79  : m_capacity(capacity), m_generatorFunction(generatorFunction),
80  m_cleanupFunction(cleanupFunction) {
81  SAssert(m_capacity != 0);
82  }
83 
84  virtual ~LRUCache() {
85  typename cache_type::right_iterator
86  src = m_cache.right.begin();
87  if (m_cleanupFunction) {
88  while (src != m_cache.right.end())
89  m_cleanupFunction((*src++).info);
90  }
91  }
92 
93  bool isFull() const {
94  return m_cache.size() == m_capacity;
95  }
96 
97  // Obtain value of the cached function for k
98  V get(const K& k, bool &hit) {
99  // Attempt to find existing record
100  const typename cache_type::left_iterator it
101  = m_cache.left.find(k);
102 
103  if (it == m_cache.left.end()) {
104  // We don't have it:
105  // Evaluate function and create new record
106 
107  const V v = m_generatorFunction(k);
108  insert(k,v);
109  hit = false;
110  return v;
111  } else {
112  // We do have it:
113  // Update the access record view.
114 
115  m_cache.right.relocate(
116  m_cache.right.end(),
117  m_cache.project_right(it)
118  );
119  hit = true;
120  }
121  return it->info;
122  }
123 
124  // Obtain the cached keys, most recently used element
125  // at head, least recently used at tail.
126  // This method is provided purely to support testing.
127  template <typename IT> void get_keys(IT dst) const {
128  typename cache_type::right_const_reverse_iterator
129  src = m_cache.right.rbegin();
130  while (src != m_cache.right.rend())
131  *dst++=(*src++).second;
132  }
133 protected:
134  void insert(const K& k,const V& v) {
135  SAssert(m_cache.size() <= m_capacity);
136  if (m_cache.size() == m_capacity) {
137  if (m_cleanupFunction)
138  m_cleanupFunction(m_cache.right.begin()->info);
139  // If necessary, make space
140  // by purging the least-recently-used element
141  m_cache.right.erase(m_cache.right.begin());
142  }
143 
144  // Create a new record from the key, a dummy and the value
145  m_cache.insert(typename cache_type::value_type(k,0,v));
146  }
147 
148 private:
149  size_t m_capacity;
150  boost::function<V(const K&)> m_generatorFunction;
151  boost::function<void(const V&)> m_cleanupFunction;
152  cache_type m_cache;
153 };
154 
156 
157 #endif /* __LRUCACHE_H */
void insert(const K &k, const V &v)
Definition: lrucache.h:134
boost::bimaps::bimap< boost::bimaps::set_of< K, KComp >, boost::bimaps::list_of< dummy_type >, boost::bimaps::with_info< V > > cache_type
Definition: lrucache.h:70
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
bool isFull() const
Definition: lrucache.h:93
int dummy_type
Definition: lrucache.h:63
virtual ~LRUCache()
Definition: lrucache.h:84
LRUCache()
Definition: lrucache.h:72
#define SAssert(cond)
``Static&#39;&#39; assertion (to be used outside of classes that derive from Object)
Definition: logger.h:79
void get_keys(IT dst) const
Definition: lrucache.h:127
LRUCache(size_t capacity, const boost::function< V(const K &)> &generatorFunction, const boost::function< void(const V &)> &cleanupFunction=NULL)
Definition: lrucache.h:76
Generic LRU cache implementation.
Definition: lrucache.h:61
Parent of all Mitsuba classes.
Definition: object.h:38
#define MTS_NAMESPACE_END
Definition: platform.h:138