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

📄 store.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
    storeUnlockObject(e);#endif}void#if STDC_HEADERSstoreAppendPrintf(StoreEntry * e, const char *fmt,...)#elsestoreAppendPrintf(va_alist)     va_dcl#endif{#if STDC_HEADERS    va_list args;    va_start(args, fmt);#else    va_list args;    StoreEntry *e = NULL;    const char *fmt = NULL;    va_start(args);    e = va_arg(args, StoreEntry *);    fmt = va_arg(args, char *);#endif    storeAppendVPrintf(e, fmt, args);    va_end(args);}/* used be storeAppendPrintf and Packer */voidstoreAppendVPrintf(StoreEntry * e, const char *fmt, va_list vargs){    LOCAL_ARRAY(char, buf, 4096);    buf[0] = '\0';    vsnprintf(buf, 4096, fmt, vargs);    storeAppend(e, buf, strlen(buf));}struct _store_check_cachable_hist {    struct {	int non_get;	int not_entry_cachable;	int release_request;	int wrong_content_length;	int negative_cached;	int too_big;	int private_key;	int too_many_open_files;	int too_many_open_fds;	int lru_age_too_low;    } no;    struct {	int Default;    } yes;} store_check_cachable_hist;intstoreTooManyDiskFilesOpen(void){    if (Config.max_open_disk_fds == 0)	return 0;    if (store_open_disk_fd > Config.max_open_disk_fds)	return 1;    return 0;}intstoreCheckCachable(StoreEntry * e){#if CACHE_ALL_METHODS    if (e->mem_obj->method != METHOD_GET) {	debug(20, 2) ("storeCheckCachable: NO: non-GET method\n");	store_check_cachable_hist.no.non_get++;    } else#endif    if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) {	debug(20, 2) ("storeCheckCachable: NO: not cachable\n");	store_check_cachable_hist.no.not_entry_cachable++;    } else if (EBIT_TEST(e->flags, RELEASE_REQUEST)) {	debug(20, 2) ("storeCheckCachable: NO: release requested\n");	store_check_cachable_hist.no.release_request++;    } else if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {	debug(20, 2) ("storeCheckCachable: NO: wrong content-length\n");	store_check_cachable_hist.no.wrong_content_length++;    } else if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {	debug(20, 3) ("storeCheckCachable: NO: negative cached\n");	store_check_cachable_hist.no.negative_cached++;	return 0;		/* avoid release call below */    } else if (e->mem_obj->inmem_hi > Config.Store.maxObjectSize) {	debug(20, 2) ("storeCheckCachable: NO: too big\n");	store_check_cachable_hist.no.too_big++;    } else if (EBIT_TEST(e->flags, KEY_PRIVATE)) {	debug(20, 3) ("storeCheckCachable: NO: private key\n");	store_check_cachable_hist.no.private_key++;    } else if (e->swap_status != SWAPOUT_NONE) {	/*	 * here we checked the swap_status because the remaining	 * cases are only relevant only if we haven't started swapping	 * out the object yet.	 */	return 1;    } else if (storeTooManyDiskFilesOpen()) {	debug(20, 2) ("storeCheckCachable: NO: too many disk files open\n");	store_check_cachable_hist.no.too_many_open_files++;    } else if (fdNFree() < RESERVED_FD) {	debug(20, 2) ("storeCheckCachable: NO: too many FD's open\n");	store_check_cachable_hist.no.too_many_open_fds++;    } else if (storeExpiredReferenceAge() < 300) {	debug(20, 2) ("storeCheckCachable: NO: LRU Age = %d\n",	    storeExpiredReferenceAge());	store_check_cachable_hist.no.lru_age_too_low++;    } else {	store_check_cachable_hist.yes.Default++;	return 1;    }    storeReleaseRequest(e);    EBIT_CLR(e->flags, ENTRY_CACHABLE);    return 0;}static voidstoreCheckCachableStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "Category\t Count\n");    storeAppendPrintf(sentry, "no.non_get\t%d\n",	store_check_cachable_hist.no.non_get);    storeAppendPrintf(sentry, "no.not_entry_cachable\t%d\n",	store_check_cachable_hist.no.not_entry_cachable);    storeAppendPrintf(sentry, "no.release_request\t%d\n",	store_check_cachable_hist.no.release_request);    storeAppendPrintf(sentry, "no.wrong_content_length\t%d\n",	store_check_cachable_hist.no.wrong_content_length);    storeAppendPrintf(sentry, "no.negative_cached\t%d\n",	store_check_cachable_hist.no.negative_cached);    storeAppendPrintf(sentry, "no.too_big\t%d\n",	store_check_cachable_hist.no.too_big);    storeAppendPrintf(sentry, "no.private_key\t%d\n",	store_check_cachable_hist.no.private_key);    storeAppendPrintf(sentry, "no.too_many_open_files\t%d\n",	store_check_cachable_hist.no.too_many_open_files);    storeAppendPrintf(sentry, "no.too_many_open_fds\t%d\n",	store_check_cachable_hist.no.too_many_open_fds);    storeAppendPrintf(sentry, "no.lru_age_too_low\t%d\n",	store_check_cachable_hist.no.lru_age_too_low);    storeAppendPrintf(sentry, "yes.default\t%d\n",	store_check_cachable_hist.yes.Default);}/* Complete transfer into the local cache.  */voidstoreComplete(StoreEntry * e){    debug(20, 3) ("storeComplete: '%s'\n", storeKeyText(e->key));    if (e->store_status != STORE_PENDING) {	/*	 * if we're not STORE_PENDING, then probably we got aborted	 * and there should be NO clients on this entry	 */	assert(EBIT_TEST(e->flags, ENTRY_ABORTED));	assert(e->mem_obj->nclients == 0);	return;    }    e->mem_obj->object_sz = e->mem_obj->inmem_hi;    e->store_status = STORE_OK;    assert(e->mem_status == NOT_IN_MEMORY);    if (!storeEntryValidLength(e)) {	EBIT_SET(e->flags, ENTRY_BAD_LENGTH);	storeReleaseRequest(e);    }#if USE_CACHE_DIGESTS    if (e->mem_obj->request)	e->mem_obj->request->hier.store_complete_stop = current_time;#endif    InvokeHandlers(e);    storeCheckSwapOut(e);}/* * Someone wants to abort this transfer.  Set the reason in the * request structure, call the server-side callback and mark the * entry for releasing  */voidstoreAbort(StoreEntry * e){    MemObject *mem = e->mem_obj;    assert(e->store_status == STORE_PENDING);    assert(mem != NULL);    debug(20, 6) ("storeAbort: %s\n", storeKeyText(e->key));    storeLockObject(e);		/* lock while aborting */    storeNegativeCache(e);    storeReleaseRequest(e);    EBIT_SET(e->flags, ENTRY_ABORTED);    storeSetMemStatus(e, NOT_IN_MEMORY);    /* No DISK swap for negative cached object */    e->swap_status = SWAPOUT_NONE;    e->store_status = STORE_OK;    /*     * We assign an object length here.  The only other place we assign     * the object length is in storeComplete()     */    mem->object_sz = mem->inmem_hi;    /* Notify the server side */    if (mem->abort.callback) {	eventAdd("mem->abort.callback",	    mem->abort.callback,	    mem->abort.data,	    0.0,	    0);	mem->abort.callback = NULL;	mem->abort.data = NULL;    }    /* Notify the client side */    InvokeHandlers(e);    /* Do we need to close the swapout file? */    /* Not if we never started swapping out */    /* But we may need to cancel an open/stat in progress if using ASYNC */#if USE_ASYNC_IO    aioCancel(-1, e);#endif    if (e->swap_file_number > -1) {#if USE_ASYNC_IO	/* Need to cancel any pending ASYNC writes right now */	if (mem->swapout.fd >= 0)	    aioCancel(mem->swapout.fd, NULL);#endif	/* we have to close the disk file if there is no write pending */	if (!storeSwapOutWriteQueued(mem))	    storeSwapOutFileClose(e);    }    storeUnlockObject(e);	/* unlock */}/* Clear Memory storage to accommodate the given object len */static voidstoreGetMemSpace(int size){    StoreEntry *e = NULL;    int released = 0;    static time_t last_check = 0;    int pages_needed;    dlink_node *m;    dlink_node *head;    dlink_node *prev = NULL;    if (squid_curtime == last_check)	return;    last_check = squid_curtime;    pages_needed = (size / SM_PAGE_SIZE) + 1;    if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)	return;    if (store_rebuilding)	return;    debug(20, 2) ("storeGetMemSpace: Starting, need %d pages\n", pages_needed);    head = inmem_list.head;    for (m = inmem_list.tail; m; m = prev) {	if (m == head)	    break;	prev = m->prev;	e = m->data;	if (storeEntryLocked(e)) {	    dlinkDelete(m, &inmem_list);	    dlinkAdd(e, m, &inmem_list);	    continue;	}	released++;	storePurgeMem(e);	if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)	    break;    }    debug(20, 3) ("storeGetMemSpace stats:\n");    debug(20, 3) ("  %6d HOT objects\n", hot_obj_count);    debug(20, 3) ("  %6d were released\n", released);}/* The maximum objects to scan for maintain storage space */#define MAINTAIN_MAX_SCAN	1024#define MAINTAIN_MAX_REMOVE	64/*  * This routine is to be called by main loop in main.c. * It removes expired objects on only one bucket for each time called. * returns the number of objects removed * * This should get called 1/s from main(). */voidstoreMaintainSwapSpace(void *datanotused){    dlink_node *m;    dlink_node *prev = NULL;    StoreEntry *e = NULL;    int scanned = 0;    int locked = 0;    int expired = 0;    int max_scan;    int max_remove;    double f;    static time_t last_warn_time = 0;    /* We can't delete objects while rebuilding swap */    if (store_rebuilding) {	eventAdd("MaintainSwapSpace", storeMaintainSwapSpace, NULL, 1.0, 1);	return;    } else {	f = (double) (store_swap_size - store_swap_low) / (store_swap_high - store_swap_low);	f = f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f;	max_scan = (int) (f * 400.0 + 100.0);	max_remove = (int) (f * 70.0 + 10.0);	eventAdd("MaintainSwapSpace", storeMaintainSwapSpace, NULL, 1.0 - f, 1);    }    debug(20, 3) ("storeMaintainSwapSpace: f=%f, max_scan=%d, max_remove=%d\n",	f, max_scan, max_remove);    for (m = store_list.tail; m; m = prev) {	prev = m->prev;	e = m->data;	scanned++;	if (storeEntryLocked(e)) {	    /*	     * If there is a locked entry at the tail of the LRU list,	     * move it to the beginning to get it out of the way.	     * Theoretically, we might have all locked objects at the	     * tail, and then we'll never remove anything here and the	     * LRU age will go to zero.	     */	    if (memInUse(MEM_STOREENTRY) > max_scan) {		dlinkDelete(&e->lru, &store_list);		dlinkAdd(e, &e->lru, &store_list);	    }	    locked++;	} else if (storeCheckExpired(e)) {	    expired++;	    storeRelease(e);	}	if (expired >= max_remove)	    break;	if (scanned >= max_scan)	    break;    }    debug(20, 3) ("storeMaintainSwapSpace stats:\n");    debug(20, 3) ("  %6d objects\n", memInUse(MEM_STOREENTRY));    debug(20, 3) ("  %6d were scanned\n", scanned);    debug(20, 3) ("  %6d were locked\n", locked);    debug(20, 3) ("  %6d were expired\n", expired);    if (store_swap_size < Config.Swap.maxSize)	return;    if (squid_curtime - last_warn_time < 10)	return;    debug(20, 0) ("WARNING: Disk space over limit: %d KB > %d KB\n",	store_swap_size, Config.Swap.maxSize);    last_warn_time = squid_curtime;}/* release an object from a cache *//* return number of objects released. */voidstoreRelease(StoreEntry * e){    debug(20, 3) ("storeRelease: Releasing: '%s'\n", storeKeyText(e->key));    /* If, for any reason we can't discard this object because of an     * outstanding request, mark it for pending release */    if (storeEntryLocked(e)) {	storeExpireNow(e);	debug(20, 3) ("storeRelease: Only setting RELEASE_REQUEST bit\n");	storeReleaseRequest(e);	return;    }#if USE_ASYNC_IO    /*     * Make sure all forgotten async ops are cancelled     */    aioCancel(-1, e);#endif    if (store_rebuilding) {	storeSetPrivateKey(e);	if (e->mem_obj) {	    storeSetMemStatus(e, NOT_IN_MEMORY);	    destroy_MemObject(e);	}	/*	 * Fake a call to storeLockObject().  When rebuilding is done,	 * we'll just call storeUnlockObject() on these.	 */	e->lock_count++;	stackPush(&LateReleaseStack, e);	return;    }    storeLog(STORE_LOG_RELEASE, e);    if (e->swap_file_number > -1) {	storeUnlinkFileno(e->swap_file_number);	storeDirMapBitReset(e->swap_file_number);	if (e->swap_status == SWAPOUT_DONE)	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))		storeDirUpdateSwapSize(e->swap_file_number, e->swap_file_sz, -1);	if (!EBIT_TEST(e->flags, KEY_PRIVATE))	    storeDirSwapLog(e, SWAP_LOG_DEL);    }    storeSetMemStatus(e, NOT_IN_MEMORY);    destroy_StoreEntry(e);}static voidstoreLateRelease(void *unused){    StoreEntry *e;    int i;    static int n = 0;    if (store_rebuilding) {	eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);	return;    }    for (i = 0; i < 10; i++) {	e = stackPop(&LateReleaseStack);	if (e == NULL) {	    /* done! */	    debug(20, 1) ("storeLateRelease: released %d objects\n", n);	    return;

⌨️ 快捷键说明

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