gwenhywfar  4.6.0beta
multicache.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Wed May 08 2013
3  copyright : (C) 2013 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #define DISABLE_DEBUGLOG
30 
31 #include "multicache_p.h"
32 
33 #include <gwenhywfar/debug.h>
34 
35 
36 
37 GWEN_LIST_FUNCTIONS(GWEN_MULTICACHE_ENTRY, GWEN_MultiCache_Entry);
38 GWEN_IDMAP_FUNCTIONS(GWEN_MULTICACHE_ENTRY, GWEN_MultiCache_Entry);
39 GWEN_LIST_FUNCTIONS(GWEN_MULTICACHE_TYPE, GWEN_MultiCache_Type);
40 
41 
42 
43 
44 GWEN_MULTICACHE_ENTRY *GWEN_MultiCache_Entry_new(GWEN_MULTICACHE_TYPE *ct, uint32_t id, void *p, uint32_t i) {
45  GWEN_MULTICACHE_ENTRY *e;
46 
47  GWEN_NEW_OBJECT(GWEN_MULTICACHE_ENTRY, e);
48  GWEN_LIST_INIT(GWEN_MULTICACHE_ENTRY, e);
49 
50  e->cacheType=ct;
51  e->id=id;
52  e->dataPtr=p;
53  e->dataSize=i;
54 
55  return e;
56 }
57 
58 
59 
60 void GWEN_MultiCache_Entry_free(GWEN_MULTICACHE_ENTRY *e) {
61  if (e) {
62  GWEN_LIST_FINI(GWEN_MULTICACHE_ENTRY, e);
64  }
65 }
66 
67 
68 
69 uint32_t GWEN_MultiCache_Entry_GetId(const GWEN_MULTICACHE_ENTRY *e) {
70  assert(e);
71  return e->id;
72 }
73 
74 
75 
76 uint32_t GWEN_MultiCache_Entry_GetDataSize(const GWEN_MULTICACHE_ENTRY *e) {
77  assert(e);
78  return e->dataSize;
79 }
80 
81 
82 
83 void *GWEN_MultiCache_Entry_GetDataPtr(const GWEN_MULTICACHE_ENTRY *e) {
84  assert(e);
85  return e->dataPtr;
86 }
87 
88 
89 
90 GWEN_MULTICACHE_TYPE *GWEN_MultiCache_Entry_GetCacheType(const GWEN_MULTICACHE_ENTRY *e) {
91  assert(e);
92  return e->cacheType;
93 }
94 
95 
96 
97 uint32_t GWEN_MultiCache_Entry_GetParam1(const GWEN_MULTICACHE_ENTRY *e) {
98  assert(e);
99  return e->param1;
100 }
101 
102 
103 
104 void GWEN_MultiCache_Entry_SetParam1(GWEN_MULTICACHE_ENTRY *e, uint32_t i) {
105  assert(e);
106  e->param1=i;
107 }
108 
109 
110 
111 uint32_t GWEN_MultiCache_Entry_GetParam2(const GWEN_MULTICACHE_ENTRY *e) {
112  assert(e);
113  return e->param2;
114 }
115 
116 
117 
118 void GWEN_MultiCache_Entry_SetParam2(GWEN_MULTICACHE_ENTRY *e, uint32_t i) {
119  assert(e);
120  e->param2=i;
121 }
122 
123 
124 
125 uint32_t GWEN_MultiCache_Entry_GetParam3(const GWEN_MULTICACHE_ENTRY *e) {
126  assert(e);
127  return e->param3;
128 }
129 
130 
131 
132 void GWEN_MultiCache_Entry_SetParam3(GWEN_MULTICACHE_ENTRY *e, uint32_t i) {
133  assert(e);
134  e->param3=i;
135 }
136 
137 
138 
139 uint32_t GWEN_MultiCache_Entry_GetParam4(const GWEN_MULTICACHE_ENTRY *e) {
140  assert(e);
141  return e->param4;
142 }
143 
144 
145 
146 void GWEN_MultiCache_Entry_SetParam4(GWEN_MULTICACHE_ENTRY *e, uint32_t i) {
147  assert(e);
148  e->param4=i;
149 }
150 
151 
152 
153 
154 
155 
156 
157 
158 
161 
164 
165  ct->multiCache=mc;
166  ct->entryMap=GWEN_MultiCache_Entry_IdMap_new(GWEN_IdMapAlgo_Hex4);
167 
168  return ct;
169 }
170 
171 
172 
174  if (ct) {
175  GWEN_MultiCache_ReleaseEntriesForType(ct->multiCache, ct);
177  GWEN_FREE_OBJECT(ct);
178  }
179 }
180 
181 
182 
183 void *GWEN_MultiCache_Type_GetData(const GWEN_MULTICACHE_TYPE *ct, uint32_t id) {
184  GWEN_MULTICACHE_ENTRY *e;
185 
186  e=(GWEN_MULTICACHE_ENTRY*)GWEN_MultiCache_Entry_IdMap_Find(ct->entryMap, id);
187  if (e) {
188  void *p;
189 
190  GWEN_MultiCache_UsingEntry(ct->multiCache, e);
193  return p;
194  }
195  return NULL;
196 }
197 
198 
199 
201  uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) {
202 
203  GWEN_MULTICACHE_ENTRY *e;
204 
205  e=(GWEN_MULTICACHE_ENTRY*)GWEN_MultiCache_Entry_IdMap_Find(ct->entryMap, id);
206  if (e) {
207  if ((GWEN_MultiCache_Entry_GetParam1(e)==param1) &&
208  (GWEN_MultiCache_Entry_GetParam2(e)==param2) &&
209  (GWEN_MultiCache_Entry_GetParam3(e)==param3) &&
210  (GWEN_MultiCache_Entry_GetParam4(e)==param4)) {
211  void *p;
212 
213  GWEN_MultiCache_UsingEntry(ct->multiCache, e);
216  return p;
217  }
218  }
219  return NULL;
220 }
221 
222 
223 
224 void GWEN_MultiCache_Type_SetData(GWEN_MULTICACHE_TYPE *ct, uint32_t id, void *ptr, uint32_t size) {
225  GWEN_MULTICACHE_ENTRY *e;
226 
228  e=GWEN_MultiCache_Entry_new(ct, id, ptr, size);
229  GWEN_MultiCache_AddEntry(ct->multiCache, e);
230  GWEN_MultiCache_Entry_IdMap_Insert(ct->entryMap, id, (void*) e);
231 }
232 
233 
234 
235 void GWEN_MultiCache_Type_SetDataWithParams(GWEN_MULTICACHE_TYPE *ct, uint32_t id, void *ptr, uint32_t size,
236  uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) {
237  GWEN_MULTICACHE_ENTRY *e;
238 
240 
241  e=GWEN_MultiCache_Entry_new(ct, id, ptr, size);
242  GWEN_MultiCache_AddEntry(ct->multiCache, e);
247  GWEN_MultiCache_Entry_IdMap_Insert(ct->entryMap, id, (void*) e);
248 }
249 
250 
251 
253  GWEN_MULTICACHE_ENTRY *e;
254 
255  e=(GWEN_MULTICACHE_ENTRY*)GWEN_MultiCache_Entry_IdMap_Find(ct->entryMap, id);
256  if (e)
257  GWEN_MultiCache_ReleaseEntry(ct->multiCache, e);
258 }
259 
260 
261 
263  GWEN_MultiCache_ReleaseEntriesForType(ct->multiCache, ct);
264 }
265 
266 
267 
269  assert(ct);
270  ct->attachFn=fn;
271 }
272 
273 
274 
276  assert(ct);
277  ct->freeFn=fn;
278 }
279 
280 
281 
283  assert(ct);
284  if (ct->attachFn)
285  return ct->attachFn(p);
286  else
288 }
289 
290 
291 
293  assert(ct);
294  if (ct->freeFn)
295  return ct->freeFn(p);
296  else
298 }
299 
300 
301 void GWEN_MultiCache_Type_ReleaseEntry(GWEN_MULTICACHE_TYPE *ct, GWEN_MULTICACHE_ENTRY *e) {
302  assert(ct);
303  assert(e);
304 
305  GWEN_MultiCache_Entry_IdMap_Remove(ct->entryMap, GWEN_MultiCache_Entry_GetId(e));
306 }
307 
308 
309 
310 
311 
312 
313 
315  GWEN_MULTICACHE *mc;
316 
318  mc->maxSize=maxSize;
319  mc->typeList=GWEN_MultiCache_Type_List_new();
320  mc->entryList=GWEN_MultiCache_Entry_List_new();
321 
322  return mc;
323 }
324 
325 
326 
328  if (mc) {
329  GWEN_MULTICACHE_ENTRY *ce;
330 
331  ce=GWEN_MultiCache_Entry_List_First(mc->entryList);
332  while(ce) {
334  ce=GWEN_MultiCache_Entry_List_First(mc->entryList);
335  }
336 
337  GWEN_MultiCache_Entry_List_free(mc->entryList);
338  GWEN_MultiCache_Type_List_free(mc->typeList);
339  GWEN_FREE_OBJECT(mc);
340  }
341 }
342 
343 
344 
346  assert(mc);
347  return mc->maxSizeUsed;
348 }
349 
350 
351 
352 int GWEN_MultiCache_AddEntry(GWEN_MULTICACHE *mc, GWEN_MULTICACHE_ENTRY *e) {
353  uint32_t esize;
354 
355  assert(mc);
356  assert(e);
357 
359  if ((mc->currentSize+esize)>mc->maxSize) {
360  int64_t nsize;
361 
362  /* make room */
363  nsize=(mc->currentSize+esize)-mc->maxSize;
364  while(nsize>0) {
365  GWEN_MULTICACHE_ENTRY *ce;
366 
367  ce=GWEN_MultiCache_Entry_List_First(mc->entryList);
368  if (ce) {
371  }
372  else {
373  DBG_ERROR(GWEN_LOGDOMAIN, "No entry left to release, cache size limit too low");
374  return GWEN_ERROR_MEMORY_FULL;
375  }
376  }
377  }
378 
379  mc->currentSize+=esize;
380  if (mc->currentSize>mc->maxSizeUsed)
381  mc->maxSizeUsed=mc->currentSize;
383  GWEN_MultiCache_Entry_List_Add(e, mc->entryList);
384  return 0;
385 }
386 
387 
388 
389 void GWEN_MultiCache_ReleaseEntry(GWEN_MULTICACHE *mc, GWEN_MULTICACHE_ENTRY *e) {
390  uint32_t esize;
391 
392  assert(mc);
393  assert(e);
394  assert(e->cacheType);
395 
396  /* remove from list first */
397  GWEN_MultiCache_Entry_List_Del(e);
398 
399  /* release from type's idmap */
401 
402  /* release */
406  mc->currentSize-=esize;
407 }
408 
409 
410 
412  GWEN_MULTICACHE_ENTRY *ce;
413 
414  assert(mc);
415  assert(ct);
416 
417 
418  ce=GWEN_MultiCache_Entry_List_First(mc->entryList);
419  while(ce) {
420  GWEN_MULTICACHE_ENTRY *ceNext;
421 
422  ceNext=GWEN_MultiCache_Entry_List_Next(ce);
425  ce=ceNext;
426  }
427 }
428 
429 
430 
431 void GWEN_MultiCache_UsingEntry(GWEN_MULTICACHE *mc, GWEN_MULTICACHE_ENTRY *e) {
432  assert(mc);
433 
434  /* move cache entry to the end of the list */
435  GWEN_MultiCache_Entry_List_Del(e);
436  GWEN_MultiCache_Entry_List_Add(e, mc->entryList);
437 }
438 
439 
440 
441 
442 
443 
444