KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > core > storage > AbstractReferenceCache


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Core License version 1 published by ozone-db.org.
3
//
4
// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.
5
//
6
// $Id: AbstractReferenceCache.java,v 1.2.2.2 2004/04/10 10:06:51 per_nyfelt Exp $
7

8 package org.ozoneDB.core.storage;
9
10 import java.lang.ref.Reference JavaDoc;
11 import java.lang.ref.ReferenceQueue JavaDoc;
12 import java.lang.ref.SoftReference JavaDoc;
13 import java.util.Collection JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.LinkedHashMap JavaDoc;
18 import java.util.LinkedList JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Map.Entry;
21 import java.util.Properties JavaDoc;
22 import java.util.Set JavaDoc;
23
24 /**
25  *
26  * @author <a HREF="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a>
27  * @version $Id: AbstractReferenceCache.java,v 1.2.2.2 2004/04/10 10:06:51 per_nyfelt Exp $
28  */

29 public abstract class AbstractReferenceCache implements Cache, PropertyConfigurable {
30     
31     /**
32      * We need to find objects in the map that holds the references. To do that
33      * we need to add a key to a reference. The ReferenceHandler can
34      * remove defunct references from the map, using the key to find the
35      * defunct references.
36      */

37     protected interface KeyedReference {
38         
39         public void clear();
40         
41         public boolean enqueue();
42         
43         public Object JavaDoc get();
44         
45         public boolean isEnqueued();
46         
47         public Object JavaDoc getKey();
48         
49     }
50     
51     /**
52      * Handles the garbage collector 'messages' that certain softly reachable
53      * objects have been gc-ed.
54      * The <code>ObjectReference</code> instances that pointed to them
55      * are removed from the backing map in order to prevent the backing map to
56      * overflow with soft reference instances that now point to null.
57      */

58     private class ReferenceHandler extends Thread JavaDoc {
59         
60         ReferenceHandler() {
61             super(Thread.currentThread().getThreadGroup(), "stale reference remover");
62             setDaemon(true);
63             setPriority(Thread.MAX_PRIORITY - 1);
64         }
65         
66         public void run() {
67             for(;;) {
68                 try {
69                     KeyedReference ref = (KeyedReference) getReferenceQueue().remove();
70                     Set JavaDoc keys = new HashSet JavaDoc();
71                     keys.add(ref.getKey());
72                     
73                     // The gc seems to enqueue in bulk; this is also the reason
74
// to use multiple threads instead of one static thread: in
75
// the latter case we would have to synchronize on different
76
// caches: now we can suffice with just one synchronized
77
// block. As long as the number of abstract caches stays low
78
// perfomance is a lot better.
79
while ((ref = (KeyedReference) getReferenceQueue().poll()) != null) {
80                         keys.add(ref.getKey());
81                     }
82                     synchronized(AbstractReferenceCache.this) {
83                         getMap().keySet().removeAll(keys);
84                     }
85                 } catch (InterruptedException JavaDoc ignore) {
86                 }
87             }
88         }
89         
90     } // ReferenceHandler
91

92     private ReferenceQueue JavaDoc referenceQueue;
93     private ReferenceHandler referenceHandler;
94     
95     private String JavaDoc prefix;
96     
97     /**
98      * backing map (key -> (ObjectReference -> cached object))
99      */

100     private Map JavaDoc map;
101     
102     public AbstractReferenceCache(Properties JavaDoc properties, String JavaDoc prefix) {
103         this.prefix = prefix;
104         map = new LinkedHashMap JavaDoc();
105         referenceQueue = new ReferenceQueue JavaDoc();
106         referenceHandler = new ReferenceHandler();
107         referenceHandler.start();
108     }
109     
110     protected abstract KeyedReference createKeyedReference(Object JavaDoc key, Object JavaDoc value, ReferenceQueue JavaDoc referenceQueue);
111
112     public synchronized Object JavaDoc get(Object JavaDoc key) {
113         KeyedReference ref = (KeyedReference) getMap().get(key);
114         return ref == null ? null : ref.get();
115     }
116
117     public synchronized void put(Object JavaDoc key, Object JavaDoc value) {
118         KeyedReference ref = createKeyedReference(key, value, getReferenceQueue());
119         getMap().put(key, ref);
120     }
121     
122     public synchronized Object JavaDoc remove(Object JavaDoc key) {
123         KeyedReference ref = (KeyedReference) getMap().remove(key);
124         return ref == null ? null : ref.get();
125     }
126     
127     public synchronized Map JavaDoc copyToMap() {
128         Map JavaDoc result = new HashMap JavaDoc();
129         for (Iterator JavaDoc i = getMap().entrySet().iterator(); i.hasNext(); ) {
130             Entry entry = (Entry) i.next();
131             KeyedReference ref = (KeyedReference) entry.getValue();
132             Object JavaDoc value = ref.get();
133             if (value != null) {
134                 result.put(entry.getKey(), value);
135             }
136         }
137         return result;
138     }
139     
140     // private so it can be inlined
141
private Map JavaDoc getMap() {
142         return map;
143     }
144
145     // private so it can be inlined
146
private ReferenceQueue JavaDoc getReferenceQueue() {
147         return referenceQueue;
148     }
149
150     public synchronized int size() {
151         return getMap().size();
152     }
153     
154     public String JavaDoc getPrefix() {
155         return prefix;
156     }
157     
158     public Collection JavaDoc getPropertyInfos() {
159         return new LinkedList JavaDoc();
160     }
161     
162     
163     // debug code only following
164
protected AbstractReferenceCache() {
165     }
166     
167 }
168
Popular Tags