Now the ID management is more fast
[cassata.biscotto.git] / src / MemoryCache.cpp
blob37d9cc101f3dbd9d8053f581c311c0bca291915f
1 //vim: expandtab:shiftwidth=4:fileencoding=utf-8 :
3 /* Copyright ® 2008 Fulvio Satta
5 If you want contact me, send an email to Yota_VGA@users.sf.net
7 This file is part of Biscotto
9 Biscotto is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 Biscotto is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "MemoryCache.h"
25 #include <limits>
27 unsigned int MemoryCache::search(CacheObject &obj) const
29 CacheObject *i_obj = object(obj);
30 if (i_obj == NULL)
31 return 0;
32 return i_obj->position();
35 CacheObject &MemoryCache::first() const
37 return *order.rbegin()->second;
40 CacheObject &MemoryCache::last() const
42 return *order.begin()->second;
45 CacheObject *MemoryCache::object(CacheObject &object) const
47 typeof(objects.find(&object)) obj = objects.find(&object);
48 if (obj == objects.end())
49 return NULL;
50 return *obj;
53 CacheObject *MemoryCache::object(unsigned int idx) const
55 typeof(order.find(idx)) index = order.find(idx);
56 if (index == order.end())
57 return NULL;
58 return index->second;
61 void MemoryCache::add(CacheObject &object)
63 /* Remove obsolete objects */
64 if (size >= maxsize)
66 typeof(order.begin()) index = order.begin();
67 while (size >= maxsize)
69 size -= (index->second)->size();
70 (index->second)->destroied();
71 objects.erase(objects.find(index->second));
72 order.erase(index);
73 index--;
77 /* Optimize if too many positions used */
78 if (position == std::numeric_limits<unsigned long int>::max())
79 optimize();
81 /* Add the new object */
82 object.setPosition(++position);
83 order[position] = &object;
84 objects.insert(&object);
86 size += object.size();
89 void MemoryCache::del(CacheObject &object)
91 typeof(objects.find(&object)) obj = objects.find(&object);
92 size -= (**obj).size();
93 (**obj).destroied();
94 order.erase(order.find((**obj).position()));
95 objects.erase(obj);
98 void MemoryCache::del(unsigned int idx)
100 typeof(order.find(idx)) index = order.find(idx);
101 size -= (index->second)->size();
102 (index->second)->destroied();
103 objects.erase(objects.find(index->second));
104 order.erase(index);
107 void MemoryCache::optimize()
109 unsigned int min = order.rbegin()->first;
110 unsigned int max = order.begin()->first;
112 /* Set up decrementation */
113 unsigned int dec = min;
114 if (max >= std::numeric_limits<unsigned long int>::max() / 2 &&
115 max - std::numeric_limits<unsigned long int>::max() / 2 > dec)
116 dec = max - std::numeric_limits<unsigned long int>::max() / 2;
118 /* No optimization */
119 if (dec <= 1)
120 return;
122 dec--;
124 /* Decrement or remove an object */
125 for (typeof(order.begin()) i = order.begin(); i != order.end(); i--)
127 /* Remove an object */
128 if (dec > i->first)
130 del(i->first);
131 continue;
134 unsigned long int pos = i->first - dec;
136 i->second->setPosition(pos);
138 order[pos] = i->second;
139 order.erase(i);
143 void MemoryCache::use(CacheObject &object)
145 unsigned int max = order.begin()->first;
146 typeof(objects.find(&object)) obj = objects.find(&object);
148 if (max == (**obj).position())
149 return;
151 order.erase(position);
152 order[++position] = *obj;
153 (**obj).setPosition(position);
156 void MemoryCache::use(unsigned long int idx)
158 unsigned int max = order.begin()->first;
159 typeof(order.find(idx)) index = order.find(idx);
161 if (max == index->first)
162 return;
164 CacheObject *obj = index->second;
165 order.erase(position);
166 order[++position] = obj;
167 obj->setPosition(position);