📄 ubi_cache.c
字号:
(void)ubi_trKillTree( CachePtr, CachePtr->free_func ); CachePtr->mem_used = 0; CachePtr->cache_hits = 0; CachePtr->cache_trys = 0; } return( CachePtr ); } /* ubi_cacheClear */void ubi_cachePut( ubi_cacheRootPtr CachePtr, unsigned long EntrySize, ubi_cacheEntryPtr EntryPtr, ubi_trItemPtr Key ) /* ------------------------------------------------------------------------ ** * Add an entry to the cache. * * Input: CachePtr - A pointer to the cache into which the entry * will be added. * EntrySize - The size, in bytes, of the memory block indicated * by EntryPtr. This will be copied into the * EntryPtr->entry_size field. * EntryPtr - A pointer to a memory block that begins with a * ubi_cacheEntry structure. The entry structure * should be followed immediately by the data to be * cached (even if that is a pointer to yet more data). * Key - Pointer used to identify the lookup key within the * Entry. * * Output: None. * * Notes: After adding the new node, the cache is "trimmed". This * removes extra nodes if the tree has exceeded it's memory or * entry count limits. It is unlikely that the newly added node * will be purged from the cache (assuming a reasonably large * cache), since new nodes in a splay tree (which is what this * module was designed to use) are moved to the top of the tree * and the cache purge process removes nodes from the bottom of * the tree. * - The underlying splay tree is opened in OVERWRITE mode. If * the input key matches an existing key, the existing entry will * be politely removed from the tree and freed. * - Memory is allocated in multiples of the word size. The * return value of the strlen() function does not reflect * this; it will allways be less than or equal to the amount * of memory actually allocated. * * ------------------------------------------------------------------------ ** */ { ubi_trNodePtr OldNode; EntryPtr->entry_size = EntrySize; CachePtr->mem_used += EntrySize; (void)ubi_trInsert( CachePtr, EntryPtr, Key, &OldNode ); if( OldNode ) free_entry( CachePtr, (ubi_cacheEntryPtr)OldNode ); cachetrim( CachePtr ); } /* ubi_cachePut */ubi_cacheEntryPtr ubi_cacheGet( ubi_cacheRootPtr CachePtr, ubi_trItemPtr FindMe ) /* ------------------------------------------------------------------------ ** * Attempt to retrieve an entry from the cache. * * Input: CachePtr - A ponter to the cache that is to be searched. * FindMe - A ubi_trItemPtr that indicates the key for which * to search. * * Output: A pointer to the cache entry that was found, or NULL if no * matching entry was found. * * Notes: This function also updates the hit ratio counters. * The counters are unsigned short. If the number of cache tries * reaches 32768, then both the number of tries and the number of * hits are divided by two. This prevents the counters from * overflowing. See the comments in ubi_cacheHitRatio() for * additional notes. * * ------------------------------------------------------------------------ ** */ { ubi_trNodePtr FoundPtr; FoundPtr = ubi_trFind( CachePtr, FindMe ); if( FoundPtr ) CachePtr->cache_hits++; CachePtr->cache_trys++; if( CachePtr->cache_trys & 0x8000 ) { CachePtr->cache_hits = CachePtr->cache_hits / 2; CachePtr->cache_trys = CachePtr->cache_trys / 2; } return( (ubi_cacheEntryPtr)FoundPtr ); } /* ubi_cacheGet */ubi_trBool ubi_cacheDelete( ubi_cacheRootPtr CachePtr, ubi_trItemPtr DeleteMe ) /* ------------------------------------------------------------------------ ** * Find and delete the specified cache entry. * * Input: CachePtr - A pointer to the cache. * DeleteMe - The key of the entry to be deleted. * * Output: TRUE if the entry was found & freed, else FALSE. * * ------------------------------------------------------------------------ ** */ { ubi_trNodePtr FoundPtr; FoundPtr = ubi_trFind( CachePtr, DeleteMe ); if( FoundPtr ) { (void)ubi_trRemove( CachePtr, FoundPtr ); free_entry( CachePtr, (ubi_cacheEntryPtr)FoundPtr ); return( ubi_trTRUE ); } return( ubi_trFALSE ); } /* ubi_cacheDelete */ubi_trBool ubi_cacheReduce( ubi_cacheRootPtr CachePtr, unsigned long count ) /* ------------------------------------------------------------------------ ** * Remove <count> entries from the bottom of the cache. * * Input: CachePtr - A pointer to the cache which is to be reduced in * size. * count - The number of entries to remove. * * Output: The function will return TRUE if <count> entries were removed, * else FALSE. A return value of FALSE should indicate that * there were less than <count> entries in the cache, and that the * cache is now empty. * * Notes: This function forces a reduction in the number of cache entries * without requiring that the MaxMemory or MaxEntries values be * changed. * * ------------------------------------------------------------------------ ** */ { ubi_trNodePtr NodePtr; while( count ) { NodePtr = ubi_trLeafNode( CachePtr->root.root ); if( NULL == NodePtr ) return( ubi_trFALSE ); else { (void)ubi_trRemove( CachePtr, NodePtr ); free_entry( CachePtr, (ubi_cacheEntryPtr)NodePtr ); } count--; } return( ubi_trTRUE ); } /* ubi_cacheReduce */unsigned long ubi_cacheSetMaxEntries( ubi_cacheRootPtr CachePtr, unsigned long NewSize ) /* ------------------------------------------------------------------------ ** * Change the maximum number of entries allowed to exist in the cache. * * Input: CachePtr - A pointer to the cache to be modified. * NewSize - The new maximum number of cache entries. * * Output: The maximum number of entries previously allowed to exist in * the cache. * * Notes: If the new size is less than the old size, this function will * trim the cache (remove excess entries). * - A value of zero indicates an unlimited number of entries. * * ------------------------------------------------------------------------ ** */ { unsigned long oldsize = CachePtr->max_entries; /* Save the old value. */ CachePtr->max_entries = NewSize; /* Apply the new value. */ if( (NewSize < oldsize) || (NewSize && !oldsize) ) /* If size is smaller, */ cachetrim( CachePtr ); /* remove excess. */ return( oldsize ); } /* ubi_cacheSetMaxEntries */unsigned long ubi_cacheSetMaxMemory( ubi_cacheRootPtr CachePtr, unsigned long NewSize ) /* ------------------------------------------------------------------------ ** * Change the maximum amount of memory to be used for storing cache * entries. * * Input: CachePtr - A pointer to the cache to be modified. * NewSize - The new cache memory size. * * Output: The previous maximum memory size. * * Notes: If the new size is less than the old size, this function will * trim the cache (remove excess entries). * - A value of zero indicates that the cache has no memory limit. * * ------------------------------------------------------------------------ ** */ { unsigned long oldsize = CachePtr->max_memory; /* Save the old value. */ CachePtr->max_memory = NewSize; /* Apply the new value. */ if( (NewSize < oldsize) || (NewSize && !oldsize) ) /* If size is smaller, */ cachetrim( CachePtr ); /* remove excess. */ return( oldsize ); } /* ubi_cacheSetMaxMemory */int ubi_cacheHitRatio( ubi_cacheRootPtr CachePtr ) /* ------------------------------------------------------------------------ ** * Returns a value that is 10,000 times the slightly weighted average hit * ratio for the cache. * * Input: CachePtr - Pointer to the cache to be queried. * * Output: An integer that is 10,000 times the number of successful * cache hits divided by the number of cache lookups, or: * (10000 * hits) / trys * You can easily convert this to a float, or do something * like this (where i is the return value of this function): * * printf( "Hit rate : %d.%02d%%\n", (i/100), (i%100) ); * * Notes: I say "slightly-weighted", because the numerator and * denominator are both accumulated in locations of type * 'unsigned short'. If the number of cache trys becomes * large enough, both are divided by two. (See function * ubi_cacheGet().) * Dividing both numerator and denominator by two does not * change the ratio (much...it is an integer divide), but it * does mean that subsequent increments to either counter will * have twice as much significance as previous ones. * * - The value returned by this function will be in the range * [0..10000] because ( 0 <= cache_hits <= cache_trys ) will * always be true. * * ------------------------------------------------------------------------ ** */ { int tmp = 0; if( CachePtr->cache_trys ) tmp = (int)( (10000 * (long)(CachePtr->cache_hits) ) / (long)(CachePtr->cache_trys) ); return( tmp ); } /* ubi_cacheHitRatio *//* -------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -