C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implementer un cache en c++/STL

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Jean-Marc Desperrier
Guest





PostPosted: Tue Jun 07, 2005 12:51 pm    Post subject: Implementer un cache en c++/STL Reply with quote



Bonjour,

Je suis à la rechercher d'une implémentation de cache limité en taille
efficace en C++/STL plutôt que de réinventer la roue en faisant moi-même.

Pour être précis, je veux parler d'un container qui stocke des éléments
indexé par une clé, avec accès par la clé, sur lequel je fixe une taille
limite, les éléments les plus anciens/moins souvent accédés étant
supprimés une fois cette taille atteinte.

Vous avez des références ?

L'accès par la clé doit être de préférence rapide, mais il faut voir
quels compromis il y a entre cette vitesse d'accès, et le temps pour
savoir quel est l'élément le plus ancien/moins accédés, et combien de
listes on stocke.
Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Jun 08, 2005 6:47 am    Post subject: Re: Implementer un cache en c++/STL Reply with quote



Jean-Marc Desperrier wrote:

Quote:
Je suis à la rechercher d'une implémentation de cache limité
en taille efficace en C++/STL plutôt que de réinventer la roue
en faisant moi-même.

Pour être précis, je veux parler d'un container qui stocke des
éléments indexé par une clé, avec accès par la clé, sur lequel
je fixe une taille limite, les éléments les plus anciens/moins
souvent accédés étant supprimés une fois cette taille
atteinte.

Vous avez des références ?

L'accès par la clé doit être de préférence rapide, mais il
faut voir quels compromis il y a entre cette vitesse d'accès,
et le temps pour savoir quel est l'élément le plus
ancien/moins accédés, et combien de listes on stocke.

Il n'y a pas de collection aussi compliquée dans la STL. La
solution évidente, c'est un std::map auquel on joint un
std::list; chaque fois qu'on accède à un élément du map, on
l'enlève de la liste, et on le remet en tête. Quand le nombre
d'éléments devient trop grand, on supprime ceux en queue de la
liste. Le seul problème, c'est de rétrouver rapidement l'élément
dans la liste quand on y accède dans le map ; à la rigueur, ce
qu'on stocke dans le map, c'est des struct { List::iterator,
ElemType } (et on met à jour la partie List::iterator à chaque
accès). Mais j'avoue que chaque fois que je me suis trouvé
confronté à un problème pareil, je me suis servi d'une liste
invasive, dont les liens se trouvaient dans l'objet même. Ce qui
permet d'enlever l'objet de la liste sans autre chose que
l'objet même.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Marc Boyer
Guest





PostPosted: Wed Jun 08, 2005 7:48 am    Post subject: Re: Implementer un cache en c++/STL Reply with quote



Jean-Marc Desperrier wrote:
Quote:
Je suis à la rechercher d'une implémentation de cache limité en taille
efficace en C++/STL plutôt que de réinventer la roue en faisant moi-même.

Ce qui est amusant, c'est que je fais à peut prêt la même chose
en ce moment.

Quote:
Pour être précis, je veux parler d'un container qui stocke des éléments
indexé par une clé, avec accès par la clé, sur lequel je fixe une taille
limite, les éléments les plus anciens/moins souvent accédés étant
supprimés une fois cette taille atteinte.

Un problème déjà, c'est que suivant la politique (FIFO/LFU),
la "bonne" structure de donnée pour stocker les infos de
conservation/effacement dans le cache sont très différents.
Pour FIFO, une list ou une dequeu sont assez évident.
Pour une LFU, ça se discute.

Pour une FIFO, on stocke les éléments eux-même dans une map,
puis on utilise une FIFO (dequeu,list) qui contient des iterateurs
sur map pour gérer l'ordre. On se base sur la bonne propriété
des map que les opérations n'invalident pas les itérateurs.

Pour une LFU, je stoquerais dans la map les élements + leurs
nombres d'accès. A côté, une liste/dequeu/vecteur triée
d'itérateur sur les éléments de la map, avec comme critère de
tri bien sur le nb d'accès.

