mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 14:41:25 +00:00
122 lines
2.6 KiB
C++
122 lines
2.6 KiB
C++
/*
|
|
Copyright (C) 2009 Red Hat, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _H_CACHE
|
|
#define _H_CACHE
|
|
|
|
#include "utils.h"
|
|
|
|
/*class Cache::Treat {
|
|
T* get(T*);
|
|
void release(T*);
|
|
const char* name();
|
|
};*/
|
|
|
|
template <class T, class Treat, int HASH_SIZE>
|
|
class Cache {
|
|
public:
|
|
Cache()
|
|
{
|
|
memset(_hash, 0, sizeof(_hash));
|
|
}
|
|
|
|
~Cache()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
void add(uint64_t id, T* data)
|
|
{
|
|
Item** item = &_hash[key(id)];
|
|
|
|
while (*item) {
|
|
if ((*item)->id == id) {
|
|
THROW("%s id %lu, double insert", Treat::name(), id);
|
|
}
|
|
item = &(*item)->next;
|
|
}
|
|
*item = new Item(id, data);
|
|
}
|
|
|
|
T* get(uint64_t id)
|
|
{
|
|
Item* item = _hash[key(id)];
|
|
|
|
while (item && item->id != id) {
|
|
item = item->next;
|
|
}
|
|
|
|
if (!item) {
|
|
THROW("%s id %lu, not found", Treat::name(), id);
|
|
}
|
|
return Treat::get(item->data);
|
|
}
|
|
|
|
void remove(uint64_t id)
|
|
{
|
|
Item** item = &_hash[key(id)];
|
|
|
|
while (*item) {
|
|
if ((*item)->id == id) {
|
|
Item *rm_item = *item;
|
|
*item = rm_item->next;
|
|
delete rm_item;
|
|
return;
|
|
}
|
|
item = &(*item)->next;
|
|
}
|
|
THROW("%s id %lu, not found", Treat::name(), id);
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
for (int i = 0; i < HASH_SIZE; i++) {
|
|
while (_hash[i]) {
|
|
Item *item = _hash[i];
|
|
_hash[i] = item->next;
|
|
delete item;
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
inline uint32_t key(uint64_t id) {return uint32_t(id) % HASH_SIZE;}
|
|
|
|
private:
|
|
class Item {
|
|
public:
|
|
Item(uint64_t in_id, T* data)
|
|
: id (in_id)
|
|
, next (NULL)
|
|
, data (Treat::get(data)) {}
|
|
|
|
~Item()
|
|
{
|
|
Treat::release(data);
|
|
}
|
|
|
|
uint64_t id;
|
|
Item* next;
|
|
T* data;
|
|
};
|
|
|
|
Item* _hash[HASH_SIZE];
|
|
};
|
|
|
|
#endif
|
|
|