1 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 ; 11 import java.util.Collections ; 12 import java.util.HashSet ; 13 14 public class ClockEvictionPolicy implements EvictionPolicy { 15 16 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 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 throw new AssertionError ("Please specify maxcount > 0 as capacity is set to : " + capacity + " Max Count = " 60 + maxCount); 61 } 62 Collection rv = new HashSet (); 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 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 |