DBA Data[Home] [Help]

PACKAGE BODY: APPS.WF_OBJECT_CACHE

Source


1 package body WF_OBJECT_CACHE as
2 /* $Header: WFOBCACB.pls 120.0.12010000.2 2008/08/09 13:36:23 sstomar ship $ */
3 
4 /*-------------------+
5  | Caching strutures |
6  +-------------------*/
7 
8 g_Object           WF_OBJECTS_T;
9 g_Object_List      WF_OBJECTS_TAB_T;
10 
11 /*------------+
12  | Procedures |
13  +------------*/
14 
15 -- SetCacheSize
16 --   Procedure to set the maximum size of the cache.
17 procedure SetCacheSize(p_size in number)
18 is
19 begin
20   g_cacheMaxSize := p_size;
21 end SetCacheSize;
22 
23 -- GetHashValue (PRIVATE)
24 --   This function generates hash value for a given name
25 function getHashValue(p_hash_name in varchar2)
26 return number
27 is
28 begin
29   return dbms_utility.get_hash_value(p_hash_name, g_hashBase, g_hashSize);
30 end getHashValue;
31 
32 -- CreateCache
33 --   Procedure to create a new cache to store an object type.
34 --   For example,
35 --   in BES if Events, Agents and Systems are the objects to be cached,
36 --   each of these object types would be referenced with an unique
37 --   identifier and this API called with that identifier. The identifier
38 --   would be used to store and retrieve that object type in cache.
39 procedure CreateCache(p_cache_index in varchar2)
40 is
41 begin
42 
43   -- if already created, donot create. it will overwrite the cached
44   -- objects
45   if (g_Object_List.EXISTS(p_cache_index)) then
46     return;
47   end if;
48 
49   -- Initialize the cache list and its related variables
50   g_Object_List(p_cache_index).Cache_Objs := g_Object;
51   g_Object_List(p_cache_index).Hash_Val(1) := null;
52   g_Object_List(p_cache_index).Curr_Idx := 1;
53   g_Object_List(p_cache_index).Overflow := false;
54 
55 exception
56   when others then
57     wf_core.context('WF_OBJECT_CACHE', 'CreateCache', p_cache_index);
58     raise;
59 end CreateCache;
60 
61 -- IsCacheCreated
62 --   Function that checks if cache is already created for a given cache index
63 --   If cache is already created, it need not be created again.
64 function IsCacheCreated(p_cache_index in number)
65 return boolean
66 is
67 begin
68   -- Check if cache is available for this object in the cache list
69   if (g_Object_List.COUNT = 0) then
70     return false;
71   else
72     return g_Object_List.EXISTS(p_cache_index);
73   end if;
74 end IsCacheCreated;
75 
76 --
77 -- Check_Size (PRIVATE)
78 --   Checks the size of the cache object. If the cache has exceeded the
79 --   max size specified, removes the oldest record in that cache.
80 --
81 procedure Check_Size(p_cache_key    in number,
82                      p_object_key   in number)
83 is
84   l_oldest   number;
85   l_currIdx  number;
86 begin
87   l_currIdx :=  g_Object_List(p_cache_key).Curr_Idx;
88 
89   if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
90     wf_log_pkg.string(wf_log_pkg.level_statement,
91                     'wf.plsql.WF_OBJECT_CACHE.Check_Size.Begin',
92                     'Checking size of Cache. CurrIdx {'||l_currIdx||'}');
93   end if;
94 
95   -- Check the current age pointer against max cache size
96   if (l_currIdx > g_cacheMaxSize) then
97     -- Reset the current index pointing to the hash value
98     l_currIdx := mod(l_currIdx, g_cacheMaxSize);
99     g_Object_List(p_cache_key).Curr_Idx := l_currIdx;
100 
101     g_Object_List(p_cache_key).Overflow := true;
102     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
103       wf_log_pkg.string(wf_log_pkg.level_statement,
104                       'wf.plsql.WF_OBJECT_CACHE.Check_Size.Begin',
105                       'Curr Idx exceeded Max Cache size, reseting CurrIdx. '||
106                       ' Max Cache Size {'||g_cacheMaxSize||'}');
107     end if;
108   end if;
109 
110   -- If the cache has reached it's max size, remove the oldest record
111   if (g_Object_List(p_cache_key).Overflow) then
112     l_oldest := g_Object_List(p_cache_key).Hash_Val(l_currIdx);
113     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
114       wf_log_pkg.string(wf_log_pkg.level_statement,
115                       'wf.plsql.WF_OBJECT_CACHE.Check_Size.Begin',
116                       'Removing oldest record {'||l_oldest||'} from cache');
117     end if;
118     g_Object_List(p_cache_key).Cache_Objs.DELETE(l_oldest);
119   end if;
120 end Check_Size;
121 
122 function isDuplicate(p_cache_key    in number,
123                      p_object_key   in number)
124 return boolean
125 is
126 begin
127   return g_Object_List(p_cache_key).Cache_Objs.EXISTS(p_object_key);
128 end isDuplicate;
129 
130 procedure Assign_Object(p_object       in anydata,
131                         p_cache_key    in number,
132                         p_object_key   in number)
133 is
134   l_object  anyData;
135   l_exists  boolean;
136   l_currIdx number;
137 
138   l_event  wf_event_obj;
139   dummy pls_integer;
140   l_anyData sys.anyData;
141 begin
142   -- Set object would be called only if the required object was not already
143   -- in the cache.
144   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
145     wf_log_pkg.string(wf_log_pkg.level_procedure,
146                     'wf.plsql.WF_OBJECT_CACHE.Assign_Object.Begin',
147                     'Assigning object at {'||p_object_key||'} in cache {'||p_cache_key||'}');
148   end if;
149 
150   g_Object_List(p_cache_key).Cache_Objs(p_object_key) := p_object;
151 
152   l_currIdx := g_Object_List(p_cache_key).Curr_Idx;
153   g_Object_List(p_cache_key).Hash_Val(l_currIdx) := p_object_key;
154   if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
155     wf_log_pkg.string(wf_log_pkg.level_statement,
156                     'wf.plsql.WF_OBJECT_CACHE.Assign_Object.Begin',
157                     'Current Idx for age table is {'||l_currIdx||'}');
158   end if;
159 
160   l_currIdx := l_currIdx + 1;
161   g_Object_List(p_cache_key).Curr_Idx := l_currIdx;
162 
163   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
164     wf_log_pkg.string(wf_log_pkg.level_procedure,
165                     'wf.plsql.WF_OBJECT_CACHE.Assign_Object.End',
166                     'Assigned object to cache. Next Idx {'||l_currIdx||'}');
167   end if;
168 end Assign_Object;
169 
170 -- SetObject
171 --   This procedure helps to store an object of type ANYDATA within a cache
172 --   that was previously created with CreateCache. The object is stored
173 --   within a PLSQL table under a subscript that is a hash value generated
174 --   from the object key.
175 --   For example,
176 --   If an event object is to be cached whose name is oracle.apps.vj.test,
177 --   a hash value is generated for event name oracle.apps.vj.test and the object
178 --   is stored under that location within the PLSQL table.
179 procedure SetObject(p_cache_index in number,
180                     p_object      in anydata,
181                     p_object_key  in varchar2)
182 is
183   l_cacheLoc   number;
184   l_objHashVal number;
185 
186 begin
187 
188   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
189     wf_log_pkg.string(wf_log_pkg.level_procedure,
190                     'wf.plsql.WF_OBJECT_CACHE.SetObject.Begin',
191                     'Setting object {'||p_object_key||'} in cache {'||p_cache_index||'}');
192   end if;
193 
194   l_cacheLoc := p_cache_index;
195   l_objHashVal := getHashValue(p_object_key);
196 
197   if (isDuplicate(l_cacheLoc, l_objHashVal)) then
198     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
199       wf_log_pkg.string(wf_log_pkg.level_statement,
200                       'wf.plsql.WF_OBJECT_CACHE.SetObject.Overwrite',
201                       'Object already in cache. Overwriting.');
202     end if;
203     -- If the object is already in cache, overwrite it. The new one might be an
204     -- updated one with more information
205     g_Object_List(l_cacheLoc).Cache_Objs(l_objHashVal) := p_object;
206   else
207     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
208       wf_log_pkg.string(wf_log_pkg.level_statement,
209                       'wf.plsql.WF_OBJECT_CACHE.SetObject.Assign',
210                       'Checking cache size and storing object in cache');
211     end if;
212     -- Checks if cache reached max size. If size reached, the oldest
213     -- record in that cache is removed to give space for the new one
214     Check_Size(l_cacheLoc, l_objHashVal);
215 
216     -- Assign the new object to the location as per hash value
217     Assign_Object(p_object, l_cacheLoc, l_objHashVal);
218   end if;
219 
220 exception
221   when others then
222     wf_core.context('WF_OBJECT_CACHE', 'SetObject', p_object_key);
223     raise;
224 end SetObject;
225 
226 -- GetObject
227 --   This procedure returns ANYDATA object from a given cache for a given
228 --   object cache.
229 function GetObject(p_cache_index in number,
230                    p_object_key  in  varchar2)
231 return anyData
232 is
233   l_cacheLoc   number;
234   l_objHashVal number;
235   l_idx number;
236   l_anyData sys.anyData;
237   dummy        pls_integer;
238   l_event      wf_event_obj;
239 begin
240 
241   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
242     wf_log_pkg.string(wf_log_pkg.level_procedure,
243                      'wf.plsql.WF_OBJECT_CACHE.GetObject.Begin',
244                      'Getting {'||p_object_key||'} from cache {'||p_cache_index||'}');
245   end if;
246 
247   l_cacheLoc := p_cache_index;
248   l_objHashVal := getHashValue(p_object_key);
249 
250   if (g_Object_List.EXISTS(l_cacheLoc) and
251       g_Object_List(l_cacheLoc).Cache_Objs.EXISTS(l_objHashVal)) then
252     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
253       wf_log_pkg.string(wf_log_pkg.level_statement,
254                       'wf.plsql.WF_OBJECT_CACHE.GetObject.Cache_Hit',
255                       'Object found in cache for {'||p_object_key||'}');
256     end if;
257     return g_Object_List(l_cacheLoc).Cache_Objs(l_objHashVal);
258   else
259     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
260       wf_log_pkg.string(wf_log_pkg.level_statement,
261                       'wf.plsql.WF_OBJECT_CACHE.GetObject.Cache_Hit',
262                       'Object not found in cache for {'||p_object_key||'}');
263     end if;
264     return null;
265   end if;
266 
267 exception
268   when others then
269     wf_core.context('WF_OBJECT_CACHE', 'GetObject', p_object_key);
270     raise;
271 end GetObject;
272 
273 -- GetAllObjects
274 --   This procedure returns all the ANYDATA objects cached under a given cache
275 function GetAllObjects(p_cache_index in number)
276 return wf_objects_t
277 is
278   l_objs wf_objects_t;
279 begin
280   if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
281     wf_log_pkg.string(wf_log_pkg.level_statement,
282                     'wf.plsql.WF_OBJECT_CACHE.GetAllObjects.Begin',
283                     'Returning all cached objects for {'||p_cache_index||'}');
284   end if;
285   return g_Object_List(p_cache_index).Cache_Objs;
286 end GetAllObjects;
287 
288 -- Clear
289 --   This procedure deletes all the caches from memory. This is done in case
290 --   cache is found to be invalid.
291 procedure Clear(p_cache_index in varchar2)
292 is
293   l_cacheLoc number;
294 begin
295 
296   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
297     wf_log_pkg.string(wf_log_pkg.level_procedure,
298                     'wf.plsql.WF_OBJECT_CACHE.Clear.Begin',
299                     'Clearing object at cache index {'||p_cache_index||'}');
300   end if;
301   -- If cache index is specified, delete only that specified cache
302   if (p_cache_index is not null) then
303     g_Object_List.DELETE(p_cache_index);
304   else
305     -- Since no name is specified, delete the complete cache
306     l_cacheLoc := g_Object_List.FIRST;
307 
308     while (l_cacheLoc is not null) loop
309       g_Object_List.DELETE(l_cacheLoc);
310       l_cacheLoc := g_Object_List.NEXT(l_cacheLoc);
311     end loop;
312   end if;
313 
314 end Clear;
315 
316 end WF_OBJECT_CACHE;