first cut of merge of STABLE-pre1_0 into HEAD. I won't even guarantee that it
[mir.git] / source / mir / storage / store / StoreContainer.java
1 package mir.storage.store;
2
3 /**
4  * Title:         StoreContainer
5  *
6  * Description:   This is the bucket object for one type of StorableObjects,
7  *                mainy a linked list of StoreIdenfiers. On use or creation
8  *                an object stored in StoreIdentifier is put to head of the
9  *                list. if maximum size of the list is reached, the
10  *                StoreIdentifier at the end of the list is released.
11  *
12  * Copyright:     Copyright (c) 2002
13  * Company:       indy
14  * @author        //rk
15  * @version 1.0
16  */
17
18 import java.util.*;
19 import mir.misc.Logfile;
20
21 public class StoreContainer {
22
23         private final static int    DEFAULT_SIZE=10;
24         private static Logfile      storeLog;
25         private static int          uniqueCounter=10000;
26
27         private LinkedList          container;
28         private StoreContainerType  stocType;
29         private int                 maxSize=DEFAULT_SIZE;
30         private int                 uniqueId;
31   private int                 addCount=0,removeCount=0,storeOutCount;
32   private int                 hitCount=0,missCount=0;
33
34         private StoreContainer() {};
35
36         public StoreContainer(StoreContainerType stoc_type) {
37                 this.uniqueId=++uniqueCounter;
38                 this.stocType=stoc_type;
39                 this.container=new LinkedList();
40         }
41
42         public StoreContainer(StoreContainerType stoc_type, int maxSize) {
43                 this();
44                 this.maxSize=maxSize;
45         }
46
47         public synchronized StorableObject use(StoreIdentifier sid) {
48     int hit = container.indexOf(sid);
49     if (hit>0) {
50       StoreIdentifier hitSid = (StoreIdentifier)container.get(hit);
51                   if ( hitSid!=null ) {
52          hitCount++;
53          return hitSid.use();
54                   }
55     }
56     missCount++;
57     return null;
58         }
59
60         public boolean has(StoreIdentifier sid) {
61                 return container.contains(sid);
62         }
63
64         public void add(StoreIdentifier sid) {
65                 if ( sid != null && sid.hasReference() ) {
66                         if ( has(sid) ) {
67                           moveToHead(sid);
68                           System.err.println("OBJECTStore: tried to add sid " + sid.toString() +
69                             " that was already in store.");
70       }
71                         else {
72                                 container.addFirst(sid);
73         shrinkIfNecessary();
74         addCount++;
75                         }
76                 }
77         }
78
79         /**
80          *  Method:       invalidate(StorableObject sto)
81          *  Description:  finds @see StorableObject, propagates invalidation to
82          *                @see StoreIdentifier and removes StoreIdentifier from
83          *                list.
84          */
85         public synchronized void invalidate(StoreIdentifier search_sid) {
86     if (search_sid!=null) {
87       int hit = container.indexOf(search_sid);
88       if (hit >0 ) {
89         StoreIdentifier sid = (StoreIdentifier)container.get(hit);
90         container.remove(sid);
91         sid.invalidate();
92         removeCount++;
93       }
94     }
95         }
96
97   public synchronized void invalidate() {
98     StoreIdentifier sid;
99     while (container.size() > 0) {
100       sid=(StoreIdentifier)container.getLast();
101       container.removeLast();
102       sid.invalidate();
103     }
104   }
105
106         /**
107          *  Method:       setSize
108          *  Description:  readjusts StoreContainer size to value.
109          *
110          */
111         public void setSize(int size) {
112                 if (size <0) return;
113     shrinkToSize(size);
114                 this.maxSize=size;
115         }
116
117         private void shrinkIfNecessary() { shrinkToSize(maxSize); }
118
119   private void shrinkToSize(int size) {
120     if ( size < container.size() ) {
121                         // shrink
122                         while (size < container.size() ) {
123                                 StoreIdentifier sid = (StoreIdentifier)container.getLast();
124                                 container.remove(sid);
125         sid.release();
126         storeOutCount++;
127                         }
128                 }
129   }
130
131   private synchronized void moveToHead(StoreIdentifier sid) {
132     if ( sid!=null ) {
133       container.remove(sid);
134       container.addFirst(sid);
135     }
136   }
137
138         /**
139          *  Method:       toString()
140          *  Description:  gives out statistical Information, viewable via
141          *                @see ServletStoreInfo.
142          *
143          *  @return       String
144          */
145         public String toString() {
146     float hitRatio=0;
147     long divisor=hitCount+missCount;
148     if (divisor>0) hitRatio=(float)hitCount/(float)divisor;
149     hitRatio*=100;
150
151                 StringBuffer sb = new StringBuffer("StoreContainer id: ");
152                 sb.append(uniqueId).append(" for ");
153                 sb.append(stocType.toString()).append("\n  [current/maximum size: ");
154                 sb.append(container.size()).append("/").append(maxSize);
155                 sb.append("]\n  [added/stored out/removed: ").append(addCount).append("/");
156     sb.append(storeOutCount).append("/").append(removeCount).append("]\n  [hit/miss/ratio: ");
157     sb.append(hitCount).append("/").append(missCount).append("/");
158     sb.append(hitRatio).append("%]\n");
159
160     /** @todo list members ? */
161                 return sb.toString();
162         }
163
164 }