root/coldbox/trunk/system/cache/ObjectPool.cfc @ 1976

Revision 1976, 11.9 kB (checked in by lmajano, 4 years ago)

Fix when retrieveing sof reference lookbacks if not found.

Line 
1<!-----------------------------------------------------------------------
2********************************************************************************
3Copyright 2005-2008 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4www.coldboxframework.com | www.luismajano.com | www.ortussolutions.com
5********************************************************************************
6
7Author      :   Luis Majano
8Date        :   January 18, 2007
9Description :
10        This is an object cache pool.
11
12Modification History:
1301/18/2007 - Created
14----------------------------------------------------------------------->
15<cfcomponent name="ObjectPool" hint="I manage persistance for objects." output="false">
16
17<!------------------------------------------- CONSTRUCTOR ------------------------------------------->
18
19        <cffunction name="init" access="public" output="false" returntype="ObjectPool" hint="Constructor">
20                <cfscript>
21                        var Collections = createObject("java", "java.util.Collections");
22                        /* Create the reference maps */
23                        var Map = CreateObject("java","java.util.HashMap").init();
24                        var MetadataMap = CreateObject("java","java.util.HashMap").init();
25                        var SoftRefKeyMap = CreateObject("java","java.util.HashMap").init();
26                       
27                        /* Prepare instance */
28                        variables.instance = structnew();
29                       
30                        /* Instantiate object pools */
31                        setpool( Collections.synchronizedMap( Map ) );
32                        setpool_metadata( Collections.synchronizedMap( MetadataMap ) );
33                        setSoftRefKeyMap( Collections.synchronizedMap(SoftRefKeyMap) );
34                       
35                        /* Register the reference queue for our soft references */
36                        setReferenceQueue( CreateObject("java","java.lang.ref.ReferenceQueue").init() );
37                       
38                        /* Return pool */
39                        return this;
40                </cfscript>
41        </cffunction>
42
43<!------------------------------------------- PUBLIC ------------------------------------------->
44       
45        <!--- Get/Set the Ref Queue --->
46        <cffunction name="getReferenceQueue" access="public" output="false" returntype="any" hint="Get ReferenceQueue">
47                <cfreturn instance.ReferenceQueue/>
48        </cffunction>   
49       
50        <!--- Get/Set Soft Reference KeyMap --->
51        <cffunction name="getSoftRefKeyMap" access="public" output="false" returntype="any" hint="Get SoftRefKeyMap">
52                <cfreturn instance.SoftRefKeyMap/>
53        </cffunction>   
54               
55        <!--- Check if the soft reference exists --->
56        <cffunction name="softRefLookup" access="public" returntype="boolean" hint="See if the soft reference is in the key map" output="false" >
57                <cfargument name="softRef" required="true" type="any" hint="The soft reference to check">
58                <cfreturn structKeyExists(getSoftRefKeyMap(),arguments.softRef)>
59        </cffunction>
60       
61        <!--- Get the ref key --->
62        <cffunction name="getSoftRefKey" access="public" returntype="any" hint="Get the soft reference's key from the soft reference lookback map" output="false" >
63                <cfargument name="softRef" required="true" type="any" hint="The soft reference to check">
64                <cfscript>
65                        var keyMap = getSoftRefKeyMap();
66                        if( structKeyExists(keyMap,arguments.softRef) ){
67                                return keyMap[arguments.softRef];
68                        }
69                        else{
70                                return "NOT_FOUND";
71                        }
72                </cfscript>
73        </cffunction>
74       
75        <!--- Getter/Setter For pool --->
76        <cffunction name="getpool" access="public" returntype="any" output="false" hint="Get the cache pool">
77                <cfreturn instance.pool>
78        </cffunction>
79       
80        <!--- Getter/Setter for Pool Metdata --->
81        <cffunction name="getpool_metadata" access="public" returntype="any" output="false" hint="Get the cache pool metadata">
82                <cfreturn instance.pool_metadata >
83        </cffunction>
84
85        <!--- Setter/Getter metdata property --->
86        <cffunction name="getObjectMetadata" access="public" returntype="any" output="false" hint="Get a metadata entry for a specific cache entry">
87                <cfargument name="objectKey" type="any" required="true">
88                <cfreturn instance.pool_metadata[arguments.objectKey] >
89        </cffunction>
90        <cffunction name="setObjectMetadata" access="public" returntype="void" output="false" hint="Set the metadata entry for a specific cache entry">
91                <cfargument name="objectKey" type="any" required="true">
92                <cfargument name="metadata"  type="any" required="true">
93                <cfset instance.pool_metadata[arguments.objectKey] = arguments.metadata>
94        </cffunction>
95        <cffunction name="getMetadataProperty" access="public" returntype="any" output="false" hint="Get a metadata property for a specific cache entry">
96                <cfargument name="objectKey" type="any" required="true">
97                <cfargument name="property"  type="any" required="true">
98                <cfreturn instance.pool_metadata[arguments.objectKey][arguments.property] >
99        </cffunction>
100        <cffunction name="setMetadataProperty" access="public" returntype="void" output="false" hint="Set a metadata property for a specific cache entry">
101                <cfargument name="objectKey" type="any" required="true">
102                <cfargument name="property"  type="any" required="true">
103                <cfargument name="value"         type="any"    required="true">
104                <cfset instance.pool_metadata[arguments.objectKey][arguments.property] = arguments.value >
105        </cffunction>
106
107        <!--- Simple Object Lookup --->
108        <cffunction name="lookup" access="public" output="false" returntype="boolean" hint="Check if an object is in cache, it doesn't tell you if the soft reference expired or not">
109                <!--- ************************************************************* --->
110                <cfargument name="objectKey" type="any" required="true">
111                <!--- ************************************************************* --->
112                <!--- Check for Object in Cache. --->
113                <cfreturn structKeyExists(instance.pool, arguments.objectKey) >
114        </cffunction>
115
116        <!--- Get an object from the pool --->
117        <cffunction name="get" access="public" output="false" returntype="any" hint="Get an object from cache. If its a soft reference object it might return a null value.">
118                <!--- ************************************************************* --->
119                <cfargument name="objectKey" type="any" required="true">
120                <!--- ************************************************************* --->
121                <cfscript>
122                        var tmpObj = 0;
123                       
124                        /* Record Metadata Access */
125                        setMetadataProperty(arguments.objectKey,"hits", getMetaDataProperty(arguments.objectKey,"hits")+1);
126                        setMetadataProperty(arguments.objectKey,"lastAccesed", now());
127                       
128                        /* Get Object */
129                        tmpObj = instance.pool[arguments.objectKey];
130                       
131                        /* Validate if SR or eternal */
132                        if( isSoftReference(tmpObj) ){
133                                return tmpObj.get();
134                        }
135                        else{
136                                return tmpObj;
137                        }
138                </cfscript>
139        </cffunction>
140
141        <!--- Set an Object in the pool --->
142        <cffunction name="set" access="public" output="false" returntype="void" hint="sets an object in cache.">
143                <!--- ************************************************************* --->
144                <cfargument name="objectKey"                    type="any"  required="true">
145                <cfargument name="MyObject"                             type="any"      required="true">
146                <cfargument name="Timeout"                              type="any"  required="false" default="" hint="Timeout in minutes. If timeout = 0 then object never times out. If timeout is blank, then timeout will be inherited from framework.">
147                <cfargument name="LastAccessTimeout"    type="any"  required="false" default="" hint="Timeout in minutes. If timeout is blank, then timeout will be inherited from framework.">
148                <!--- ************************************************************* --->
149                <cfscript>
150                        var MetaData = structnew();
151                        var targetObj = 0;
152                       
153                        /* Check for eternal object */
154                        if( arguments.timeout neq 0 ){
155                                /* Cache as soft reference not an eternal object */
156                                targetObj = createSoftReference(arguments.objectKey,arguments.MyObject);
157                        }
158                        else{
159                                targetObj = arguments.MyObject;
160                        }
161                       
162                        /* Set new Object into cache pool */
163                        instance.pool[arguments.objectKey] = targetObj;
164                       
165                        /* Create object's metdata */
166                        MetaData.hits = 1;
167                        MetaData.Timeout = arguments.timeout;
168                        MetaData.LastAccessTimeout = arguments.LastAccessTimeout;
169                        MetaData.Created = now();
170                        MetaData.LastAccesed = now();                   
171                       
172                        /* Save the metadata */
173                        setObjectMetaData(arguments.objectkey,MetaData);
174                </cfscript>
175        </cffunction>
176
177        <!--- Clear an object from the pool --->
178        <cffunction name="clearKey" access="public" output="false" returntype="boolean" hint="Clears a key from the cache.">
179                <!--- ************************************************************* --->
180                <cfargument name="objectKey" type="string" required="true">
181                <!--- ************************************************************* --->
182                <cfscript>
183                        var Results = false;
184                        var softRef = "";
185                       
186                        try{
187                                /* Is this a soft Ref */
188                                softRef = instance.pool[arguments.objectKey];
189                                /* Removal of Soft Ref Lookup */
190                                if( isSoftReference(softRef) ){
191                                        structDelete(getSoftRefKeyMap(),softRef);
192                                }
193                               
194                                /* Remove Normal Cache Entries */
195                                structDelete(getPool(),arguments.objectKey);
196                                structDelete(getpool_metadata(),arguments.objectKey);
197                                                               
198                                /* Removed */
199                                Results = true;
200                        }
201                        catch(Any e){
202                                //Nothing;
203                        }
204                        return Results;
205                </cfscript>
206        </cffunction>
207
208        <!--- Get the size of the pool --->
209        <cffunction name="getSize" access="public" output="false" returntype="numeric" hint="Get the cache's size in items">
210                <cfreturn StructCount(getPool())>
211        </cffunction>
212
213        <!--- Get the itemList --->
214        <cffunction name="getObjectsKeyList" access="public" output="false" returntype="string" hint="Get the cache's object entries listing.">
215                <cfreturn structKeyList(getPool())>
216        </cffunction>
217
218<!------------------------------------------- PRIVATE ------------------------------------------->
219
220        <!--- Set the pool_metadata --->
221        <cffunction name="setpool_metadata" access="public" returntype="void" output="false" hint="Set the cache pool metadata">
222                <cfargument name="pool_metadata" type="struct" required="true">
223                <cfset instance.pool_metadata = arguments.pool_metadata>
224        </cffunction>
225       
226        <!--- Set the object pool --->
227        <cffunction name="setpool" access="private" returntype="void" output="false" hint="Set the cache pool">
228                <cfargument name="pool" type="struct" required="true">
229                <cfset instance.pool = arguments.pool>
230        </cffunction>
231
232        <!--- Set the reference queue --->
233        <cffunction name="setReferenceQueue" access="private" output="false" returntype="void" hint="Set ReferenceQueue">
234                <cfargument name="ReferenceQueue" type="any" required="true"/>
235                <cfset instance.ReferenceQueue = arguments.ReferenceQueue/>
236        </cffunction>
237       
238        <!--- Set the soft ref key map --->
239        <cffunction name="setSoftRefKeyMap" access="private" output="false" returntype="void" hint="Set SoftRefKeyMap">
240                <cfargument name="SoftRefKeyMap" type="any" required="true"/>
241                <cfset instance.SoftRefKeyMap = arguments.SoftRefKeyMap/>
242        </cffunction>
243       
244        <!--- Create a soft referenec --->
245        <cffunction name="createSoftReference" access="private" returntype="any" hint="Create SR, register cached object and reference" output="false" >
246                <!--- ************************************************************* --->
247                <cfargument name="objectKey" type="any"         required="true" hint="The value of the key pair">
248                <cfargument name="MyObject"      type="any"     required="true" hint="The object to wrap">
249                <!--- ************************************************************* --->
250                <cfscript>
251                        /* Create Soft Reference Wrapper and register with Queue */
252                        var softRef = CreateObject("java","java.lang.ref.SoftReference").init(arguments.MyObject,getReferenceQueue());
253                        var RefKeyMap = getSoftRefKeyMap();
254                       
255                        /* Create Reverse Mapping */
256                        RefKeyMap[softRef] = arguments.objectKey;
257                       
258                        /* Return object */
259                        return softRef;
260                </cfscript>
261        </cffunction>
262       
263        <!--- Check if this is a soft referene --->
264        <cffunction name="isSoftReference" access="private" returntype="boolean" hint="Whether the passed object is a soft reference" output="false" >
265                <cfargument name="MyObject"      type="any" required="true" hint="The object to test">
266                <cfscript>
267                        if( isObject(arguments.myObject) and getMetaData(arguments.MyObject).name eq "java.lang.ref.SoftReference" ){
268                                return true;
269                        }
270                        else{
271                                return false;
272                        }                       
273                </cfscript>
274        </cffunction>
275
276</cfcomponent>
Note: See TracBrowser for help on using the browser.