raze/source/common/filesystem/cache.cpp
2019-10-31 20:17:49 +01:00

125 lines
2.2 KiB
C++

CACHENODE Resource::purgeHead = { NULL, &purgeHead, &purgeHead, 0 };
void *Resource::Lock(DICTNODE *h)
{
dassert(h != NULL);
if (h->ptr)
{
if (h->lockCount == 0)
{
RemoveMRU(h);
}
}
else
{
h->ptr = Alloc(h->size);
Read(h);
}
h->lockCount++;
return h->ptr;
}
void Resource::Unlock(DICTNODE *h)
{
dassert(h != NULL);
dassert(h->ptr != NULL);
if (h->lockCount > 0)
{
h->lockCount--;
if (h->lockCount == 0)
{
h->prev = purgeHead.prev;
purgeHead.prev->next = h;
h->next = &purgeHead;
purgeHead.prev = h;
}
}
}
void Resource::Flush(CACHENODE *h)
{
if (h->ptr)
{
#ifdef USE_QHEAP
heap->Free(h->ptr);
#else
delete[] (char*)h->ptr;
#endif
h->ptr = NULL;
if (h->lockCount == 0)
{
RemoveMRU(h);
return;
}
h->lockCount = 0;
}
}
void Resource::Purge(void)
{
for (unsigned int i = 0; i < count; i++)
{
if (dict[i].ptr)
{
Flush((CACHENODE *)&dict[i]);
}
}
}
void Resource::PurgeCache(void)
{
#ifndef USE_QHEAP
for (CACHENODE *node = purgeHead.next; node != &purgeHead; node = node->next)
{
DICTNODE *pDict = (DICTNODE*)node;
if (!(pDict->flags & DICT_LOAD))
{
dassert(pDict->lockCount == 0);
dassert(pDict->ptr != NULL);
Free(pDict->ptr);
pDict->ptr = NULL;
RemoveMRU(pDict);
}
}
#endif
}
void *Resource::Load(DICTNODE *h)
{
dassert(h != NULL);
if (h->ptr)
{
if (!h->lockCount)
{
RemoveMRU(h);
h->prev = purgeHead.prev;
purgeHead.prev->next = h;
h->next = &purgeHead;
purgeHead.prev = h;
}
}
else
{
h->ptr = Alloc(h->size);
Read(h);
h->prev = purgeHead.prev;
purgeHead.prev->next = h;
h->next = &purgeHead;
purgeHead.prev = h;
}
return h->ptr;
}
void Resource::RemoveMRU(CACHENODE *h)
{
h->prev->next = h->next;
h->next->prev = h->prev;
}