⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ubi_cache.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ========================================================================== ** *                                 ubi_Cache.c * *  Copyright (C) 1997 by Christopher R. Hertel * *  Email: crh@ubiqx.mn.org * -------------------------------------------------------------------------- ** * *  This module implements a generic cache. * * -------------------------------------------------------------------------- ** * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public *  License along with this library; if not, write to the Free *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * -------------------------------------------------------------------------- ** * *  This module uses a splay tree to implement a simple cache.  The cache *  module adds a thin layer of functionality to the splay tree.  In *  particular: * *    - The tree (cache) may be limited in size by the number of *      entries permitted or the amount of memory used.  When either *      limit is exceeded cache entries are removed until the cache *      conforms. *    - Some statistical information is kept so that an approximate *      "hit ratio" can be calculated. *    - There are several functions available that provide access to *      and management of cache size limits, hit ratio, and tree *      trimming. * *  The splay tree is used because recently accessed items tend toward the *  top of the tree and less recently accessed items tend toward the bottom. *  This makes it easy to purge less recently used items should the cache *  exceed its limits. * *  To use this module, you will need to supply a comparison function of *  type ubi_trCompFunc and a node-freeing function of type *  ubi_trKillNodeRtn.  See ubi_BinTree.h for more information on *  these.  (This is all basic ubiqx tree management stuff.) * *  Notes: * *  - Cache performance will start to suffer dramatically if the *    cache becomes large enough to force the OS to start swapping *    memory to disk.  This is because the nodes of the underlying tree *    will be scattered across memory in an order that is completely *    unrelated to their traversal order.  As more and more of the *    cache is placed into swap space, more and more swaps will be *    required for a simple traversal (...and then there's the splay *    operation). * *    In one simple test under Linux, the load and dump of a cache of *    400,000 entries took only 1min, 40sec of real time.  The same *    test with 450,000 records took 2 *hours* and eight minutes. * *  - In an effort to save memory, I considered using an unsigned *    short to save the per-entry entry size.  I would have tucked this *    value into some unused space in the tree node structure.  On *    32-bit word aligned systems this would have saved an additional *    four bytes per entry.  I may revisit this issue, but for now I've *    decided against it. * *    Using an unsigned short would limit the size of an entry to 64K *    bytes.  That's probably more than enough for most applications. *    The key word in that last sentence, however, is "probably".  I *    really dislike imposing such limits on things. * *  - Each entry keeps track of the amount of memory it used and the *    cache header keeps the total.  This information is provided via *    the EntrySize parameter in ubi_cachePut(), so it is up to you to *    make sure that the numbers are accurate.  (The numbers don't even *    have to represent bytes used.) * *    As you consider this, note that the strdup() function--as an *    example--will call malloc().  The latter generally allocates a *    multiple of the system word size, which may be more than the *    number of bytes needed to store the string. * * -------------------------------------------------------------------------- ** * *  Log: ubi_Cache.c,v  *  Revision 0.4  1999/09/22 03:42:24  crh *  Fixed a minor typo. * *  Revision 0.3  1998/06/03 18:00:15  crh *  Further fiddling with sys_include.h, which is no longer explicitly *  included by this module since it is inherited from ubi_BinTree.h. * *  Revision 0.2  1998/06/02 01:36:18  crh *  Changed include name from ubi_null.h to sys_include.h to make it *  more generic. * *  Revision 0.1  1998/05/20 04:36:02  crh *  The C file now includes ubi_null.h.  See ubi_null.h for more info. * *  Revision 0.0  1997/12/18 06:24:33  crh *  Initial Revision. * * ========================================================================== ** */#include "ubi_Cache.h"    /* Header for *this* module. *//* -------------------------------------------------------------------------- ** * Static data... *//*  commented out until I make use of it...static char ModuleID[] = "ubi_Cache\n\\tRevision: 0.4 \n\\tDate: 1999/09/22 03:42:24 \n\\tAuthor: crh \n";*//* -------------------------------------------------------------------------- ** * Internal functions... */static void free_entry( ubi_cacheRootPtr CachePtr, ubi_cacheEntryPtr EntryPtr )  /* ------------------------------------------------------------------------ **   * Free a ubi_cacheEntry, and adjust the mem_used counter accordingly.   *   *  Input:  CachePtr  - A pointer to the cache from which the entry has   *                      been removed.   *          EntryPtr  - A pointer to the already removed entry.   *   *  Output: none.   *   *  Notes:  The entry must be removed from the cache *before* this function   *          is called!!!!   * ------------------------------------------------------------------------ **   */  {  CachePtr->mem_used -= EntryPtr->entry_size;  (*CachePtr->free_func)( (void *)EntryPtr );  } /* free_entry */static void cachetrim( ubi_cacheRootPtr crptr )  /* ------------------------------------------------------------------------ **   * Remove entries from the cache until the number of entries and the amount   * of memory used are *both* below or at the maximum.   *   *  Input:  crptr - pointer to the cache to be trimmed.   *   *  Output: None.   *   * ------------------------------------------------------------------------ **   */  {  while( ( crptr->max_entries && (crptr->max_entries < crptr->root.count) )      || ( crptr->max_memory  && (crptr->max_memory  < crptr->mem_used)   ) )    {    if( !ubi_cacheReduce( crptr, 1 ) )      return;    }  } /* cachetrim *//* -------------------------------------------------------------------------- ** * Exported functions... */ubi_cacheRootPtr ubi_cacheInit( ubi_cacheRootPtr  CachePtr,                                ubi_trCompFunc    CompFunc,                                ubi_trKillNodeRtn FreeFunc,                                unsigned long     MaxEntries,                                unsigned long     MaxMemory )  /* ------------------------------------------------------------------------ **   * Initialize a cache header structure.   *   *  Input:  CachePtr    - A pointer to a ubi_cacheRoot structure that is   *                        to be initialized.   *          CompFunc    - A pointer to the function that will be called   *                        to compare two cache values.  See the module   *                        comments, above, for more information.   *          FreeFunc    - A pointer to a function that will be called   *                        to free a cache entry.  If you allocated   *                        the cache entry using malloc(), then this   *                        will likely be free().  If you are allocating   *                        cache entries from a free list, then this will   *                        likely be a function that returns memory to the   *                        free list, etc.   *          MaxEntries  - The maximum number of entries that will be   *                        allowed to exist in the cache.  If this limit   *                        is exceeded, then existing entries will be   *                        removed from the cache.  A value of zero   *                        indicates that there is no limit on the number   *                        of cache entries.  See ubi_cachePut().   *          MaxMemory   - The maximum amount of memory, in bytes, to be   *                        allocated to the cache (excluding the cache   *                        header).  If this is exceeded, existing entries   *                        in the cache will be removed until enough memory   *                        has been freed to meet the condition.  See   *                        ubi_cachePut().   *   *  Output: A pointer to the initialized cache (i.e., the same as CachePtr).   *   *  Notes:  Both MaxEntries and MaxMemory may be changed after the cache   *          has been created.  See   *            ubi_cacheSetMaxEntries()    *            ubi_cacheSetMaxMemory()   *            ubi_cacheGetMaxEntries()   *            ubi_cacheGetMaxMemory()    (the latter two are macros).   *   *        - 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.  Keep this in mind when   *          choosing a value for MaxMemory.   *   * ------------------------------------------------------------------------ **   */  {  if( CachePtr )    {    (void)ubi_trInitTree( CachePtr, CompFunc, ubi_trOVERWRITE );    CachePtr->free_func   = FreeFunc;    CachePtr->max_entries = MaxEntries;    CachePtr->max_memory  = MaxMemory;    CachePtr->mem_used    = 0;    CachePtr->cache_hits  = 0;    CachePtr->cache_trys  = 0;    }  return( CachePtr );  } /* ubi_cacheInit */ubi_cacheRootPtr ubi_cacheClear( ubi_cacheRootPtr CachePtr )  /* ------------------------------------------------------------------------ **   * Remove and free all entries in an existing cache.   *   *  Input:  CachePtr  - A pointer to the cache that is to be cleared.   *   *  Output: A pointer to the cache header (i.e., the same as CachePtr).   *          This function re-initializes the cache header.   *   * ------------------------------------------------------------------------ **   */  {  if( CachePtr )    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -