2 # ifndef TPL_HASH_CACHE_H
3 # define TPL_HASH_CACHE_H
7 # include <tpl_dnode.H>
8 # include <tpl_lhash.H>
30 template <
typename Key,
typename Data,
class Cmp = Aleph::equal_to<Key>>
53 Dlink* link_lru() {
return &dlink_lru; }
55 bool is_in_hash_table;
60 throw std::runtime_error(
"Cache_Entry is already locked");
68 throw std::runtime_error(
"Cache_Entry is not locked");
74 Dlink * link_inside() {
return &dlink_inside; }
79 Cache_Entry() : locked(
false), is_in_hash_table(
false) { }
102 Chunk_Descriptor chunk_list;
103 void insert_entry_to_lru_list(Cache_Entry * cache_entry)
106 lru_list.
insert(cache_entry->link_lru());
108 void remove_entry_from_lru_list(Cache_Entry * cache_entry)
111 cache_entry->link_lru()->del();
114 void insert_entry_to_locked_list(Cache_Entry * cache_entry)
117 locked_list.
insert(cache_entry->link_lru());
120 void remove_entry_from_locked_list(Cache_Entry * cache_entry)
123 cache_entry->link_lru()->del();
126 void move_to_inside_front(Cache_Entry * cache_entry)
128 cache_entry->link_inside()->del();
129 inside_list.
insert(cache_entry->link_inside());
132 void do_mru(Cache_Entry * cache_entry)
134 cache_entry->link_lru()->del();
135 lru_list.
insert(cache_entry->link_lru());
137 void do_lru(Cache_Entry * cache_entry)
139 cache_entry->link_lru()->del();
140 lru_list.
append(cache_entry->link_lru());
142 void remove_entry_from_hash_table(Cache_Entry * cache_entry)
144 cache_entry->link_inside()->del();
145 hash_table.remove(cache_entry);
146 cache_entry->is_in_hash_table =
false;
149 Cache_Entry * get_lru_entry()
153 throw std::underflow_error(
"All entries are locked");
157 Cache_Entry * cache_entry = dlink_lru_to_Cache_Entry(lru_entry_link);
160 if (cache_entry->is_in_hash_table)
161 remove_entry_from_hash_table(cache_entry);
189 const size_t & __hash_size,
const size_t & __cache_size)
191 throw (std::exception, std::bad_alloc)
193 : hash_table(hash_fct, __hash_size,
false),
194 num_lru(0), cache_size(__cache_size), num_locked(0)
204 std::unique_ptr<Chunk_Descriptor>
206 chunk_list.
insert(chunk_descriptor.get());
209 for (
int i = 0; i < cache_size; i++)
210 insert_entry_to_lru_list(&entries_array[i]);
212 chunk_descriptor.release();
217 delete [] entries_array;
227 Chunk_Descriptor * current_chunk = chunk_list.
remove_next();
229 delete [] current_chunk->
get_data();
230 delete current_chunk;
254 cache_entry->get_key() = key;
256 inside_list.
insert(cache_entry->link_inside());
257 hash_table.insert(cache_entry);
258 cache_entry->is_in_hash_table =
true;
273 if (cache_entry != NULL)
276 move_to_inside_front(cache_entry);
294 static_cast<Cache_Entry*
>(hash_table.search_next(cache_entry));
295 if (next_entry != NULL)
298 move_to_inside_front(cache_entry);
308 throw(std::exception, std::runtime_error, std::domain_error)
312 if (cache_entry->is_locked())
313 throw std::runtime_error(
"Cache_Entry is already locked");
315 if (not cache_entry->is_in_table())
316 throw std::domain_error(
"Cache_Entry is not in the cache");
318 remove_entry_from_lru_list(cache_entry);
319 insert_entry_to_locked_list(cache_entry);
326 throw(std::exception, std::runtime_error)
330 if (not cache_entry->is_locked())
331 throw std::runtime_error(
"Cache_Entry is not locked");
333 remove_entry_from_locked_list(cache_entry);
334 insert_entry_to_lru_list(cache_entry);
335 cache_entry->unlock();
342 throw(std::exception, std::runtime_error, std::domain_error)
346 if (cache_entry->is_locked())
347 throw std::runtime_error(
"Cache_Entry is already locked");
348 if (not cache_entry->is_in_table())
349 throw std::domain_error(
"Cache_Entry is not in the cache");
351 remove_entry_from_hash_table(cache_entry);
359 throw(std::exception, std::range_error, std::bad_alloc)
364 throw std::range_error (
"bad plus_size");
366 const size_t new_cache_size = cache_size + plus_size;
374 std::unique_ptr<Chunk_Descriptor>
378 const float curr_hash_ratio = 1.0*cache_size/hash_table.capacity();
379 const size_t new_hash_capacity = new_cache_size/curr_hash_ratio;
381 hash_table.resize(new_hash_capacity);
384 for (
int i = 0; i < plus_size; i++)
385 insert_entry_to_lru_list(&entries_array[i]);
387 chunk_list.
insert(chunk_descriptor.release());
388 cache_size = new_cache_size;
393 delete [] entries_array;
401 const size_t &
capacity()
const {
return cache_size; }
404 const size_t &
size()
const {
return hash_table.size(); }
416 return hash_table.get_num_busy_slots();
422 return hash_table.capacity();
444 return Cache_Entry::dlink_inside_to_Cache_Entry(dl);
452 # endif // TPL_HASH_CACHE_H
Cache_Entry * get_current()
Retorna el Cache_Entry actual.
Definition: tpl_hash_cache.H:441
const size_t & size() const
Retorna en número de datos que están contenidos en el cache.
Definition: tpl_hash_cache.H:404
void expand(const size_t &plus_size)
Definition: tpl_hash_cache.H:357
Cache_Entry * search(const Key &key)
Definition: tpl_hash_cache.H:270
Definition: tpl_hash_cache.H:428
#define LINKNAME_TO_TYPE(type_name, link_name)
Definition: dlink.H:741
Iterador sobre enlaces.
Definition: dlink.H:437
Dnode< T > * remove_next()
Elimina sucesor a this y retorna su dirección.
Definition: tpl_dnode.H:37
const bool & is_locked() const
Retorna true si la entrada está trancada.
Definition: tpl_hash_cache.H:85
const size_t & get_num_busy_slots() const
Definition: tpl_hash_cache.H:414
void unlock_entry(Cache_Entry *cache_entry)
Definition: tpl_hash_cache.H:324
Cache_Entry * Item_Type
El tipo de elemento que retorna get_current().
Definition: tpl_hash_cache.H:435
Data & get_data()
Retorna una referencia al dato asociado a la clave.
Definition: tpl_hash_cache.H:83
Dlink *& get_prev()
Retorna enlace antes de this.
Definition: dlink.H:189
const size_t & get_hash_capacity() const
Retorna el tamaño de la tabla hash.
Definition: tpl_hash_cache.H:420
Definition: tpl_hash_cache.H:31
Iterator(Hash_Cache &cache)
Instancia un iterador sobre cache.
Definition: tpl_hash_cache.H:438
Cache_Entry * insert(const Key &key, const Data &data)
Definition: tpl_hash_cache.H:251
Definition: tpl_lhash.H:531
const size_t & capacity() const
Retorna el tamaño de cache.
Definition: tpl_hash_cache.H:401
Cache_Entry * search_next(Cache_Entry *cache_entry)
Definition: tpl_hash_cache.H:291
const bool & is_in_table() const
Retorna true si la entrada está dentro de la tabla.
Definition: tpl_hash_cache.H:88
void lock_entry(Cache_Entry *cache_entry)
Definition: tpl_hash_cache.H:306
Definition: tpl_hash_cache.H:46
Hash_Cache(size_t(*hash_fct)(const Key &), const size_t &__hash_size, const size_t &__cache_size)
Definition: tpl_hash_cache.H:188
const size_t & get_num_locked() const
Definition: tpl_hash_cache.H:409
void append(Dlink *node)
Definition: dlink.H:166
Dlink * get_current() const
Retorna dirección de nodo actual.
Definition: dlink.H:564
bool is_empty() const
retorna true si this está vacía
Definition: dlink.H:127
void insert(Dlink *node)
Definition: dlink.H:140
T & get_data()
Retorna referencia a dato contenido en el nodo.
Definition: tpl_dnode.H:126
Hash_Cache Set_Type
El tipo de conjunto sobre el cual se itera.
Definition: tpl_hash_cache.H:433