📄 store.c
字号:
} storeUnlockObject(e); n++; } eventAdd("storeLateRelease", storeLateRelease, NULL, 0.0, 1);}/* return 1 if a store entry is locked */static intstoreEntryLocked(const StoreEntry * e){ if (e->lock_count) return 1; if (e->swap_status == SWAPOUT_OPENING) return 1; if (e->swap_status == SWAPOUT_WRITING) return 1; if (e->store_status == STORE_PENDING) return 1; /* * SPECIAL, PUBLIC entries should be "locked" */ if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) if (!EBIT_TEST(e->flags, KEY_PRIVATE)) return 1; return 0;}static intstoreEntryValidLength(const StoreEntry * e){ int diff; const HttpReply *reply; assert(e->mem_obj != NULL); reply = e->mem_obj->reply; debug(20, 3) ("storeEntryValidLength: Checking '%s'\n", storeKeyText(e->key)); debug(20, 5) ("storeEntryValidLength: object_len = %d\n", objectLen(e)); debug(20, 5) ("storeEntryValidLength: hdr_sz = %d\n", reply->hdr_sz); debug(20, 5) ("storeEntryValidLength: content_length = %d\n", reply->content_length); if (reply->content_length < 0) { debug(20, 5) ("storeEntryValidLength: Unspecified content length: %s\n", storeKeyText(e->key)); return 1; } if (reply->hdr_sz == 0) { debug(20, 5) ("storeEntryValidLength: Zero header size: %s\n", storeKeyText(e->key)); return 1; } if (e->mem_obj->method == METHOD_HEAD) { debug(20, 5) ("storeEntryValidLength: HEAD request: %s\n", storeKeyText(e->key)); return 1; } if (reply->sline.status == HTTP_NOT_MODIFIED) return 1; if (reply->sline.status == HTTP_NO_CONTENT) return 1; diff = reply->hdr_sz + reply->content_length - objectLen(e); if (diff == 0) return 1; debug(20, 3) ("storeEntryValidLength: %d bytes too %s; '%s'\n", diff < 0 ? -diff : diff, diff < 0 ? "big" : "small", storeKeyText(e->key)); return 0;}static voidstoreInitHashValues(void){ int i; /* Calculate size of hash table (maximum currently 64k buckets). */ i = Config.Swap.maxSize / Config.Store.avgObjectSize; debug(20, 1) ("Swap maxSize %d KB, estimated %d objects\n", Config.Swap.maxSize, i); i /= Config.Store.objectsPerBucket; debug(20, 1) ("Target number of buckets: %d\n", i); /* ideally the full scan period should be configurable, for the * moment it remains at approximately 24 hours. */ store_hash_buckets = storeKeyHashBuckets(i); store_maintain_rate = 86400 / store_hash_buckets; assert(store_maintain_rate > 0); debug(20, 1) ("Using %d Store buckets, replacement runs every %d second%s\n", store_hash_buckets, store_maintain_rate, store_maintain_rate == 1 ? null_string : "s"); debug(20, 1) ("Max Mem size: %d KB\n", Config.memMaxSize >> 10); debug(20, 1) ("Max Swap size: %d KB\n", Config.Swap.maxSize);}voidstoreInit(void){ storeKeyInit(); storeInitHashValues(); store_table = hash_create(storeKeyHashCmp, store_hash_buckets, storeKeyHashHash); storeDigestInit(); storeLogOpen(); if (storeVerifyCacheDirs() < 0) { xstrncpy(tmp_error_buf, "\tFailed to verify one of the swap directories, Check cache.log\n" "\tfor details. Run 'squid -z' to create swap directories\n" "\tif needed, or if running Squid for the first time.", ERROR_BUF_SZ); fatal(tmp_error_buf); } storeDirOpenSwapLogs(); store_list.head = store_list.tail = NULL; inmem_list.head = inmem_list.tail = NULL; stackInit(&LateReleaseStack); eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1); storeRebuildStart(); cachemgrRegister("storedir", "Store Directory Stats", storeDirStats, 0, 1); cachemgrRegister("store_check_cachable_stats", "storeCheckCachable() Stats", storeCheckCachableStats, 0, 1);}voidstoreConfigure(void){ store_swap_high = (long) (((float) Config.Swap.maxSize * (float) Config.Swap.highWaterMark) / (float) 100); store_swap_low = (long) (((float) Config.Swap.maxSize * (float) Config.Swap.lowWaterMark) / (float) 100); store_swap_mid = (store_swap_high >> 1) + (store_swap_low >> 1); store_pages_max = Config.memMaxSize / SM_PAGE_SIZE;}static intstoreKeepInMemory(const StoreEntry * e){ MemObject *mem = e->mem_obj; if (mem == NULL) return 0; if (mem->data_hdr.head == NULL) return 0; return mem->inmem_lo == 0;}static intstoreCheckExpired(const StoreEntry * e){ if (storeEntryLocked(e)) return 0; if (EBIT_TEST(e->flags, RELEASE_REQUEST)) return 1; if (EBIT_TEST(e->flags, ENTRY_NEGCACHED) && squid_curtime >= e->expires) return 1; if (squid_curtime - e->lastref > storeExpiredReferenceAge()) return 1; return 0;}/* * storeExpiredReferenceAge * * The LRU age is scaled exponentially between 1 minute and * Config.referenceAge , when store_swap_low < store_swap_size < * store_swap_high. This keeps store_swap_size within the low and high * water marks. If the cache is very busy then store_swap_size stays * closer to the low water mark, if it is not busy, then it will stay * near the high water mark. The LRU age value can be examined on the * cachemgr 'info' page. */time_tstoreExpiredReferenceAge(void){ double x; double z; time_t age; x = (double) (store_swap_high - store_swap_size) / (store_swap_high - store_swap_low); x = x < 0.0 ? 0.0 : x > 1.0 ? 1.0 : x; z = pow((double) (Config.referenceAge / 60), x); age = (time_t) (z * 60.0); if (age < 60) age = 60; else if (age > 31536000) age = 31536000; return age;}voidstoreNegativeCache(StoreEntry * e){ e->expires = squid_curtime + Config.negativeTtl; EBIT_SET(e->flags, ENTRY_NEGCACHED);}voidstoreFreeMemory(void){ hashFreeItems(store_table, destroy_StoreEntry); hashFreeMemory(store_table); store_table = NULL;#if USE_CACHE_DIGEST if (store_digest) cacheDigestDestroy(store_digest);#endif store_digest = NULL;}intexpiresMoreThan(time_t expires, time_t when){ if (expires < 0) /* No Expires given */ return 1; return (expires > (squid_curtime + when));}intstoreEntryValidToSend(StoreEntry * e){ if (EBIT_TEST(e->flags, RELEASE_REQUEST)) return 0; if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) if (e->expires <= squid_curtime) return 0; if (EBIT_TEST(e->flags, ENTRY_ABORTED)) return 0; return 1;}voidstoreTimestampsSet(StoreEntry * entry){ time_t served_date = -1; const HttpReply *reply = entry->mem_obj->reply; served_date = reply->date; if (served_date < 0) served_date = squid_curtime; entry->expires = reply->expires; entry->lastmod = reply->last_modified; entry->timestamp = served_date;}voidstoreRegisterAbort(StoreEntry * e, STABH * cb, void *data){ MemObject *mem = e->mem_obj; assert(mem); assert(mem->abort.callback == NULL); mem->abort.callback = cb; mem->abort.data = data;}voidstoreUnregisterAbort(StoreEntry * e){ MemObject *mem = e->mem_obj; assert(mem); mem->abort.callback = NULL;}voidstoreMemObjectDump(MemObject * mem){ debug(20, 1) ("MemObject->data.head: %p\n", mem->data_hdr.head); debug(20, 1) ("MemObject->data.tail: %p\n", mem->data_hdr.tail); debug(20, 1) ("MemObject->data.origin_offset: %d\n", mem->data_hdr.origin_offset); debug(20, 1) ("MemObject->start_ping: %d.%06d\n", (int) mem->start_ping.tv_sec, (int) mem->start_ping.tv_usec); debug(20, 1) ("MemObject->inmem_hi: %d\n", (int) mem->inmem_hi); debug(20, 1) ("MemObject->inmem_lo: %d\n", (int) mem->inmem_lo); debug(20, 1) ("MemObject->clients: %p\n", mem->clients); debug(20, 1) ("MemObject->nclients: %d\n", mem->nclients); debug(20, 1) ("MemObject->swapout.fd: %d\n", mem->swapout.fd); debug(20, 1) ("MemObject->reply: %p\n", mem->reply); debug(20, 1) ("MemObject->request: %p\n", mem->request); debug(20, 1) ("MemObject->log_url: %p %s\n", mem->log_url, checkNullString(mem->log_url));}voidstoreEntryDump(StoreEntry * e, int l){ debug(20, l) ("StoreEntry->key: %s\n", storeKeyText(e->key)); debug(20, l) ("StoreEntry->next: %p\n", e->next); debug(20, l) ("StoreEntry->mem_obj: %p\n", e->mem_obj); debug(20, l) ("StoreEntry->timestamp: %d\n", (int) e->timestamp); debug(20, l) ("StoreEntry->lastref: %d\n", (int) e->lastref); debug(20, l) ("StoreEntry->expires: %d\n", (int) e->expires); debug(20, l) ("StoreEntry->lastmod: %d\n", (int) e->lastmod); debug(20, l) ("StoreEntry->swap_file_sz: %d\n", (int) e->swap_file_sz); debug(20, l) ("StoreEntry->refcount: %d\n", e->refcount); debug(20, l) ("StoreEntry->flags: %s\n", storeEntryFlags(e)); debug(20, l) ("StoreEntry->swap_file_number: %d\n", (int) e->swap_file_number); debug(20, l) ("StoreEntry->lock_count: %d\n", (int) e->lock_count); debug(20, l) ("StoreEntry->mem_status: %d\n", (int) e->mem_status); debug(20, l) ("StoreEntry->ping_status: %d\n", (int) e->ping_status); debug(20, l) ("StoreEntry->store_status: %d\n", (int) e->store_status); debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);}/* NOTE, this function assumes only two mem states */voidstoreSetMemStatus(StoreEntry * e, int new_status){ MemObject *mem = e->mem_obj; if (new_status == e->mem_status) return; assert(mem != NULL); if (new_status == IN_MEMORY) { assert(mem->inmem_lo == 0); dlinkAdd(e, &mem->lru, &inmem_list); hot_obj_count++; } else { dlinkDelete(&mem->lru, &inmem_list); hot_obj_count--; } e->mem_status = new_status;}const char *storeUrl(const StoreEntry * e){ if (e == NULL) return "[null_entry]"; else if (e->mem_obj == NULL) return "[null_mem_obj]"; else return e->mem_obj->url;}voidstoreCreateMemObject(StoreEntry * e, const char *url, const char *log_url){ if (e->mem_obj) return; e->mem_obj = new_MemObject(url, log_url);}/* this just sets DELAY_SENDING */voidstoreBuffer(StoreEntry * e){ EBIT_SET(e->flags, DELAY_SENDING);}/* this just clears DELAY_SENDING and Invokes the handlers */voidstoreBufferFlush(StoreEntry * e){ EBIT_CLR(e->flags, DELAY_SENDING); InvokeHandlers(e); storeCheckSwapOut(e);}voidstoreUnlinkFileno(int fileno){ debug(20, 5) ("storeUnlinkFileno: %08X\n", fileno);#if USE_ASYNC_IO safeunlink(storeSwapFullPath(fileno, NULL), 1);#else unlinkdUnlink(storeSwapFullPath(fileno, NULL));#endif}intobjectLen(const StoreEntry * e){ assert(e->mem_obj != NULL); return e->mem_obj->object_sz;}intcontentLen(const StoreEntry * e){ assert(e->mem_obj != NULL); assert(e->mem_obj->reply != NULL); return e->mem_obj->object_sz - e->mem_obj->reply->hdr_sz;}HttpReply *storeEntryReply(StoreEntry * e){ if (NULL == e) return NULL; if (NULL == e->mem_obj) return NULL; return e->mem_obj->reply;}voidstoreEntryReset(StoreEntry * e){ MemObject *mem = e->mem_obj; debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e)); assert(mem->swapout.fd == -1); stmemFree(&mem->data_hdr); mem->inmem_hi = mem->inmem_lo = 0; httpReplyDestroy(mem->reply); mem->reply = httpReplyCreate();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -