]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/store_dir.cc
3 * $Id: store_dir.cc,v 1.92 1999/05/22 07:42:11 wessels Exp $
5 * DEBUG: section 47 Store Directory Routines
6 * AUTHOR: Duane Wessels
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 const char *SwapDirType
[] =
51 storeSwapFullPath(sfileno f
, char *buf
)
53 return storeUfsFullPath(f
, buf
);
57 storeCreateSwapDirectories(void)
59 storeUfsCreateSwapDirectories();
63 *Spread load across least 3/4 of the store directories
66 storeDirSelectSwapDir(void)
68 double least_used
= 1.0;
69 double high
= (double) Config
.Swap
.highWaterMark
/ 100.0;
74 static int nleast
= 0;
76 static int *dirq
= NULL
;
77 static double *diru
= NULL
;
79 * Handle simplest case of a single swap directory immediately
81 if (Config
.cacheSwap
.n_configured
== 1)
84 * Initialise dirq on the first call or on change of number of dirs
86 if (nconf
!= Config
.cacheSwap
.n_configured
) {
87 nconf
= Config
.cacheSwap
.n_configured
;
88 nleast
= (nconf
* 3) / 4;
90 dirq
= (int *) xmalloc(sizeof(int) * nleast
);
92 diru
= (double *) xmalloc(sizeof(double) * nconf
);
93 for (j
= 0; j
< nleast
; j
++)
97 * Scan for a non-negative dirn in the dirq array and return that one
100 for (j
= 0; j
< nleast
; j
++) {
108 * If we found a valid dirn return it
113 * Now for the real guts of the algorithm - building the dirq array
115 for (i
= 0; i
< nconf
; i
++) {
117 SD
= &Config
.cacheSwap
.swapDirs
[i
];
118 SD
->flags
.selected
= 0;
119 if (SD
->flags
.read_only
)
121 u
= (double) SD
->cur_size
/ SD
->max_size
;
126 for (j
= 0; j
< nleast
; j
++) {
130 for (i
= 0; i
< nconf
; i
++) {
131 if (diru
[i
] < least_used
) {
132 least_used
= diru
[i
];
140 /* set selected flag for debugging/cachemgr only */
141 Config
.cacheSwap
.swapDirs
[dirn
].flags
.selected
= 1;
144 * Setup default return of 0 if no least found
154 storeDirValidFileno(int fn
)
156 int dirn
= fn
>> SWAP_DIR_SHIFT
;
157 int filn
= fn
& SWAP_FILE_MASK
;
158 if (dirn
> Config
.cacheSwap
.n_configured
)
164 if (filn
> Config
.cacheSwap
.swapDirs
[dirn
].map
->max_n_files
)
170 storeDirMapBitTest(int fn
)
172 int dirn
= fn
>> SWAP_DIR_SHIFT
;
173 int filn
= fn
& SWAP_FILE_MASK
;
174 return file_map_bit_test(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
178 storeDirMapBitSet(int fn
)
180 int dirn
= fn
>> SWAP_DIR_SHIFT
;
181 int filn
= fn
& SWAP_FILE_MASK
;
182 file_map_bit_set(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
186 storeDirMapBitReset(int fn
)
188 int dirn
= fn
>> SWAP_DIR_SHIFT
;
189 int filn
= fn
& SWAP_FILE_MASK
;
190 file_map_bit_reset(Config
.cacheSwap
.swapDirs
[dirn
].map
, filn
);
194 storeDirMapAllocate(void)
196 int dirn
= storeDirSelectSwapDir();
197 SwapDir
*SD
= &Config
.cacheSwap
.swapDirs
[dirn
];
198 int filn
= file_map_allocate(SD
->map
, SD
->suggest
);
199 SD
->suggest
= filn
+ 1;
200 return (dirn
<< SWAP_DIR_SHIFT
) | (filn
& SWAP_FILE_MASK
);
204 storeSwapDir(int dirn
)
206 assert(0 <= dirn
&& dirn
< Config
.cacheSwap
.n_configured
);
207 return Config
.cacheSwap
.swapDirs
[dirn
].path
;
211 storeDirNumber(int swap_file_number
)
213 return swap_file_number
>> SWAP_DIR_SHIFT
;
217 storeDirProperFileno(int dirn
, int fn
)
219 return (dirn
<< SWAP_DIR_SHIFT
) | (fn
& SWAP_FILE_MASK
);
223 * An entry written to the swap log MUST have the following
225 * 1. It MUST be a public key. It does no good to log
226 * a public ADD, change the key, then log a private
227 * DEL. So we need to log a DEL before we change a
228 * key from public to private.
229 * 2. It MUST have a valid (> -1) swap_file_number.
232 storeDirSwapLog(const StoreEntry
* e
, int op
)
234 int dirn
= e
->swap_file_number
>> SWAP_DIR_SHIFT
;
235 assert(dirn
< Config
.cacheSwap
.n_configured
);
236 assert(!EBIT_TEST(e
->flags
, KEY_PRIVATE
));
237 assert(e
->swap_file_number
>= 0);
239 * icons and such; don't write them to the swap log
241 if (EBIT_TEST(e
->flags
, ENTRY_SPECIAL
))
243 assert(op
> SWAP_LOG_NOP
&& op
< SWAP_LOG_MAX
);
244 debug(20, 3) ("storeDirSwapLog: %s %s %08X\n",
246 storeKeyText(e
->key
),
247 e
->swap_file_number
);
248 storeUfsDirSwapLog(e
, op
);
252 storeDirSwapLogFile(int dirn
, const char *ext
)
254 return storeUfsDirSwapLogFile(dirn
, ext
);
258 storeDirUpdateSwapSize(int fn
, size_t size
, int sign
)
260 int dirn
= (fn
>> SWAP_DIR_SHIFT
) % Config
.cacheSwap
.n_configured
;
261 int k
= ((size
+ 1023) >> 10) * sign
;
262 Config
.cacheSwap
.swapDirs
[dirn
].cur_size
+= k
;
263 store_swap_size
+= k
;
271 storeDirStats(StoreEntry
* sentry
)
273 storeAppendPrintf(sentry
, "Store Directory Statistics:\n");
274 storeAppendPrintf(sentry
, "Store Entries : %d\n",
275 memInUse(MEM_STOREENTRY
));
276 storeAppendPrintf(sentry
, "Maximum Swap Size : %8d KB\n",
277 Config
.Swap
.maxSize
);
278 storeAppendPrintf(sentry
, "Current Store Swap Size: %8d KB\n",
280 storeAppendPrintf(sentry
, "Current Capacity : %d%% used, %d%% free\n",
281 percent((int) store_swap_size
, (int) Config
.Swap
.maxSize
),
282 percent((int) (Config
.Swap
.maxSize
- store_swap_size
), (int) Config
.Swap
.maxSize
));
283 storeUfsDirStats(sentry
);
287 storeDirMapBitsInUse(void)
291 for (i
= 0; i
< Config
.cacheSwap
.n_configured
; i
++)
292 n
+= Config
.cacheSwap
.swapDirs
[i
].map
->n_files_in_map
;
297 * storeDirWriteCleanLogs
299 * Writes a "clean" swap log file from in-memory metadata.
302 storeDirWriteCleanLogs(int reopen
)
304 return storeUfsDirWriteCleanLogs(reopen
);
308 storeDirConfigure(void)
314 Config
.Swap
.maxSize
= 0;
315 for (i
= 0; i
< Config
.cacheSwap
.n_configured
; i
++) {
316 SD
= &Config
.cacheSwap
.swapDirs
[i
];;
317 Config
.Swap
.maxSize
+= SD
->max_size
;
318 n
= 2 * SD
->max_size
/ Config
.Store
.avgObjectSize
;
319 if (NULL
== SD
->map
) {
321 SD
->map
= file_map_create(n
);
322 } else if (n
> SD
->map
->max_n_files
) {
323 /* it grew, need to expand */
324 fm
= file_map_create(n
);
325 filemapCopy(SD
->map
, fm
);
326 filemapFreeMemory(SD
->map
);
329 /* else it shrunk, and we leave the old one in place */
334 storeDirDiskFull(int fn
)
336 int dirn
= fn
>> SWAP_DIR_SHIFT
;
337 SwapDir
*SD
= &Config
.cacheSwap
.swapDirs
[dirn
];
338 assert(0 <= dirn
&& dirn
< Config
.cacheSwap
.n_configured
);
339 SD
->max_size
= SD
->cur_size
;
340 debug(20, 1) ("WARNING: Shrinking cache_dir #%d to %d KB\n",
345 storeDirOpenSwapLogs(void)
347 return storeUfsDirOpenSwapLogs();
351 storeDirCloseSwapLogs(void)
353 return storeUfsDirCloseSwapLogs();
357 storeDirCloseTmpSwapLog(int dirn
)
359 return storeUfsDirCloseTmpSwapLog(dirn
);