void GWEN_MemCache_PurgeEntries(GWEN_MEMCACHE *mc, uint32_t id, uint32_t mask) { GWEN_IDMAP_RESULT res; uint32_t currentId; assert(mc); GWEN_MemCache_Lock(mc); res=GWEN_MemCacheEntry_IdMap_GetFirst(mc->idMap, ¤tId); while(res==GWEN_IdMapResult_Ok) { uint32_t nextId; nextId=currentId; res=GWEN_MemCacheEntry_IdMap_GetNext(mc->idMap, &nextId); if ((currentId & mask)==id) { GWEN_MEMCACHE_ENTRY *me; me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, currentId); if (me) { me->isValid=0; GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, currentId); if (me->useCounter==0) GWEN_MemCacheEntry_free(me); } } currentId=nextId; } GWEN_MemCache_Unlock(mc); }
int GWEN_MemCache__MakeRoom(GWEN_MEMCACHE *mc, size_t neededSize) { assert(mc); /* release unused entries until there is enough memory */ while (neededSize) { GWEN_MEMCACHE_ENTRY *oldestEntry; GWEN_IDMAP_RESULT res; uint32_t currentId; /* get oldest entry */ oldestEntry=NULL; res=GWEN_MemCacheEntry_IdMap_GetFirst(mc->idMap, ¤tId); while (res==GWEN_IdMapResult_Ok) { GWEN_MEMCACHE_ENTRY *me; me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, currentId); if (me) { if (me->isValid && me->useCounter==0) { if (oldestEntry==NULL) oldestEntry=me; else { if (me->unusedSince<oldestEntry->unusedSince) oldestEntry=me; } } } res=GWEN_MemCacheEntry_IdMap_GetNext(mc->idMap, ¤tId); } if (oldestEntry==NULL) /* no unused entry found */ break; /* subtract size of to-be-removed entry from needed size */ if (neededSize<oldestEntry->dataLen) neededSize=0; else neededSize-=oldestEntry->dataLen; /* remove oldest entry (it is unused, so we also delete it here) */ GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, oldestEntry->id); GWEN_MemCacheEntry_free(oldestEntry); } return (neededSize==0)?0:GWEN_ERROR_MEMORY_FULL; }