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