KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > services > cache > CachedItem


1 /*
2
3    Derby - Class org.apache.derby.impl.services.cache.CachedItem
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.services.cache;
23
24 import org.apache.derby.iapi.services.cache.Cacheable;
25 import org.apache.derby.iapi.services.cache.CacheableFactory;
26 import org.apache.derby.iapi.services.cache.CacheManager;
27 import org.apache.derby.iapi.error.StandardException;
28
29 import org.apache.derby.iapi.services.sanity.SanityManager;
30 import org.apache.derby.iapi.services.context.ContextService;
31
32 /**
33     A generic class to represent the cache related infomation of a cached object (Cacheable).
34     <P><PRE>
35     The relationship between isValid and settingIdentity can be explain by the
36     following life cycle of a cached item.
37
38     Stage 1 2 3
39     ----------------------
40     isValid F T T
41     settingIdentity X T F
42
43     In Stage 1, the CachedItem is created but it is invalid and has an entry
44     that is just a holder object with no identity.
45
46     In Stage 2, the identity has been set and the item is being created or
47     being faulted into the cache.
48
49     In Stage 3, the item found in the CachedItem entry
50     </PRE> <P>
51     Remove is set if this item is being removed out of existance, not just
52     being evicted from the cache. When the last referece to it release it from
53     the cache, it will be removed.
54     <BR>
55     RecentlyUsed is set whenever this item is accessed (via a keep() call).
56     It is reset by the clockHand as it sweeps around the cache looking for
57     victims to evict.
58
59     <P>MT - must be MT-safe and work with cache manager. Every method that
60     access (set or get) instance variables is synchronized on the cached item
61     object. The following method waits so it should not be called by the cache
62     manager inside a sync block: clean(), waitFor(), create(), remove().
63     (RESOLVE: need to move these from the cache manager to here)
64
65     @see org.apache.derby.impl.services.cache
66     @see Cacheable
67 */

