diff options
Diffstat (limited to 'app/xfs/difs/cache.c')
-rw-r--r-- | app/xfs/difs/cache.c | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/app/xfs/difs/cache.c b/app/xfs/difs/cache.c deleted file mode 100644 index 06fca6c35..000000000 --- a/app/xfs/difs/cache.c +++ /dev/null @@ -1,382 +0,0 @@ -/* -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - * Copyright 1990, 1991 Network Computing Devices; - * Portions Copyright 1987 by Digital Equipment Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the names of Network Computing Devices, - * or Digital not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Network Computing Devices, or Digital - * make no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE - * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "config.h" - -#include "cachestr.h" -#include "misc.h" - -#define INITBUCKETS 64 -#define INITHASHSIZE 6 -#define MAXHASHSIZE 11 - - -#define ENTRYOFFSET 22 -#define CACHE_ENTRY_MASK 0x3FFFFF -#define CACHE_ENTRY_BITS(id) ((id) & 0x1fc00000) -#define CACHE_ID(id) ((int)(CACHE_ENTRY_BITS(id) >> ENTRYOFFSET)) - -#define NullCacheEntry ((CacheEntryPtr) 0) - -#define MAX_NUM_CACHES 32 -/* XXX make this dynamic? */ -static CachePtr caches[MAX_NUM_CACHES]; -static int num_caches = 1; - -/*- - * Notes on cache implementation - * - * This is basically the X11 resource code, with some modifications - * to handle aging. - * - * Its currently optimized for lookup & store. Flushing old stuff - * is a lot slower than it should probably be, but there's tradeoffs - * in tuning. - */ - -Cache -CacheInit(unsigned long maxsize) -{ - Cache id = (Cache) num_caches; - CachePtr cache; - - cache = (CachePtr) fsalloc(sizeof(CacheRec)); - if (!cache) - return (Cache) 0; - cache->entries = (CacheEntryPtr *) - fsalloc(INITBUCKETS * sizeof(CacheEntryPtr)); - bzero((char *) cache->entries, (INITBUCKETS * sizeof(CacheEntryPtr))); - if (!cache->entries) { - fsfree(cache); - return (Cache) 0; - } - caches[id] = cache; - cache->elements = 0; - cache->buckets = INITBUCKETS; - cache->hashsize = INITHASHSIZE; - cache->maxsize = maxsize; - cache->cursize = 0; - cache->nextid = id << ENTRYOFFSET; - cache->id = id; - num_caches++; - return id; -} - -static int -hash(CacheID cid) -{ - CachePtr cache = caches[CACHE_ID(cid)]; - - switch (cache->hashsize) { -#ifdef DEBUG /* only need this if INITHASHSIZE < 6 */ - case 2: - return ((int) (0x03 & (cid ^ (cid >> 2) ^ (cid >> 8)))); - case 3: - return ((int) (0x07 & (cid ^ (cid >> 3) ^ (cid >> 9)))); - case 4: - return ((int) (0x0F & (cid ^ (cid >> 4) ^ (cid >> 10)))); - case 5: - return ((int) (0x01F & (cid ^ (cid >> 5) ^ (cid >> 11)))); -#endif - case 6: - return ((int) (0x03F & (cid ^ (cid >> 6) ^ (cid >> 12)))); - case 7: - return ((int) (0x07F & (cid ^ (cid >> 7) ^ (cid >> 13)))); - case 8: - return ((int) (0x0FF & (cid ^ (cid >> 8) ^ (cid >> 16)))); - case 9: - return ((int) (0x1FF & (cid ^ (cid >> 9)))); - case 10: - return ((int) (0x3FF & (cid ^ (cid >> 10)))); - case 11: - return ((int) (0x7FF & (cid ^ (cid >> 11)))); - } - return -1; -} - -static void -rebuild_cache(CachePtr cache) -{ - int j; - CacheEntryPtr cp, - next, - **tails, - *entries, - **tptr, - *cptr; - - assert(cache); - j = 2 * cache->buckets; - tails = (CacheEntryPtr **) ALLOCATE_LOCAL(j * sizeof(CacheEntryPtr *)); - if (!tails) - return; - entries = (CacheEntryPtr *) fsalloc(j * sizeof(CacheEntryPtr)); - if (!entries) { - DEALLOCATE_LOCAL(tails); - return; - } - for (cptr = entries, tptr = tails; --j >= 0; cptr++, tptr++) { - *cptr = NullCacheEntry; - *tptr = cptr; - } - cache->hashsize++; - for (j = cache->buckets, cptr = cache->entries; --j >= 0; cptr++) { - for (cp = *cptr; cp; cp = next) { - next = cp->next; - cp->next = NullCacheEntry; - tptr = &tails[hash(cp->id)]; - **tptr = cp; - *tptr = &cp->next; - } - } - DEALLOCATE_LOCAL(tails); - cache->buckets *= 2; - fsfree(cache->entries); - cache->entries = entries; -} - -/* - * throws out all existing entries - */ -void -CacheReset(void) -{ - CacheEntryPtr cp; - CachePtr cache; - int i, - j; - - for (j = 0; j < num_caches; j++) { - cache = caches[j]; - if (!cache) - continue; - for (i = 0; i < cache->buckets; i++) { - for (cp = cache->entries[i]; cp; cp = cp->next) { - cache->elements--; - cache->cursize -= cp->size; - (*cp->free_func) (cp->id, cp->data, CacheWasReset); - fsfree(cp); - } - cache->entries[i] = (CacheEntryPtr) 0; - } - assert(cache->cursize == 0); - } -} - -static void -flush_cache(CachePtr cache, unsigned long needed) -{ -/* XXX -- try to set oldprev properly inside search loop */ - CacheEntryPtr cp, - oldest, - *oldprev; - int oldbucket = -1, - i; - - while ((cache->cursize + needed) > cache->maxsize) { - oldest = (CacheEntryPtr) 0; - /* find oldest */ - for (i = 0; i < cache->buckets; i++) { - cp = cache->entries[i]; - if (!cp) - continue; - if (!oldest) { - oldbucket = i; - oldest = cp; - } - while (cp) { - if (cp->timestamp < oldest->timestamp) { - oldest = cp; - oldbucket = i; - } - cp = cp->next; - } - } - /* fixup list */ - oldprev = &cache->entries[oldbucket]; - cp = *oldprev; - for (; (cp = *oldprev) != NULL; oldprev = &cp->next) { - if (cp == oldest) { - *oldprev = oldest->next; - break; - } - } - /* clobber it */ - cache->elements--; - cache->cursize -= oldest->size; - (*oldest->free_func) (oldest->id, oldest->data, CacheEntryOld); - fsfree(oldest); - } -} - -void -CacheResize(Cache cid, unsigned newsize) -{ - CachePtr cache = caches[cid]; - - if (!cache) - return; - - if (newsize < cache->maxsize) { - /* have to toss some stuff */ - flush_cache(cache, cache->maxsize - newsize); - } - cache->maxsize = newsize; -} - -CacheID -CacheStoreMemory( - Cache cid, - pointer data, - unsigned long size, - CacheFree free_func) -{ - CacheID id; - CacheEntryPtr cp, - *head; - CachePtr cache = caches[cid]; - - if (size > cache->maxsize) /* beyond cache limits */ - return (CacheID) 0; - - if ((cache->elements >= 4 * cache->buckets) && - (cache->hashsize < MAXHASHSIZE)) { - rebuild_cache(cache); - } - id = cache->nextid++; - - if ((cache->cursize + size) > cache->maxsize) { - flush_cache(cache, size); - } - head = &cache->entries[hash(id)]; - cp = (CacheEntryPtr) fsalloc(sizeof(CacheEntryRec)); - if (!cp) { - return (CacheID) 0; - } - cp->next = *head; - cp->id = id; - cp->timestamp = GetTimeInMillis(); - cp->free_func = free_func; - cp->size = size; - cp->data = data; - cache->cursize += size; - cache->elements++; - *head = cp; - - return id; -} - -pointer -CacheFetchMemory( - CacheID cid, - Bool update) -{ - CachePtr cache = caches[CACHE_ID(cid)]; - CacheEntryPtr cp, - *head; - - head = &cache->entries[hash(cid)]; - for (cp = *head; cp; cp = cp->next) { - if (cp->id == cid) { - if (update) { - cp->timestamp = GetTimeInMillis(); - if (cp != *head) { /* put it in the front */ - cp->next = *head; - *head = cp; - } - } - return cp->data; - } - } - return (pointer) 0; -} - -void -CacheFreeMemory( - CacheID cid, - Bool notify) -{ - CachePtr cache = caches[CACHE_ID(cid)]; - CacheEntryPtr cp, - *prev, - *head; - int *elptr; - int elements; - Bool found = FALSE; - - head = &cache->entries[hash(cid)]; - elptr = &cache->elements; - prev = head; - while ((cp = *prev) != NullCacheEntry) { - if (cp->id == cid) { - *prev = cp->next; - elements = --*elptr; - if (notify) { - (*(cp->free_func)) (cid, cp->data, CacheEntryFreed); - } - cache->cursize -= cp->size; - fsfree(cp); - if (*elptr != elements) - prev = head; - found = TRUE; - } else { - prev = &cp->next; - } - } - if (!found) - FatalError("freeing cache entry %ld which isn't there\n", cid); -} - -/* ARGSUSED */ -void -CacheSimpleFree( - CacheID cid, - pointer data, - int reason) -{ - fsfree(data); -} |