Marc Boyer
--
Je ne respecte plus le code de la route à vélo depuis une double fracture
due au fait que j'étais le seul à le respecter.

Back to top
Jean-Marc Desperrier
Guest





PostPosted: Wed Jun 08, 2005 10:11 pm    Post subject: Re: Implementer un cache en c++/STL Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
Il n'y a pas de collection aussi compliquée dans la STL.

Ca me semble pourtant un besoin assez courant et générique, il n'y a
rien dans Boost non plus ?

Quote:
solution évidente, c'est un std::map auquel on joint un
std::list; [...]. Le seul problème, c'est de rétrouver rapidement l'élément
dans la liste quand on y accède dans le map ;
[...] j'avoue que chaque fois que je me suis trouvé
confronté à un problème pareil, je me suis servi d'une liste
invasive, dont les liens se trouvaient dans l'objet même.

Ca parait nickel ! J'avais un faible pour les solutions type LFU au
départ, mais en réfléchissant un peu plus les cas dégénérés peuvent
devenir franchement catatrophiques.

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Jun 08, 2005 11:06 pm    Post subject: Re: Implementer un cache en c++/STL Reply with quote

On Thu, 09 Jun 2005 00:11:10 +0200, Jean-Marc Desperrier
<jmdesp (AT) alussinan (DOT) org>:

Quote:
Il n'y a pas de collection aussi compliquée dans la STL.

Ca me semble pourtant un besoin assez courant et générique

Vider un conteneur est aussi un truc très courant, et pourtant la STL
ne propose aucune solution directe. Il faut faire soit-même la
fonction

template <class T> void ViderConteneur (T& t)
{
t.erase (t.begin(), t.end());
}


Back to top
Loïc Joly
Guest





PostPosted: Wed Jun 08, 2005 11:36 pm    Post subject: Re: Implementer un cache en c++/STL Reply with quote

Fabien LE LEZ a écrit :
Quote:
On Thu, 09 Jun 2005 00:11:10 +0200, Jean-Marc Desperrier
[email]jmdesp (AT) alussinan (DOT) org[/email]>:


Il n'y a pas de collection aussi compliquée dans la STL.

Ca me semble pourtant un besoin assez courant et générique


Vider un conteneur est aussi un truc très courant, et pourtant la STL
ne propose aucune solution directe. Il faut faire soit-même la
fonction

template <class T> void ViderConteneur (T& t)
{
t.erase (t.begin(), t.end());
}

Ah ?

Table 67—Sequence requirements (in addition to container)
________________________________________________
expression return type assertion/note
pre/postcondition

a.clear() void erase(begin(), end())
post: size() == 0.
________________________________________________

Ou alors tu voulais parler de l'astuce avec swap ?

--
Loïc

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jun 09, 2005 8:12 am    Post subject: Re: Implementer un cache en c++/STL Reply with quote

Jean-Marc Desperrier wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:
Il n'y a pas de collection aussi compliquée dans la STL.

Ca me semble pourtant un besoin assez courant et générique, il
n'y a rien dans Boost non plus ?

Pas à ce que je sache. Il n'y a pas de map bi-directionnel
non-plus.

La bibliothèque standard ne peut pas fournir des solutions tout
faites pour tous les problèmes. Son rôle, c'est plutôt de fornir
des mechanismes de base qui peuvent servir à implémenter des
solutions à des problèmes divers.

Quote:
solution évidente, c'est un std::map auquel on joint un
std::list; [...]. Le seul problème, c'est de rétrouver
rapidement l'élément dans la liste quand on y accède dans le
map ; [...] j'avoue que chaque fois que je me suis trouvé
confronté à un problème pareil, je me suis servi d'une liste
invasive, dont les liens se trouvaient dans l'objet même.

