diff -rc2 ../squid-hno/src/cache_cf.c ./src/cache_cf.c *** ../squid-hno/src/cache_cf.c Mon Jan 10 19:56:42 2000 --- ./src/cache_cf.c Mon Mar 20 23:36:39 2000 *************** *** 342,345 **** --- 342,353 ---- Config.Wais.peer->http_port = Config.Wais.relayPort; } + if (Config.max_small_object_target != 0 && Config.max_small_object_target < 1000) { + debug(3, 0) ("WARNING: disabling 'max_small_object_target'\n"); + Config.max_small_object_target = 0; + } + if (Config.small_object_max_size < 10000) { + debug(3, 0) ("WARNING: resetting 'small_object_max_size' to 10000\n"); + Config.small_object_max_size = 10000; + } } diff -rc2 ../squid-hno/src/cf.data.pre ./src/cf.data.pre *** ../squid-hno/src/cf.data.pre Mon Jan 10 19:56:42 2000 --- ./src/cf.data.pre Mon Mar 20 23:31:57 2000 *************** *** 1173,1176 **** --- 1173,1206 ---- DOC_END + NAME: max_small_object_target + TYPE: int + LOC: Config.max_small_object_target + DEFAULT: 0 + DOC_START + When using a very large disk cache, the referenceAge can become + so large that an inordinate amount of small objects is cached. + When byte hit rate is more important than Squids CPU usage, + setting a target maximum for the number of small objects can help + keeping Squids memory footprint down, while keeping large objects + in the cache longer. + + Default is 0 (disabled). It is suggested to disable this feature + first, and watch the number of objects in the cache until Squid + runs out of memory, then set the target at two thirds of that + amount. + + max_small_object_target 0 + DOC_END + + NAME: small_object_max_size + TYPE: int + LOC: Config.small_object_max_size + DEFAULT: 0 + DOC_START + The maximum size for an object to be eligible for premature + discarding with the max_small_object_target setting enabled. + + small_object_max_size 100000 + DOC_END NAME: quick_abort_min diff -rc2 ../squid-hno/src/squid.conf ./src/squid.conf diff -rc2 ../squid-hno/src/store.c ./src/store.c *** ../squid-hno/src/store.c Mon Jan 10 19:56:42 2000 --- ./src/store.c Mon Mar 20 23:32:58 2000 *************** *** 76,79 **** --- 76,80 ---- * local function prototypes */ + static void storeRemoveSmallObjects(void); static int storeCheckExpired(const StoreEntry *); static int storeEntryLocked(const StoreEntry *); *************** *** 721,724 **** --- 722,726 ---- double f; static time_t last_warn_time = 0; + static int times_run = 0; /* We can't delete objects while rebuilding swap */ if (store_rebuilding) { *************** *** 765,768 **** --- 767,773 ---- debug(20, 3) (" %6d were locked\n", locked); debug(20, 3) (" %6d were expired\n", expired); + times_run++; + if (Config.max_small_object_target > 0 && (times_run % 60) == 0) + storeRemoveSmallObjects(); if (store_swap_size < Config.Swap.maxSize) return; *************** *** 772,775 **** --- 777,833 ---- store_swap_size, Config.Swap.maxSize); last_warn_time = squid_curtime; + } + + /* + * This routine is to be called by storeMaintainSwapSpace at most + * once per minute, and only when safe. + * It removes small objects using a fairly deep traversal. + * Returns the number of objects removed + * + * This should get called 1/s from main(). + */ + static void + storeRemoveSmallObjects(void) + { + dlink_node *m; + dlink_node *prev = NULL; + StoreEntry *e = NULL; + int scanned = 0; + int locked = 0; + int expired = 0; + int toobig = 0; + int max_scan; + int target; + + if (memInUse(MEM_STOREENTRY) < Config.max_small_object_target) + return; + + max_scan = memInUse(MEM_STOREENTRY) / 2; + target = memInUse(MEM_STOREENTRY) - Config.max_small_object_target; + for (m = store_list.tail; m; m = prev) { + prev = m->prev; + e = m->data; + scanned++; + if (storeEntryLocked(e)) { + locked++; + } else if (e->swap_file_sz > Config.small_object_max_size) { + toobig++; + } else { + expired++; + target--; + storeRelease(e); + } + if (target <= 0) + break; + if (scanned >= max_scan) + break; + } + /* XXX Change level back to 3 */ + debug(20, 1) ("storeRemoveSmallObjects stats:\n"); + debug(20, 1) (" %6d objects\n", memInUse(MEM_STOREENTRY)); + debug(20, 1) (" %6d were scanned\n", scanned); + debug(20, 1) (" %6d were locked\n", locked); + debug(20, 1) (" %6d were expired\n", expired); + debug(20, 1) (" %6d were too big\n", toobig); } diff -rc2 ../squid-hno/src/structs.h ./src/structs.h *** ../squid-hno/src/structs.h Mon Jan 10 19:56:42 2000 --- ./src/structs.h Mon Mar 20 23:06:32 2000 *************** *** 455,458 **** --- 455,460 ---- char *coredump_dir; char *chroot_dir; + int max_small_object_target; + int small_object_max_size; };