Mir goes GPL
[mir.git] / source / mir / storage / store / StoreContainer.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mir.storage.store;
33
34 /**
35  * Title:         StoreContainer
36  *
37  * Description:   This is the bucket object for one type of StorableObjects,
38  *                mainy a linked list of StoreIdenfiers. On use or creation
39  *                an object stored in StoreIdentifier is put to head of the
40  *                list. if maximum size of the list is reached, the
41  *                StoreIdentifier at the end of the list is released.
42  *
43  * Copyright:     Copyright (c) 2002
44  * Company:       indy
45  * @author        //rk
46  * @version 1.0
47  */
48
49 import java.util.*;
50 import javax.servlet.http.*;
51 import mir.misc.*;
52
53 public class StoreContainer {
54
55         private final static int    DEFAULT_SIZE=10;
56         private static Logfile      storeLog;
57         private static int          uniqueCounter=10000;
58
59         private LinkedList          container;
60         private StoreContainerType  stocType;
61         private int                 maxSize=DEFAULT_SIZE, uniqueId;
62   private int                 addCount=0,removeCount=0,storeOutCount;
63   private int                 hitCount=0,missCount=0;
64   private static ObjectStore  o_store = ObjectStore.getInstance();
65
66         // avoid construction without parameters
67   private StoreContainer() {};
68
69         public StoreContainer(StoreContainerType stoc_type) {
70                 this.uniqueId=++uniqueCounter;
71                 this.stocType=stoc_type;
72                 this.container=new LinkedList();
73     int defaultSize = stoc_type.getDefaultSize();
74     String confProperty = stoc_type.getConfPrefix()+".DefaultSize";
75     String confedSize = o_store.getConfProperty(confProperty);
76     if ( confedSize!=null ) {
77       this.maxSize = StringUtil.parseInt (confedSize, defaultSize);
78     }
79         }
80
81         public StoreContainer(StoreContainerType stoc_type, int maxSize) {
82                 this();
83                 this.maxSize=maxSize;
84         }
85
86
87
88         public synchronized StorableObject use(StoreIdentifier sid) {
89     int hit = container.indexOf(sid);
90     if (hit>=0) {
91       StoreIdentifier hitSid = (StoreIdentifier)container.get(hit);
92                   if ( hitSid!=null ) {
93          hitCount++;
94          return hitSid.use();
95                   }
96     }
97     missCount++;
98     return null;
99         }
100
101         public boolean has(StoreIdentifier sid) {
102                 return container.contains(sid);
103         }
104
105         public void add(StoreIdentifier sid) {
106                 if ( sid != null && sid.hasReference() ) {
107                         if ( has(sid) ) {
108                           moveToHead(sid);
109                           System.err.println("OBJECTStore: tried to add sid " + sid.toString() +
110                             " that was already in store.");
111       }
112                         else {
113                                 container.addFirst(sid);
114         shrinkIfNecessary();
115         addCount++;
116                         }
117                 }
118         }
119
120         /**
121          *  Method:       invalidate(StorableObject sto)
122          *  Description:  finds @see StorableObject, propagates invalidation to
123          *                @see StoreIdentifier and removes StoreIdentifier from
124          *                list.
125          */
126         public synchronized void invalidate(StoreIdentifier search_sid) {
127     if (search_sid!=null) {
128       int hit = container.indexOf(search_sid);
129       if (hit >0 ) {
130         StoreIdentifier sid = (StoreIdentifier)container.get(hit);
131         container.remove(sid);
132         sid.invalidate();
133         removeCount++;
134       }
135     }
136         }
137
138   public synchronized void invalidate() {
139     StoreIdentifier sid;
140     while (container.size() > 0) {
141       sid=(StoreIdentifier)container.getLast();
142       container.removeLast();
143       sid.invalidate();
144     }
145   }
146
147         /**
148          *  Method:       setSize
149          *  Description:  readjusts StoreContainer size to value.
150          *
151          */
152         public void setSize(int size) {
153                 if (size <0) return;
154     shrinkToSize(size);
155                 this.maxSize=size;
156         }
157
158         private void shrinkIfNecessary() { shrinkToSize(maxSize); }
159
160   private void shrinkToSize(int size) {
161     if ( size < container.size() ) {
162                         // shrink
163                         while (size < container.size() ) {
164                                 StoreIdentifier sid = (StoreIdentifier)container.getLast();
165                                 container.remove(sid);
166         sid.release();
167         storeOutCount++;
168                         }
169                 }
170   }
171
172   private synchronized void moveToHead(StoreIdentifier sid) {
173     if ( sid!=null ) {
174       container.remove(sid);
175       container.addFirst(sid);
176     }
177   }
178
179         /**
180          *  Method:       toString()
181          *  Description:  gives out statistical Information, viewable via
182          *                @see ServletStoreInfo.
183          *
184          *  @return       String
185          */
186         public String toString() {
187     return toHtml(null);
188         }
189
190   public String toHtml(HttpServletRequest req) {
191     boolean showingContent=false;
192     float hitRatio=0;
193     long divisor=hitCount+missCount;
194     if (divisor>0) hitRatio=(float)hitCount/(float)divisor;
195     hitRatio*=100;
196
197                 StringBuffer sb = new StringBuffer("StoreContainer id: ");
198                 sb.append(uniqueId).append(" for ");
199                 sb.append(stocType.toString());
200     if ( req!=null ) {
201       String show = req.getParameter("stoc_show");
202       if ( show!=null && show.equals(""+uniqueId) ) {
203         // show all entries in container
204         sb.append(" [<b>showing</b>]");
205         showingContent=true;
206       }
207       else
208         sb.append(" [<a href=\"?stoc_show="+uniqueId+"\">show</a>]");
209     }
210     sb.append("\n  [current/maximum size: ");
211                 sb.append(container.size()).append("/").append(maxSize);
212                 sb.append("]\n  [added/stored out/removed: ").append(addCount).append("/");
213     sb.append(storeOutCount).append("/").append(removeCount).append("]\n  [hit/miss/ratio: ");
214     sb.append(hitCount).append("/").append(missCount).append("/");
215     sb.append(hitRatio).append("%]\n");
216
217     if (showingContent) {
218       sb.append("  <b>Container contains following references:</b>\n  ");
219       ListIterator it = container.listIterator();
220       while ( it.hasNext() ) {
221         StoreIdentifier sid = (StoreIdentifier)it.next();
222         sb.append(sid.toString()).append("\n  ");
223       }
224       sb.append("<b>End of List</b>\n\n");
225
226     }
227
228                 return sb.toString();
229         }
230
231 }