Ca parait nickel ! J'avais un faible pour les solutions type
LFU au départ, mais en réfléchissant un peu plus les cas
dégénérés peuvent devenir franchement catatrophiques.

En plus, c'est beaucoup plus difficile à implémenter:-). Pour
qu'il soit efficace, il faut bien gerer l'aspect time ; les
utilisations anciennes ne compte pas autant que les utilisations
récentes. Il faut donc un espèce de côte affaiblissant : tu y
ajoutes une constante à chaque utilisation, à des intervales
fixes, tu en soustrais une constante à tous les éléments, et
quand il faut supprimer, tu supprimes celui dont la côte est la
plus basse. (À la place des intervales fixes, je suppose qu'on
pourrait utiliser des accès : a chaque dizième accès, par
exemple. Voir même à chaque accès.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Jun 09, 2005 8:31 am    Post subject: Re: Implementer un cache en c++/STL Reply with quote

Marc Boyer wrote:
Quote:
Jean-Marc Desperrier wrote:
Je suis à la rechercher d'une implémentation de cache limité
en taille efficace en C++/STL plutôt que de réinventer la
roue en faisant moi-même.

Ce qui est amusant, c'est que je fais à peut prêt la même
chose en ce moment.

Pour être précis, je veux parler d'un container qui stocke
des éléments indexé par une clé, avec accès par la clé, sur
lequel je fixe une taille limite, les éléments les plus
anciens/moins souvent accédés étant supprimés une fois cette
taille atteinte.

Un problème déjà, c'est que suivant la politique (FIFO/LFU),
la "bonne" structure de donnée pour stocker les infos de
conservation/effacement dans le cache sont très différents.
Pour FIFO, une list ou une dequeu sont assez évident.
Pour une LFU, ça se discute.

Dans les deux cas, tu as besoin de deux collections, une indexée
par la clé, et l'autre pour gerer l'ordre de suppression.

Dans le cas d'un FIFO, il te faut les deux en permanance. Dans
le cas LFU, ça dépend ; on pourrait envisager de ne créer la
deuxième collection qu'en cas de besoin.

Quote:
Pour une FIFO, on stocke les éléments eux-même dans une map,
puis on utilise une FIFO (dequeu,list) qui contient des
iterateurs sur map pour gérer l'ordre. On se base sur la bonne
propriété des map que les opérations n'invalident pas les
itérateurs.

C'est une solution. En fait, comme j'ai dit, j'ai souvent mis
l'implémentation de la liste dans l'objet.

Quote:
Pour une LFU, je stoquerais dans la map les élements + leurs
nombres d'accès. A côté, une liste/dequeu/vecteur triée
d'itérateur sur les éléments de la map, avec comme critère de
tri bien sur le nb d'accès.

Pourquoi pas un map d'itérateurs comme deuxième collection
aussi ?

Sinon, si les cas de suppression ne sont pas si fréquent, ou
pourrait envisager de ne créer, ou au moin ne trier la deuxième
collection que quand on veut supprimer. D'autant plus qu'on n'a
pas besoin de trier complètement ; on doit pouvoir se servir de
std::partial_sort ou std::nth_element.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Joaquín M López Muñoz
Guest





PostPosted: Fri Jun 10, 2005 6:48 am    Post subject: Re: Implementer un cache en c++/STL Reply with quote



Jean-Marc Desperrier wrote:
Quote:
kanze (AT) gabi-soft (DOT) fr wrote:
Il n'y a pas de collection aussi compliquée dans la STL.

Ca me semble pourtant un besoin assez courant et générique, il n'y a
rien dans Boost non plus ?


Veuillez regarder sur

http://boost-consulting.com/boost/libs/multi_index/doc/examples.html#example9

por un exemple de container cache en utilisant
Boost.MultiIndex. L'exemple emploie des "hashed indices" pour
la récupération rapide des eléments: Ces index ne sont pas
disponibles encore (début en Boost 1.33), mais on peut
les substituer par des "ordered indices", qui resemblent
à des maps de STL.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.