33 #ifndef GRAPHLAB_CACHE_HPP
34 #define GRAPHLAB_CACHE_HPP
38 #include <boost/functional/hash.hpp>
40 #include <boost/bimap.hpp>
41 #include <boost/bimap/list_of.hpp>
42 #include <boost/bimap/unordered_set_of.hpp>
45 #include <graphlab/logger/assertions.hpp>
64 template<
typename Key,
typename Value>
68 typedef Value value_type;
70 typedef boost::bimaps::bimap<
71 boost::bimaps::unordered_set_of<key_type>,
72 boost::bimaps::list_of<value_type> >
75 typedef typename cache_map_type::iterator iterator_type;
76 typedef typename cache_map_type::value_type pair_type;
79 mutable cache_map_type cache_map;
84 lru(
size_t cache_reserve = 1024) {
85 cache_map.left.rehash(cache_reserve);
89 size_t size()
const {
return cache_map.size(); }
90 size_t empty()
const {
return size() == 0; }
92 iterator_type begin() {
return cache_map.begin(); }
93 iterator_type end() {
return cache_map.end(); }
95 std::pair<key_type, value_type> evict() {
96 ASSERT_FALSE(cache_map.empty());
97 typedef typename cache_map_type::right_iterator iterator_type;
98 iterator_type iter = cache_map.right.begin();
99 const std::pair<key_type, value_type>
100 result(iter->get_left(), iter->get_right());
101 cache_map.right.erase(iter);
105 std::pair<bool, value_type> evict(
const key_type& key) {
106 typedef typename cache_map_type::left_iterator iterator_type;
107 iterator_type iter = cache_map.left.find(key);
108 if(iter == cache_map.left.end())
109 return std::make_pair(
false, value_type());
110 const value_type result = iter->get_right();
111 cache_map.left.erase(iter);
112 return std::make_pair(
true, result);
115 bool evict(
const key_type& key, value_type& ret_value) {
116 typedef typename cache_map_type::left_iterator iterator_type;
117 iterator_type iter = cache_map.left.find(key);
118 if(iter == cache_map.left.end())
return false;
119 ret_value = iter->get_right();
120 cache_map.left.erase(iter);
125 bool contains(
const key_type& key)
const {
126 typedef typename cache_map_type::left_const_iterator iterator_type;
127 iterator_type iter = cache_map.left.find(key);
128 return iter != cache_map.left.end();
137 value_type& operator[](
const key_type& key) {
138 typedef typename cache_map_type::left_iterator iterator_type;
139 iterator_type iter = cache_map.left.find(key);
140 if(iter != cache_map.left.end()) {
142 cache_map.right.relocate(cache_map.right.end(),
143 cache_map.project_right(iter));
144 return iter->get_right();
148 typedef typename cache_map_type::value_type pair_type;
149 cache_map.insert(pair_type(key, value_type()));
150 return cache_map.left[key];
154 const value_type& operator[](
const key_type& key)
const {
155 typedef typename cache_map_type::left_const_iterator iterator_type;
156 iterator_type iter = cache_map.left.find(key);
157 if(iter != cache_map.left.end()) {
159 cache_map.right.relocate(cache_map.right.end(),
160 cache_map.project_right(iter));
161 return iter->get_right();
163 logstream(
LOG_FATAL) <<
"Key not found!" << std::endl;
167 bool get(
const key_type& key, value_type& ret_value) {
168 typedef typename cache_map_type::left_iterator iterator_type;
169 iterator_type iter = cache_map.left.find(key);
170 if(iter != cache_map.left.end()) {
171 ret_value = iter->get_right();
173 cache_map.right.relocate(cache_map.right.end(),
174 cache_map.project_right(iter));
185 template<
typename Key,
typename Value>
188 typedef Key key_type;
189 typedef Value value_type;
193 std::vector<key_type>
keys;
194 std::vector<value_type>
values;
195 std::vector<bool> is_set;
197 boost::hash<key_type> hash_function;
201 associative(
size_t cache_size = 1024) :
203 is_set(cache_size), size_(0) { }
205 size_t size() {
return size_; }
208 bool evict_slot(
const key_type& key,
209 key_type& ret_key, value_type& ret_value) {
210 const size_t index = hash_function(key) %
keys.size();
212 ret_key =
keys[index]; ret_value =
values[index];
213 is_set[index] =
false;
218 std::pair<bool, value_type> evict(
const key_type& key) {
219 const size_t index = hash_function(key) %
keys.size();
220 if(is_set[index] && key[index] == key) {
221 is_set[index] =
false;
222 return std::make_pair(
true,
values[index]);
224 return std::make_pair(
false, value_type());
228 bool evict(
const key_type& key, value_type& ret_value) {
229 const size_t index = hash_function(key) %
keys.size();
230 if(is_set[index] && key[index] == key) {
231 is_set[index] =
false;
232 ret_value =
values[index];
239 bool contains(
const key_type& key)
const {
240 const size_t index = hash_function(key) %
keys.size();
241 return is_set[index] &&
keys[index] == key;
245 value_type& operator[](
const key_type& key) {
246 const size_t index = hash_function(key) %
keys.size();
248 ASSERT_TRUE(key ==
keys[index]);
252 is_set[index] =
true;
253 values[index] = value_type();
258 const value_type& operator[](
const key_type& key)
const {
259 const size_t index = hash_function(key) %
keys.size();
261 ASSERT_TRUE(key ==
keys[index]);
264 logstream(
LOG_FATAL) <<
"Key not found!" << std::endl;
269 bool get(
const key_type& key, value_type& ret_value) {
270 const size_t index = hash_function(key) %
keys.size();
271 if(is_set[index] &&
keys[index] == key) {
272 ret_value =
values[index];