]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/store_dir.cc
3 * $Id: store_dir.cc,v 1.90 1999/05/04 19:14:27 wessels Exp $
4 * $Id: store_dir.cc,v 1.90 1999/05/04 19:14:27 wessels Exp $
6 * DEBUG: section 47 Store Directory Routines
7 * AUTHOR: Duane Wessels
9 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
10 * ----------------------------------------------------------
12 * Squid is the result of efforts by numerous individuals from the
13 * Internet community. Development is led by Duane Wessels of the
14 * National Laboratory for Applied Network Research and funded by the
15 * National Science Foundation. Squid is Copyrighted (C) 1998 by
16 * Duane Wessels and the University of California San Diego. Please
17 * see the COPYRIGHT file for full details. Squid incorporates
18 * software developed and/or copyrighted by other sources. Please see
19 * the CREDITS file for full details.
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
46 storeSwapFullPath(sfileno f
, char *buf
)
48 return storeUfsFullPath(f
, buf
);
52 storeCreateSwapDirectories(void)
54 storeUfsCreateSwapDirectories();
58 *Spread load across least 3/4 of the store directories
61 storeDirSelectSwapDir(void)
63 double least_used
= 1.0;
64 double high
= (double) Config
.Swap
.highWaterMark
/ 100.0;
69 static int nleast
= 0;
71 static int *dirq
= NULL
;
72 static double *diru
= NULL
;
74 * Handle simplest case of a single swap directory immediately
76 if (Config
.cacheSwap
.n_configured
== 1)
79 * Initialise dirq on the first call or on change of number of dirs
81 if (nconf
!= Config
.cacheSwap
.n_configured
) {
82 nconf
= Config
.cacheSwap
.n_configured
;
83 nleast
= (nconf
* 3) / 4;
85 dirq
= (int *) xmalloc(sizeof(int) * nleast
);
87 diru
= (double *) xmalloc(sizeof(double) * nconf
);
88 for (j
= 0; j
< nleast
; j
++)
92 * Scan for a non-negative dirn in the dirq array and return that one
95 for (j
= 0; j
< nleast
; j
++) {
103 * If we found a valid dirn return it
108 * Now for the real guts of the algorithm - building the dirq array
110 for (i
= 0; i
< nconf
; i
++) {
112 SD
= &Config
.cacheSwap
.swapDirs
[i
];
113 SD
->flags
.selected
= 0;
114 if (SD
->flags
.read_only
)
116 u
= (double) SD
->cur_size
/ SD
->max_size
;
121 for (j
= 0; j
< nleast
; j
++) {
125 for (i
= 0; i
< nconf
; i
++) {
126 if (diru
[i
] < least_used
) {
127 least_used
= diru
[i
];
135 /* set selected flag for debugging/cachemgr only */
136 Config
.cacheSwap
.swapDirs
[dirn
].flags
.selected
= 1;
139 * Setup default return of 0 if no least found
149 storeDirValidFileno(int fn
)
151 int dirn
= fn
>> SWAP_DIR_SHIFT
;
152 int filn
= fn
& SWAP_FILE_MASK
;
153 if (dirn
> Config
.cacheSwap
.n_configured
)
159 if (filn
> Config
.cacheSwap
.swapDirs
[dirn
].map
->max_n_files
)
165 storeDirMapBitTest(int fn
)
167 int dirn
= fn
>> SWAP_DIR_SHIFT
;
168 int filn
= fn
& SWAP_FILE_MASK
;
169 return file_map_bit_test(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
173 storeDirMapBitSet(int fn
)
175 int dirn
= fn
>> SWAP_DIR_SHIFT
;
176 int filn
= fn
& SWAP_FILE_MASK
;
177 file_map_bit_set(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
181 storeDirMapBitReset(int fn
)
183 int dirn
= fn
>> SWAP_DIR_SHIFT
;
184 int filn
= fn
& SWAP_FILE_MASK
;
185 file_map_bit_reset(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
189 storeDirMapAllocate(void)
191 int dirn
= storeDirSelectSwapDir();
192 SwapDir
*SD
= &Config
.cacheSwap
.swapDirs
[dirn
];
193 int filn
= file_map_allocate(SD
->map
, SD
->suggest
);
194 SD
->suggest
= filn
+ 1;
195 return (dirn
<< SWAP_DIR_SHIFT
) | (filn
& SWAP_FILE_MASK
);
199 storeSwapDir(int dirn
)
201 assert(0 <= dirn
&& dirn
< Config
.cacheSwap
.n_configured
);
202 return Config
.cacheSwap
.swapDirs
[dirn
].path
;
206 storeDirNumber(int swap_file_number
)
208 return swap_file_number
>> SWAP_DIR_SHIFT
;
212 storeDirProperFileno(int dirn
, int fn
)
214 return (dirn
<< SWAP_DIR_SHIFT
) | (fn
& SWAP_FILE_MASK
);
218 * An entry written to the swap log MUST have the following
220 * 1. It MUST be a public key. It does no good to log
221 * a public ADD, change the key, then log a private
222 * DEL. So we need to log a DEL before we change a
223 * key from public to private.
224 * 2. It MUST have a valid (> -1) swap_file_number.
227 storeDirSwapLog(const StoreEntry
* e
, int op
)
229 int dirn
= e
->swap_file_number
>> SWAP_DIR_SHIFT
;
230 assert(dirn
< Config
.cacheSwap
.n_configured
);
231 assert(!EBIT_TEST(e
->flags
, KEY_PRIVATE
));
232 assert(e
->swap_file_number
>= 0);
234 * icons and such; don't write them to the swap log
236 if (EBIT_TEST(e
->flags
, ENTRY_SPECIAL
))
238 assert(op
> SWAP_LOG_NOP
&& op
< SWAP_LOG_MAX
);
239 debug(20, 3) ("storeDirSwapLog: %s %s %08X\n",
241 storeKeyText(e
->key
),
242 e
->swap_file_number
);
243 storeUfsDirSwapLog(e
, op
);
247 storeDirSwapLogFile(int dirn
, const char *ext
)
249 return storeUfsDirSwapLogFile(dirn
, ext
);
253 storeDirUpdateSwapSize(int fn
, size_t size
, int sign
)
255 int dirn
= (fn
>> SWAP_DIR_SHIFT
) % Config
.cacheSwap
.n_configured
;
256 int k
= ((size
+ 1023) >> 10) * sign
;
257 Config
.cacheSwap
.swapDirs
[dirn
].cur_size
+= k
;
258 store_swap_size
+= k
;
266 storeDirStats(StoreEntry
* sentry
)
268 storeAppendPrintf(sentry
, "Store Directory Statistics:\n");
269 storeAppendPrintf(sentry
, "Store Entries : %d\n",
270 memInUse(MEM_STOREENTRY
));
271 storeAppendPrintf(sentry
, "Maximum Swap Size : %8d KB\n",
272 Config
.Swap
.maxSize
);
273 storeAppendPrintf(sentry
, "Current Store Swap Size: %8d KB\n",
275 storeAppendPrintf(sentry
, "Current Capacity : %d%% used, %d%% free\n",
276 percent((int) store_swap_size
, (int) Config
.Swap
.maxSize
),
277 percent((int) (Config
.Swap
.maxSize
- store_swap_size
), (int) Config
.Swap
.maxSize
));
278 storeUfsDirStats(sentry
);
282 storeDirMapBitsInUse(void)
286 for (i
= 0; i
< Config
.cacheSwap
.n_configured
; i
++)
287 n
+= Config
.cacheSwap
.swapDirs
[i
].map
->n_files_in_map
;
292 * storeDirWriteCleanLogs
294 * Writes a "clean" swap log file from in-memory metadata.
297 storeDirWriteCleanLogs(int reopen
)
299 return storeUfsDirWriteCleanLogs(reopen
);
303 storeDirConfigure(void)
309 Config
.Swap
.maxSize
= 0;
310 for (i
= 0; i
< Config
.cacheSwap
.n_configured
; i
++) {
311 SD
= &Config
.cacheSwap
.swapDirs
[i
];;
312 Config
.Swap
.maxSize
+= SD
->max_size
;
313 n
= 2 * SD
->max_size
/ Config
.Store
.avgObjectSize
;
314 if (NULL
== SD
->map
) {
316 SD
->map
= file_map_create(n
);
317 } else if (n
> SD
->map
->max_n_files
) {
318 /* it grew, need to expand */
319 fm
= file_map_create(n
);
320 filemapCopy(SD
->map
, fm
);
321 filemapFreeMemory(SD
->map
);
324 /* else it shrunk, and we leave the old one in place */
329 storeDirDiskFull(int fn
)
331 int dirn
= fn
>> SWAP_DIR_SHIFT
;
332 SwapDir
*SD
= &Config
.cacheSwap
.swapDirs
[dirn
];
333 assert(0 <= dirn
&& dirn
< Config
.cacheSwap
.n_configured
);
334 SD
->max_size
= SD
->cur_size
;
335 debug(20, 1) ("WARNING: Shrinking cache_dir #%d to %d KB\n",
340 storeDirOpenSwapLogs(void)
342 return storeUfsDirOpenSwapLogs();
346 storeDirCloseSwapLogs(void)
348 return storeUfsDirCloseSwapLogs();
352 storeDirCloseTmpSwapLog(int dirn
)
354 return storeUfsDirCloseTmpSwapLog(dirn
);