68 public final class CachedItem {
69
70     private static final int VALID = 0x00000001;
71     private static final int REMOVE_REQUESTED = 0x00000002;
72     private static final int SETTING_IDENTITY = 0x00000004;
73     private static final int REMOVE_OK = 0x00000008;
74
75     private static final int RECENTLY_USED = 0x00000010;
76
77     /*
78     ** Fields
79     */

80
81     /**
82         Does entry (the Cacheable) have an identity.
83
84         <BR> MT - single thread required : synchronization provided by cache manager.
85     */

86     private int state;
87
88     /**
89         The current keep count on the entry.
90
91         <BR> MT - single thread required : synchronization provided by cache manager.
92
93     */

94     private int keepCount;
95
96     /**
97         The Cacheable object being represented.
98
99         <BR> Mutable - content dynamic
100     */

101     private Cacheable entry;
102         
103     /**
104         Create a CachedItem in the not valid state.
105     */

106     public CachedItem() {
107     }
108
109     /**
110         Keep the cached object after a search.
111
112     */

113     public void keepAfterSearch() {
114         keepCount++;
115         setUsed(true);
116     }
117
118     public void keepForCreate() {
119         if (SanityManager.DEBUG) {
120             SanityManager.ASSERT(!isKept());
121             SanityManager.ASSERT(!isValid());
122         }
123         keepCount = 1;
124         state |= SETTING_IDENTITY;
125     }
126
127     public void unkeepForCreate( )
128     {
129         settingIdentityComplete();
130         unkeep();
131     }
132
133     public void keepForClean() {
134         if (SanityManager.DEBUG) {
135             SanityManager.ASSERT(isValid());
136         }
137         keepCount++;
138     }
139
140
141
142     /**
143         Unkeep the cached object.
144
145         <P>MT - not synchronized, only modified single threaded by the cache manager
146
147         @return if the object is still kept after this call.
148     */

149     public synchronized boolean unkeep() {
150         boolean unkept = --keepCount == 0;
151
152         if (SanityManager.DEBUG) {
153             SanityManager.ASSERT(keepCount >= 0);
154         }
155         return unkept && ((state & REMOVE_REQUESTED) != 0);
156     }
157
158     /**
159         Is the cached object kept?
160
161         <P>MT - not synchronized, only accessed single threaded by the cache manager
162     */

163     public final boolean isKept() {
164
165         return keepCount != 0;
166     }
167
168     /**
169         Clean the cached object
170
171         <P>MT - <BR>
172         The wait will not release the lock on the cache manager, so the
173         cache manager should not waitfor clean inside a sync block or
174         the whole cache will freeze
175
176         @param forRemove if true, get rid of the backend persistent store object
177         @exception StandardException error thrown while writing cacheable
178         object to disk
179     */

180     public void clean(boolean forRemove) throws StandardException
181     {
182         entry.clean(forRemove);
183     }
184
185     /**
186         Set the state of the to-be removed flag.
187     */

188     public synchronized void setRemoveState() {
189         state |= REMOVE_REQUESTED;
190     }
191
192     /**
193         Does the cached object have a valid identity.
194     */

195     public final synchronized boolean isValid() {
196         return (state & VALID) != 0;
197     }
198
199     /**
200         Set the valid state of the cached object.
201     */

202     public synchronized void setValidState(boolean flag) {
203
204         if (flag)
205             state |= VALID;
206         else
207             state &= ~VALID;
208
209         state &= ~(REMOVE_REQUESTED | REMOVE_OK);
210
211         setUsed(flag);
212     }
213
214     /**
215         Get the cached object.
216     */

217     public Cacheable getEntry() {
218         return entry;
219     }
220
221     /**
222         Make entry (the Cacheable) take on a new identity.
223     */

224     public Cacheable takeOnIdentity(CacheManager cm, CacheableFactory holderFactory,
225         Object JavaDoc key, boolean forCreate, Object JavaDoc createParameter)
226         throws StandardException {
227
228         // tell the object it needs to create itself
229
Cacheable oldEntry = entry;
230         if (oldEntry == null)
231             oldEntry = holderFactory.newCacheable(cm);
232
233         if (forCreate) {
234             entry = oldEntry.createIdentity(key, createParameter);
235         } else {
236             entry = oldEntry.setIdentity(key);
237         }
238
239         if (entry != null) {
240             // item was found or created
241
if (SanityManager.DEBUG) {
242                 SanityManager.ASSERT(entry.getIdentity().equals(key));
243             }
244
245             return entry;
246         }
247
248         entry = oldEntry;
249         return null;
250     }
251
252     public synchronized void settingIdentityComplete() {
253         // notify all waiters that this item has finished setting its identity,
254
// successfully or not.
255
state &= ~SETTING_IDENTITY;
256                 
257         notifyAll();
258     }
259
260     /**
261         Allow use of the cacheable entry.
262     */

263
264     public synchronized Cacheable use() throws StandardException {
265
266         while ((state & SETTING_IDENTITY) != 0) {
267             try {
268                 if (SanityManager.DEBUG) {
269                     SanityManager.DEBUG("CacheTrace",
270                         "trying to use a cached item that is taking on an identity");
271                 }
272
273                 wait();
274
275             } catch (InterruptedException JavaDoc ie) {
276                 throw StandardException.interrupt(ie);
277             }
278         }
279
280         // see if the setting of this identity failed ...
281
if (!isValid())
282             return null;
283
284         if (SanityManager.DEBUG)
285         {
286             if (SanityManager.DEBUG_ON("CacheTrace"))
287                 SanityManager.DEBUG(
288                     "CacheTrace", "item keep count is " + keepCount);
289         }
290
291
292         return entry;
293     }
294
295     /**
296     */

297     public void remove(boolean removeNow) throws StandardException {
298
299         if (!removeNow) {
300
301             synchronized (this) {
302                 while ((state & REMOVE_OK) == 0) {
303                     try {
304                         wait();
305                     } catch (InterruptedException JavaDoc ie) {
306                         throw StandardException.interrupt(ie);
307                     }
308                 }
309             }
310         }
311         
312         clean(true);
313     }
314
315     public synchronized void notifyRemover() {
316
317         if (SanityManager.DEBUG) {
318             SanityManager.ASSERT((state & REMOVE_REQUESTED) != 0);
319             SanityManager.ASSERT(isKept());
320         }
321
322         state |= REMOVE_OK;
323         notifyAll();
324     }
325
326     /**
327         The clock hand has swept past this entry.
328     */

329     public synchronized void setUsed(boolean flag)
330     {
331         if (flag)
332             state |= RECENTLY_USED;
333         else
334             state &= ~RECENTLY_USED;
335     }
336
337     /**
338         Has the cached object been referenced (kept) since the last sweep of
339         the clock hand?
340     */

341     public synchronized boolean recentlyUsed() {
342         return (state & RECENTLY_USED) != 0;
343     }
344 }
345
346     
347     
348
Popular Tags