KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > carol > cmi > WeakCache


1 /*
2  * Copyright (C) 2002-2003, Simon Nieuviarts
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA
18  */

19 package org.objectweb.carol.cmi;
20
21 import java.lang.ref.WeakReference JavaDoc;
22 import java.lang.ref.ReferenceQueue JavaDoc;
23
24 /**
25  * An object cache, to reduce memory usage by returning always the same instance for
26  * equal objects.
27  */

28 public class WeakCache {
29     private java.util.HashMap JavaDoc table = new java.util.HashMap JavaDoc();
30
31     private class WeakRef extends WeakReference JavaDoc {
32         private int hash;
33
34         public WeakRef(Object JavaDoc obj) {
35             super(obj);
36             hash = obj.hashCode();
37         }
38
39         public WeakRef(Object JavaDoc obj, ReferenceQueue JavaDoc rq) {
40             super(obj, rq);
41             hash = obj.hashCode();
42         }
43
44         public int hashCode() {
45             return hash;
46         }
47
48         public boolean equals(Object JavaDoc obj) {
49             // This first check is necessary to remove empty WeakRef from the table
50
if (obj == this) {
51                 return true;
52             }
53
54             if (obj instanceof WeakRef) {
55                 Object JavaDoc o = this.get();
56                 return (o != null) && o.equals(((WeakRef) obj).get());
57             } else
58                 return false;
59         }
60
61         public void remove() {
62             synchronized (table) {
63                 table.remove(this);
64             }
65         }
66     }
67
68     private static ReferenceQueue JavaDoc rQueue = new ReferenceQueue JavaDoc();
69     private static Thread JavaDoc rQueueThread = new RefQueueFlush();
70     static {
71         rQueueThread.setDaemon(true);
72         rQueueThread.start();
73     }
74
75     private static class RefQueueFlush extends Thread JavaDoc {
76         public RefQueueFlush() {
77         }
78         public void run() {
79             while (true) {
80                 try {
81                     WeakRef wr = (WeakRef) rQueue.remove();
82                     wr.remove();
83                 } catch (InterruptedException JavaDoc e) {
84                     // Ignored
85
}
86             }
87         }
88     }
89
90     /**
91      * Registers an object in the cache or return an already registered equal object.
92      * @param obj Object to register.
93      * @return the copy to use.
94      */

95     public Object JavaDoc getCached(Object JavaDoc obj) {
96         WeakRef wr = new WeakRef(obj, rQueue);
97         synchronized (table) {
98             WeakRef cached = (WeakRef) table.get(wr);
99             if (cached == null) {
100                 table.put(wr, wr);
101                 return obj;
102             }
103             Object JavaDoc c = cached.get();
104             if (c == null) {
105                 table.remove(cached);
106                 table.put(wr, wr);
107                 return obj;
108             }
109             return c;
110         }
111     }
112 }
113
Popular Tags