KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > cache > ClockEvictionPolicy


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.object.cache;
5
6 import com.tc.text.PrettyPrinter;
7
8 import gnu.trove.TLinkedList;
9
10 import java.util.Collection JavaDoc;
11 import java.util.Collections JavaDoc;
12 import java.util.HashSet JavaDoc;
13
14 public class ClockEvictionPolicy implements EvictionPolicy {
15
16   // private static final TCLogger logger = new LossyTCLogger(TCLogging.getLogger(ClockEvictionPolicy.class), 1000);
17

18   private final TLinkedList cache = new TLinkedList();
19   private final int capacity;
20   private Cacheable hand = null;
21   private final int evictionSize;
22   private Cacheable save;
23
24   public ClockEvictionPolicy(int size) {
25     this(size, (int) ((size * 0.1)));
26   }
27
28   public ClockEvictionPolicy(int capacity, int evictionSize) {
29     this.capacity = capacity;
30     this.evictionSize = (evictionSize <= 0 ? 1 : evictionSize);
31   }
32
33   public synchronized boolean add(Cacheable obj) {
34     if (hand == null) {
35       cache.addLast(obj);
36     } else {
37       cache.addBefore(hand, obj);
38     }
39     markReferenced(obj);
40     return isCacheFull();
41   }
42
43   private boolean isCacheFull() {
44     if (capacity <= 0 || cache.size() <= capacity) {
45       return false;
46     } else {
47       return true;
48     }
49   }
50
51   public synchronized Collection JavaDoc getRemovalCandidates(int maxCount) {
52     if (capacity > 0) {
53       if (!isCacheFull()) return Collections.EMPTY_LIST;
54       if (maxCount <= 0 || maxCount > evictionSize) {
55         maxCount = evictionSize;
56       }
57     } else if (maxCount <= 0) {
58       // disallow negetative maxCount when capacity is negative
59
throw new AssertionError JavaDoc("Please specify maxcount > 0 as capacity is set to : " + capacity + " Max Count = "
60                                + maxCount);
61     }
62     Collection JavaDoc rv = new HashSet JavaDoc();
63     int count = Math.min(cache.size(), maxCount);
64     while (cache.size() - rv.size() > capacity && count > 0 && moveHand()) {
65       rv.add(hand);
66       count--;
67     }
68     erasePosition();
69     return rv;
70   }
71
72   private void erasePosition() {
73     this.save = null;
74   }
75
76   private void markPosition() {
77     this.save = this.hand;
78   }
79
80   public synchronized void remove(Cacheable obj) {
81     if (hand != null && obj == hand) {
82       hand = (Cacheable) hand.getPrevious();
83     }
84     cache.remove(obj);
85   }
86
87   public void markReferenced(Cacheable obj) {
88     obj.markAccessed();
89   }
90
91   public PrettyPrinter prettyPrint(PrettyPrinter out) {
92     return null;
93   }
94
95   private boolean moveHand() {
96     boolean found = false;
97     while (!found) {
98       if (hand == null || hand.getNext() == null) {
99         hand = (Cacheable) cache.getFirst();
100       } else {
101         this.hand = (Cacheable) hand.getNext();
102       }
103       if (hand.recentlyAccessed()) {
104         hand.clearAccessed();
105       } else if (hand.canEvict()) {
106         found = true;
107         break;
108       }
109       if (hand == save) {
110         // logger.info("Cache Evictor : Couldnt find any more ! - cache.size () = " + cache.size());
111
break;
112       }
113       if (save == null) {
114         markPosition();
115       }
116     }
117     return found;
118   }
119
120   public int getCacheCapacity() {
121     return capacity;
122   }
123 }
124
Popular Tags