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

📄 store_repl_lru.c

📁 一个功能非常全面的代理服务器源代码程序,
💻 C
字号:
/* * $Id: store_repl_lru.c,v 1.12 2005/05/17 16:56:44 hno Exp $ * * DEBUG: section ?     LRU Removal policy * AUTHOR: Henrik Nordstrom * * SQUID Web Proxy Cache          http://www.squid-cache.org/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from *  the Internet community; see the CONTRIBUTORS file for full *  details.   Many organizations have provided support for Squid's *  development; see the SPONSORS file for full details.  Squid is *  Copyrighted (C) 2001 by the Regents of the University of *  California; see the COPYRIGHT file for full details.  Squid *  incorporates software developed and/or copyrighted by other *  sources; see the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"REMOVALPOLICYCREATE createRemovalPolicy_lru;typedef struct _LruPolicyData LruPolicyData;struct _LruPolicyData {    RemovalPolicy *policy;    dlink_list list;    int count;    int nwalkers;    enum heap_entry_type {	TYPE_UNKNOWN = 0, TYPE_STORE_ENTRY, TYPE_STORE_MEM    } type;};/* Hack to avoid having to remember the RemovalPolicyNode location. * Needed by the purge walker to clear the policy information */static enum heap_entry_typerepl_guessType(StoreEntry * entry, RemovalPolicyNode * node){    if (node == &entry->repl)	return TYPE_STORE_ENTRY;    if (entry->mem_obj && node == &entry->mem_obj->repl)	return TYPE_STORE_MEM;    fatal("Heap Replacement: Unknown StoreEntry node type");    return TYPE_UNKNOWN;}#define SET_POLICY_NODE(entry,value) \    switch(lru->type) { \    case TYPE_STORE_ENTRY: entry->repl.data = value; break ; \    case TYPE_STORE_MEM: entry->mem_obj->repl.data = value ; break ; \    default: break; \    }typedef struct _LruNode LruNode;struct _LruNode {    /* Note: the dlink_node MUST be the first member of the LruNode     * structure. This member is later pointer typecasted to LruNode *.     */    dlink_node node;};static MemPool *lru_node_pool = NULL;static int nr_lru_policies = 0;static voidlru_add(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node){    LruPolicyData *lru = policy->_data;    LruNode *lru_node;    assert(!node->data);    node->data = lru_node = memPoolAlloc(lru_node_pool);    dlinkAddTail(entry, &lru_node->node, &lru->list);    lru->count += 1;    if (!lru->type)	lru->type = repl_guessType(entry, node);}static voidlru_remove(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node){    LruPolicyData *lru = policy->_data;    LruNode *lru_node = node->data;    if (!lru_node)	return;    /*     * It seems to be possible for an entry to exist in the hash     * but not be in the LRU list, so check for that case rather     * than suffer a NULL pointer access.     */    if (NULL == lru_node->node.data)	return;    assert(lru_node->node.data == entry);    node->data = NULL;    dlinkDelete(&lru_node->node, &lru->list);    memPoolFree(lru_node_pool, lru_node);    lru->count -= 1;}static voidlru_referenced(RemovalPolicy * policy, const StoreEntry * entry,    RemovalPolicyNode * node){    LruPolicyData *lru = policy->_data;    LruNode *lru_node = node->data;    if (!lru_node)	return;    dlinkDelete(&lru_node->node, &lru->list);    dlinkAddTail((void *) entry, &lru_node->node, &lru->list);}/** RemovalPolicyWalker **/typedef struct _LruWalkData LruWalkData;struct _LruWalkData {    LruNode *current;};static const StoreEntry *lru_walkNext(RemovalPolicyWalker * walker){    LruWalkData *lru_walk = walker->_data;    LruNode *lru_node = lru_walk->current;    if (!lru_node)	return NULL;    lru_walk->current = (LruNode *) lru_node->node.next;    return (StoreEntry *) lru_node->node.data;}static voidlru_walkDone(RemovalPolicyWalker * walker){    RemovalPolicy *policy = walker->_policy;    LruPolicyData *lru = policy->_data;    assert(strcmp(policy->_type, "lru") == 0);    assert(lru->nwalkers > 0);    lru->nwalkers -= 1;    safe_free(walker->_data);    cbdataFree(walker);}static RemovalPolicyWalker *lru_walkInit(RemovalPolicy * policy){    LruPolicyData *lru = policy->_data;    RemovalPolicyWalker *walker;    LruWalkData *lru_walk;    lru->nwalkers += 1;    walker = cbdataAlloc(RemovalPolicyWalker);    lru_walk = xcalloc(1, sizeof(*lru_walk));    walker->_policy = policy;    walker->_data = lru_walk;    walker->Next = lru_walkNext;    walker->Done = lru_walkDone;    lru_walk->current = (LruNode *) lru->list.head;    return walker;}/** RemovalPurgeWalker **/typedef struct _LruPurgeData LruPurgeData;struct _LruPurgeData {    LruNode *current;    LruNode *start;};static StoreEntry *lru_purgeNext(RemovalPurgeWalker * walker){    LruPurgeData *lru_walker = walker->_data;    RemovalPolicy *policy = walker->_policy;    LruPolicyData *lru = policy->_data;    LruNode *lru_node;    StoreEntry *entry;  try_again:    lru_node = lru_walker->current;    if (!lru_node || walker->scanned >= walker->max_scan)	return NULL;    walker->scanned += 1;    lru_walker->current = (LruNode *) lru_node->node.next;    if (lru_walker->current == lru_walker->start) {	/* Last node found */	lru_walker->current = NULL;    }    entry = (StoreEntry *) lru_node->node.data;    dlinkDelete(&lru_node->node, &lru->list);    if (storeEntryLocked(entry)) {	/* Shit, it is locked. we can't return this one */	walker->locked++;	dlinkAddTail(entry, &lru_node->node, &lru->list);	goto try_again;    }    memPoolFree(lru_node_pool, lru_node);    lru->count -= 1;    SET_POLICY_NODE(entry, NULL);    return entry;}static voidlru_purgeDone(RemovalPurgeWalker * walker){    RemovalPolicy *policy = walker->_policy;    LruPolicyData *lru = policy->_data;    assert(strcmp(policy->_type, "lru") == 0);    assert(lru->nwalkers > 0);    lru->nwalkers -= 1;    safe_free(walker->_data);    cbdataFree(walker);}static RemovalPurgeWalker *lru_purgeInit(RemovalPolicy * policy, int max_scan){    LruPolicyData *lru = policy->_data;    RemovalPurgeWalker *walker;    LruPurgeData *lru_walk;    lru->nwalkers += 1;    walker = cbdataAlloc(RemovalPurgeWalker);    lru_walk = xcalloc(1, sizeof(*lru_walk));    walker->_policy = policy;    walker->_data = lru_walk;    walker->max_scan = max_scan;    walker->Next = lru_purgeNext;    walker->Done = lru_purgeDone;    lru_walk->start = lru_walk->current = (LruNode *) lru->list.head;    return walker;}static voidlru_stats(RemovalPolicy * policy, StoreEntry * sentry){    LruPolicyData *lru = policy->_data;    LruNode *lru_node = (LruNode *) lru->list.head;  again:    if (lru_node) {	StoreEntry *entry = (StoreEntry *) lru_node->node.data;	if (storeEntryLocked(entry)) {	    lru_node = (LruNode *) lru_node->node.next;	    goto again;	}	storeAppendPrintf(sentry, "LRU reference age: %.2f days\n", (double) (squid_curtime - entry->lastref) / (double) (24 * 60 * 60));    }}static voidlru_free(RemovalPolicy * policy){    LruPolicyData *lru = policy->_data;    /* Make some verification of the policy state */    assert(strcmp(policy->_type, "lru") == 0);    assert(lru->nwalkers);    assert(lru->count);    /* Ok, time to destroy this policy */    safe_free(policy->_data);    memset(policy, 0, sizeof(*policy));    cbdataFree(policy);}RemovalPolicy *createRemovalPolicy_lru(wordlist * args){    RemovalPolicy *policy;    LruPolicyData *lru_data;    /* no arguments expected or understood */    assert(!args);    /* Initialize */    if (!lru_node_pool)	lru_node_pool = memPoolCreate("LRU policy node", sizeof(LruNode));    /* Allocate the needed structures */    lru_data = xcalloc(1, sizeof(*lru_data));    policy = cbdataAlloc(RemovalPolicy);    /* Initialize the URL data */    lru_data->policy = policy;    /* Populate the policy structure */    policy->_type = "lru";    policy->_data = lru_data;    policy->Free = lru_free;    policy->Add = lru_add;    policy->Remove = lru_remove;    policy->Referenced = lru_referenced;    policy->Dereferenced = lru_referenced;    policy->WalkInit = lru_walkInit;    policy->PurgeInit = lru_purgeInit;    policy->Stats = lru_stats;    /* Increase policy usage count */    nr_lru_policies += 0;    return policy;}

⌨️ 快捷键说明

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