Index: lutinutil/src/java/org/codelutin/util/HashMapMultiKey.java diff -u lutinutil/src/java/org/codelutin/util/HashMapMultiKey.java:1.5 lutinutil/src/java/org/codelutin/util/HashMapMultiKey.java:1.6 --- lutinutil/src/java/org/codelutin/util/HashMapMultiKey.java:1.5 Thu Oct 27 16:28:00 2005 +++ lutinutil/src/java/org/codelutin/util/HashMapMultiKey.java Fri Nov 11 03:16:59 2005 @@ -23,9 +23,9 @@ * Created: 2 nov. 2004 * * @author Benjamin Poussin - * @version $Revision: 1.5 $ + * @version $Revision: 1.6 $ * - * Mise a jour: $Date: 2005/10/27 16:28:00 $ + * Mise a jour: $Date: 2005/11/11 03:16:59 $ * par : $Author: bpoussin $ */ @@ -44,8 +44,8 @@ /** * Permet de stocker un element suivant un ensemble de cle. - * @TODO pour l'instant on ne gere pas les references sur les clef - * FIXME pas le temps d'implanter toutes les methodes pour un support + * + * FIXME: pas le temps d'implanter toutes les methodes pour un support * complet des References. iterator(), entrySet(), ... peuvent ne pas * fonctionner comme il faut, c-a-d qu'il retourne les references et non * les objets. Mais les methodes simples fonctionnent: put, remove, get, ... @@ -64,6 +64,7 @@ /** key: la valeur, valeur: la cle. Permet de supprimer rapidement une * key lorsque la valeur disparait */ protected HashMap valueToKey = new HashMap(); + protected ReferenceQueue refQueueKey = new ReferenceQueue(); protected ReferenceQueue refQueueValue = new ReferenceQueue(); protected Object keyType = null; @@ -92,17 +93,23 @@ */ protected void cleanQueue(){ Reference o = null; + while(null != (o = refQueueKey.poll())) { + if(log.isTraceEnabled()){ log.trace("clean the refQueueKey : " + o);} + Object val = super.remove(o); + valueToKey.remove(val); + } + while(null != (o = refQueueValue.poll())) { if(log.isTraceEnabled()){ log.trace("clean the refQueueValue : " + o);} // suppression dans la table des values et recuperation de la cle // associé - Object key = valueToKey.remove(o); + Object key = derefKey(valueToKey.remove(o)); if( key != null) { // suppression dans la table a partir de la cle recuperé super.remove(key); // suppression dans l'association des objets de la cle for(Iterator i=((Key)key).iterator(); i.hasNext();){ - Set list = (Set)keys.get(i.next()); + Set list = getKeys(i.next()); if (list != null) { list.remove(key); } @@ -111,8 +118,6 @@ if(log.isTraceEnabled()){ log.trace("key is null !!! " + o);} } } - - // TODO la meme chose ici pour la queue des cles } /** @@ -167,18 +172,35 @@ * e. * @param e l'element que doivent contenir les cles * @return la liste des cles. Si aucune cle ne contient l'element e, - * alors la liste retourné est vide + * alors la liste retourné est vide. */ public Set getKeys(Object e){ cleanQueue(); Set list = (Set)keys.get(e); if( list == null){ list = new HashSet(); - keys.put(e, list); + } else { + // on nettoie un peu la liste en supprimant les cles liberees + for (Iterator i=list.iterator(); i.hasNext();) { + if (derefKey(i.next()) == null) { + i.remove(); + } + } + if (list.size() == 0) { + keys.remove(e); + } } return list; } + protected Set getKeysAndAdd(Object e){ + Set list = getKeys(e); + // il ne faut pas encapsuler e dans une ref, sinon on ne retrouve + // plus les cles si l'objet etait seulement dans la cle + keys.put(e, list); + return list; + } + /** * Method put * @@ -195,17 +217,18 @@ if(key instanceof Key){ // ajout dans la hash des cles Key keyObject = (Key)key; + Object keyRef = refKey(key); for(int i=0; i * Copyright Code Lutin -* @version $Revision: 1.3 $ +* @version $Revision: 1.4 $ * -* Mise a jour: $Date: 2005/10/27 16:28:00 $ +* Mise a jour: $Date: 2005/11/11 03:16:59 $ * par : $Author: bpoussin $ */ package org.codelutin.util; @@ -85,12 +85,18 @@ // on travail avec un variable local pour ne pas etre obligé de // synchroniser la méthode Object local = get(); + Object other = o; if (o instanceof Reference) { - o = ((Reference)o).get(); + other = ((Reference)o).get(); + + if (other == null) { + // on fait l'egalite sur les hash car on a perdu les objets + return o.hashCode() == hashCode(); + } } - return (o == null && local == null) - || (o != null && o.equals(local)); + return (other == null && local == null) || + (other != null && other.equals(local)); } /**