filemap.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:5k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: filemap.c,v 1.31 1998/07/22 20:37:19 wessels Exp $
  3.  *
  4.  * DEBUG: section 8     Swap File Bitmap
  5.  * AUTHOR: Harvest Derived
  6.  *
  7.  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
  8.  * ----------------------------------------------------------
  9.  *
  10.  *  Squid is the result of efforts by numerous individuals from the
  11.  *  Internet community.  Development is led by Duane Wessels of the
  12.  *  National Laboratory for Applied Network Research and funded by the
  13.  *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
  14.  *  Duane Wessels and the University of California San Diego.  Please
  15.  *  see the COPYRIGHT file for full details.  Squid incorporates
  16.  *  software developed and/or copyrighted by other sources.  Please see
  17.  *  the CREDITS file for full details.
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *  
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *  
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32.  *
  33.  */
  34. #include "squid.h"
  35. /* Number of bits in a long */
  36. #if SIZEOF_LONG == 8
  37. #define LONG_BIT_SHIFT 6
  38. #define BITS_IN_A_LONG 0x40
  39. #define LONG_BIT_MASK  0x3F
  40. #define ALL_ONES (unsigned long) 0xFFFFFFFFFFFFFFFF
  41. #elif SIZEOF_LONG == 4
  42. #define LONG_BIT_SHIFT 5
  43. #define BITS_IN_A_LONG 0x20
  44. #define LONG_BIT_MASK  0x1F
  45. #define ALL_ONES (unsigned long) 0xFFFFFFFF
  46. #else
  47. #define LONG_BIT_SHIFT 5
  48. #define BITS_IN_A_LONG 0x20
  49. #define LONG_BIT_MASK  0x1F
  50. #define ALL_ONES (unsigned long) 0xFFFFFFFF
  51. #endif
  52. fileMap *
  53. file_map_create(int n)
  54. {
  55.     fileMap *fm = xcalloc(1, sizeof(fileMap));
  56.     fm->max_n_files = n;
  57.     fm->nwords = n >> LONG_BIT_SHIFT;
  58.     debug(8, 3) ("file_map_create: creating space for %d filesn", n);
  59.     debug(8, 5) ("--> %d words of %d bytes eachn",
  60. fm->nwords, sizeof(unsigned long));
  61.     fm->file_map = xcalloc(fm->nwords, sizeof(unsigned long));
  62.     /* XXX account fm->file_map */
  63.     return fm;
  64. }
  65. int
  66. file_map_bit_set(fileMap * fm, int file_number)
  67. {
  68.     unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  69.     fm->file_map[file_number >> LONG_BIT_SHIFT] |= bitmask;
  70.     fm->n_files_in_map++;
  71.     if (!fm->toggle && (fm->n_files_in_map > ((fm->max_n_files * 7) >> 3))) {
  72. fm->toggle++;
  73. debug(8, 0) ("WARNING: filemap utilization at %d%%n"
  74.     "tConsider decreasing store_avg_object_size in squid.confn",
  75.     percent(fm->n_files_in_map, fm->max_n_files));
  76.     } else if (fm->n_files_in_map == fm->max_n_files) {
  77. fatal_dump("You've run out of swap file numbers.");
  78.     }
  79.     return (file_number);
  80. }
  81. void
  82. file_map_bit_reset(fileMap * fm, int file_number)
  83. {
  84.     unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  85.     fm->file_map[file_number >> LONG_BIT_SHIFT] &= ~bitmask;
  86.     fm->n_files_in_map--;
  87. }
  88. int
  89. file_map_bit_test(fileMap * fm, int file_number)
  90. {
  91.     unsigned long bitmask = (1L << (file_number & LONG_BIT_MASK));
  92.     /* be sure the return value is an int, not a u_long */
  93.     return (fm->file_map[file_number >> LONG_BIT_SHIFT] & bitmask ? 1 : 0);
  94. }
  95. int
  96. file_map_allocate(fileMap * fm, int suggestion)
  97. {
  98.     int word;
  99.     int bit;
  100.     int count;
  101.     if (suggestion > fm->max_n_files)
  102. suggestion = 0;
  103.     if (!file_map_bit_test(fm, suggestion)) {
  104. return file_map_bit_set(fm, suggestion);
  105.     }
  106.     word = suggestion >> LONG_BIT_SHIFT;
  107.     for (count = 0; count < fm->nwords; count++) {
  108. if (fm->file_map[word] != ALL_ONES)
  109.     break;
  110. word = (word + 1) % fm->nwords;
  111.     }
  112.     for (bit = 0; bit < BITS_IN_A_LONG; bit++) {
  113. suggestion = ((unsigned long) word << LONG_BIT_SHIFT) | bit;
  114. if (!file_map_bit_test(fm, suggestion)) {
  115.     return file_map_bit_set(fm, suggestion);
  116. }
  117.     }
  118.     fatal("file_map_allocate: Exceeded filemap limit");
  119.     return 0; /* NOTREACHED */
  120. }
  121. void
  122. filemapFreeMemory(fileMap * fm)
  123. {
  124.     safe_free(fm->file_map);
  125.     safe_free(fm);
  126. }
  127. void
  128. filemapCopy(fileMap * old, fileMap * new)
  129. {
  130.     assert(old->max_n_files <= new->max_n_files);
  131.     assert(0 == new->n_files_in_map);
  132.     xmemcpy(new->file_map, old->file_map, old->nwords * sizeof(unsigned long));
  133.     new->n_files_in_map = old->n_files_in_map;
  134. }
  135. #ifdef TEST
  136. #define TEST_SIZE 1<<16
  137. main(argc, argv)
  138. {
  139.     int i;
  140.     fm = file_map_create(TEST_SIZE);
  141.     for (i = 0; i < TEST_SIZE; ++i) {
  142. file_map_bit_set(i);
  143. assert(file_map_bit_test(i));
  144. file_map_bit_reset(i);
  145.     }
  146. }
  147. #endif