refresh times. Replaced 'ttl_pattern' with 'refresh_pattern'.
- Dropped 'http', 'ftp', and 'gopher' config options.
- Added a single 'maximum_object_size' value.
- Moved storeStartDeleteBehind() calls from http/ftp/gopher to
storeAppend().
- Moved storeClientListAdd() call from store to client/icp
because of storeClientCopy() race condition between IMS
replies and objects in delete behind mode.
- renamed TCP_EXPIRED* to TCP_REFRESH*.
- Stopped appending error messages to partially delivered
objects.
/*
- * $Id: cache_cf.cc,v 1.118 1996/10/27 07:11:51 wessels Exp $
+ * $Id: cache_cf.cc,v 1.119 1996/10/28 07:44:18 wessels Exp $
*
* DEBUG: section 3 Configuration File Parsing
* AUTHOR: Harvest Derived
#define DefaultSwapHighWaterMark 90 /* 90% */
#define DefaultSwapLowWaterMark 75 /* 75% */
-#define DefaultFtpDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
-#define DefaultFtpMaxObjSize (4 << 20) /* 4 MB */
-#define DefaultGopherDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
-#define DefaultGopherMaxObjSize (4 << 20) /* 4 MB */
-#define DefaultHttpDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
-#define DefaultHttpMaxObjSize (4 << 20) /* 4 MB */
-#define DefaultWaisDefaultTtl (3 * 24 * 60 * 60) /* 3 days */
-#define DefaultWaisMaxObjSize (4 << 20) /* 4 MB */
#define DefaultWaisRelayHost (char *)NULL
#define DefaultWaisRelayPort 0
#define DefaultIpcacheLow 90
#define DefaultIpcacheHigh 95
#define DefaultMinDirectHops 4
+#define DefaultMaxObjectSize (4<<20) /* 4Mb */
+#define DefaultAvgObjectSize 20 /* 20k */
+#define DefaultObjectsPerBucket 50
int httpd_accel_mode = 0; /* for fast access */
char *DefaultSwapDir = DEFAULT_SWAP_DIR;
static void parseDnsProgramLine _PARAMS((void));
static void parseEffectiveUserLine _PARAMS((void));
static void parseErrHtmlLine _PARAMS((void));
-static void parseFtpLine _PARAMS((void));
static void parseFtpOptionsLine _PARAMS((void));
static void parseFtpProgramLine _PARAMS((void));
static void parseFtpUserLine _PARAMS((void));
-static void parseGopherLine _PARAMS((void));
static void parseWordlist _PARAMS((wordlist **));
static void parseHostAclLine _PARAMS((void));
static void parseHostDomainLine _PARAMS((void));
-static void parseHttpLine _PARAMS((void));
static void parseHttpPortLine _PARAMS((void));
static void parseHttpdAccelLine _PARAMS((void));
static void parseIPLine _PARAMS((ip_acl ** list));
static void parseMemLine _PARAMS((void));
static void parseMgrLine _PARAMS((void));
static void parsePidFilenameLine _PARAMS((void));
-static void parseRequestSizeLine _PARAMS((void));
+static void parseKilobytes _PARAMS((int *));
static void parseStoreLogLine _PARAMS((void));
static void parseSwapLine _PARAMS((void));
static void parseRefreshPattern _PARAMS((int icase));
Config.Swap.maxSize = i << 10;
}
-static void
-parseHttpLine(void)
-{
- char *token;
- int i;
- GetInteger(i);
- Config.Http.maxObjSize = i << 20;
- GetInteger(i);
- Config.Http.defaultTtl = i * 60;
-}
-
-static void
-parseGopherLine(void)
-{
- char *token;
- int i;
- GetInteger(i);
- Config.Gopher.maxObjSize = i << 20;
- GetInteger(i);
- Config.Gopher.defaultTtl = i * 60;
-}
-
-static void
-parseFtpLine(void)
-{
- char *token;
- int i;
- GetInteger(i);
- Config.Ftp.maxObjSize = i << 20;
- GetInteger(i);
- Config.Ftp.defaultTtl = i * 60;
-}
-
static void
parseRefreshPattern(int icase)
{
}
static void
-parseRequestSizeLine(void)
+parseKilobytes(int *val)
{
char *token;
int i;
GetInteger(i);
- Config.maxRequestSize = i * 1024;
+ *val = i * 1024;
}
static void
Config.Wais.relayHost = xstrdup(token);
GetInteger(i);
Config.Wais.relayPort = (u_short) i;
- GetInteger(i);
- Config.Wais.maxObjSize = i << 20;
}
static void
aclParseAccessLine(&DelayAccessList);
#endif
- else if (!strcmp(token, "gopher"))
- parseGopherLine();
-
- else if (!strcmp(token, "http"))
- parseHttpLine();
-
- else if (!strcmp(token, "ftp"))
- parseFtpLine();
-
else if (!strcmp(token, "refresh_pattern"))
parseRefreshPattern(0);
else if (!strcmp(token, "refresh_pattern/i"))
parseIntegerValue(&Config.lifetimeShutdown);
else if (!strcmp(token, "request_size"))
- parseRequestSizeLine();
+ parseKilobytes(&Config.maxRequestSize);
else if (!strcmp(token, "connect_timeout"))
parseIntegerValue(&Config.connectTimeout);
parseIntegerValue(&Config.minDirectHops);
else if (!strcmp(token, "store_objects_per_bucket"))
- parseIntegerValue(&Config.storeHash.objectsPerBucket);
+ parseIntegerValue(&Config.Store.objectsPerBucket);
else if (!strcmp(token, "store_avg_object_size"))
- parseIntegerValue(&Config.storeHash.avgObjectSize);
+ parseIntegerValue(&Config.Store.avgObjectSize);
+ else if (!strcmp(token, "maximum_object_size"))
+ parseKilobytes(&Config.Store.maxObjectSize);
/* If unknown, treat as a comment line */
else {
Config.Swap.highWaterMark = DefaultSwapHighWaterMark;
Config.Swap.lowWaterMark = DefaultSwapLowWaterMark;
- Config.Ftp.defaultTtl = DefaultFtpDefaultTtl;
- Config.Ftp.maxObjSize = DefaultFtpMaxObjSize;
- Config.Gopher.defaultTtl = DefaultGopherDefaultTtl;
- Config.Gopher.maxObjSize = DefaultGopherMaxObjSize;
- Config.Http.defaultTtl = DefaultHttpDefaultTtl;
- Config.Http.maxObjSize = DefaultHttpMaxObjSize;
- Config.Wais.defaultTtl = DefaultWaisDefaultTtl;
- Config.Wais.maxObjSize = DefaultWaisMaxObjSize;
Config.Wais.relayHost = safe_xstrdup(DefaultWaisRelayHost);
Config.Wais.relayPort = DefaultWaisRelayPort;
Config.ipcache.low = DefaultIpcacheLow;
Config.ipcache.high = DefaultIpcacheHigh;
Config.minDirectHops = DefaultMinDirectHops;
+ Config.Store.maxObjectSize = DefaultMaxObjectSize;
+ Config.Store.avgObjectSize = DefaultAvgObjectSize;
+ Config.Store.objectsPerBucket = DefaultObjectsPerBucket;
}
static void
/*
- * $Id: client_side.cc,v 1.52 1996/10/27 07:11:52 wessels Exp $
+ * $Id: client_side.cc,v 1.53 1996/10/28 07:44:20 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
icpState->request->flags,
icpState->method);
/* NOTE, don't call storeLockObject(), storeCreateEntry() does it */
+ storeClientListAdd(entry, fd, 0);
entry->lastmod = icpState->old_entry->lastmod;
debug(33, 5, "icpProcessExpired: setting lmt = %d\n",
StoreEntry *oldentry;
debug(33, 3, "icpHandleIMSReply: FD %d '%s'\n", fd, entry->url);
/* unregister this handler */
- storeUnregister(entry, fd);
if (entry->store_status == STORE_ABORTED) {
debug(33, 1, "icpHandleIMSReply: ABORTED/%s '%s'\n",
log_tags[entry->mem_obj->abort_code], entry->url);
/* We have an existing entry, but failed to validate it,
* so send the old one anyway */
- icpState->log_type = LOG_TCP_EXPIRED_FAIL_HIT;
+ icpState->log_type = LOG_TCP_REFRESH_FAIL_HIT;
storeUnlockObject(entry);
+ storeUnregister(entry, fd);
icpState->entry = icpState->old_entry;
icpState->entry->refcount++;
} else if (mem->reply->code == 0) {
(void *) icpState);
return 0;
}
- icpState->log_type = LOG_TCP_EXPIRED_HIT;
+ icpState->log_type = LOG_TCP_REFRESH_HIT;
hbuf = get_free_8k_page();
storeClientCopy(oldentry, 0, 8191, hbuf, &len, fd);
if (oldentry->mem_obj->request == NULL) {
unlink_request = 1;
}
storeUnlockObject(entry);
+ storeUnregister(entry, fd);
entry = icpState->entry = oldentry;
entry->timestamp = squid_curtime;
if (mime_headers_end(hbuf)) {
}
} else {
/* the client can handle this reply, whatever it is */
- icpState->log_type = LOG_TCP_EXPIRED_MISS;
+ icpState->log_type = LOG_TCP_REFRESH_MISS;
if (mem->reply->code == 304) {
icpState->old_entry->timestamp = squid_curtime;
icpState->old_entry->refcount++;
- icpState->log_type = LOG_TCP_EXPIRED_HIT;
+ icpState->log_type = LOG_TCP_REFRESH_HIT;
}
storeUnlockObject(icpState->old_entry);
+ storeUnregister(icpState->old_entry, fd);
}
icpState->old_entry = NULL; /* done with old_entry */
icpSendMoreData(fd, icpState); /* give data to the client */
/*
- * $Id: ftp.cc,v 1.70 1996/10/27 07:11:53 wessels Exp $
+ * $Id: ftp.cc,v 1.71 1996/10/28 07:44:20 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
/* update fdstat and fdtable */
storeComplete(entry);
comm_close(fd);
- } else if (((entry->mem_obj->e_current_len + len) > Config.Ftp.maxObjSize) &&
- !(entry->flag & DELETE_BEHIND)) {
- /* accept data, but start to delete behind it */
- storeStartDeleteBehind(entry);
- storeAppend(entry, buf, len);
- commSetSelect(fd,
- COMM_SELECT_READ,
- (PF) ftpReadReply,
- (void *) data, 0);
} else if (entry->flag & CLIENT_ABORT_REQUEST) {
/* append the last bit of info we get */
storeAppend(entry, buf, len);
/*
- * $Id: gopher.cc,v 1.56 1996/10/27 07:11:55 wessels Exp $
+ * $Id: gopher.cc,v 1.57 1996/10/28 07:44:21 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
BIT_RESET(entry->flag, DELAY_SENDING);
storeComplete(entry);
comm_close(fd);
- } else if (((entry->mem_obj->e_current_len + len) > Config.Gopher.maxObjSize) &&
- !(entry->flag & DELETE_BEHIND)) {
- /* accept data, but start to delete behind it */
- storeStartDeleteBehind(entry);
- if (data->conversion != NORMAL) {
- gopherToHTML(data, buf, len);
- } else {
- storeAppend(entry, buf, len);
- }
- commSetSelect(fd,
- COMM_SELECT_READ,
- (PF) gopherReadReply,
- (void *) data, 0);
- commSetSelect(fd,
- COMM_SELECT_TIMEOUT,
- (PF) gopherReadReplyTimeout,
- (void *) data,
- Config.readTimeout);
} else if (entry->flag & CLIENT_ABORT_REQUEST) {
/* append the last bit of info we got */
if (data->conversion != NORMAL) {
/*
- * $Id: http.cc,v 1.88 1996/10/27 07:11:55 wessels Exp $
+ * $Id: http.cc,v 1.89 1996/10/28 07:44:22 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
httpState->reply_hdr);
/* Parse headers into reply structure */
httpParseHeaders(httpState->reply_hdr, reply);
- timestampsSet(entry);
+ timestampsSet(entry);
/* Check if object is cacheable or not based on reply code */
if (reply->code)
debug(11, 3, "httpProcessReplyHeader: HTTP CODE: %d\n", reply->code);
storeAppend(entry, buf, len); /* invoke handlers! */
storeComplete(entry); /* deallocates mem_obj->request */
comm_close(fd);
- } else if ((entry->mem_obj->e_current_len + len) > Config.Http.maxObjSize &&
- !(entry->flag & DELETE_BEHIND)) {
- /* accept data, but start to delete behind it */
- storeStartDeleteBehind(entry);
- storeAppend(entry, buf, len);
- commSetSelect(fd,
- COMM_SELECT_READ,
- httpReadReply,
- (void *) httpState, 0);
- commSetSelect(fd,
- COMM_SELECT_TIMEOUT,
- httpReadReplyTimeout,
- (void *) httpState, Config.readTimeout);
} else if (entry->flag & CLIENT_ABORT_REQUEST) {
/* append the last bit of info we get */
storeAppend(entry, buf, len);
/*
- * $Id: neighbors.cc,v 1.73 1996/10/27 07:11:58 wessels Exp $
+ * $Id: neighbors.cc,v 1.74 1996/10/28 07:44:24 wessels Exp $
*
* DEBUG: section 15 Neighbor Routines
* AUTHOR: Harvest Derived
}
}
-static void
+static void
neighborCountIgnored(edge * e, icp_opcode op_unused)
{
if (e == NULL)
/*
- * $Id: refresh.cc,v 1.1 1996/10/27 08:40:23 wessels Exp $
+ * $Id: refresh.cc,v 1.2 1996/10/28 07:44:25 wessels Exp $
*
* DEBUG: section 22 Refresh Calculation
* AUTHOR: Harvest Derived
char *pattern = ".";
time_t age;
int factor;
- debug(22,1,"refreshCheck: '%s'\n", entry->url);
+ debug(22, 3, "refreshCheck: '%s'\n", entry->url);
for (R = Refresh_tbl; R; R = R->next) {
if (regexec(&(R->compiled_pattern), entry->url, 0, 0, 0) != 0)
continue;
pattern = R->pattern;
break;
}
- debug(22, 1, "refreshCheck: Matched '%s %d %d%% %d'\n",
+ debug(22, 3, "refreshCheck: Matched '%s %d %d%% %d'\n",
pattern, (int) min, pct, (int) max);
age = squid_curtime - entry->timestamp;
- debug(22,1,"refreshCheck: age = %d\n", (int) age);
+ debug(22, 3, "refreshCheck: age = %d\n", (int) age);
if (age <= min) {
- debug(22,1,"refreshCheck: NO: age < min\n");
+ debug(22, 3, "refreshCheck: NO: age < min\n");
return 0;
}
if (-1 < entry->expires && entry->expires <= squid_curtime) {
- debug(22,1,"refreshCheck: YES: expires <= curtime\n");
+ debug(22, 3, "refreshCheck: YES: expires <= curtime\n");
return 1;
}
if (age > max) {
- debug(22,1,"refreshCheck: YES: age > max\n");
+ debug(22, 3, "refreshCheck: YES: age > max\n");
return 1;
}
if (entry->timestamp <= entry->lastmod) {
- debug(22,1,"refreshCheck: YES: lastvalid <= lastmod\n");
+ debug(22, 3, "refreshCheck: YES: lastvalid <= lastmod\n");
return 1;
}
factor = 100 * age / (entry->timestamp - entry->lastmod);
- debug(22,1,"refreshCheck: factor = %d\n", factor);
+ debug(22, 3, "refreshCheck: factor = %d\n", factor);
if (factor > pct) {
- debug(22,1,"refreshCheck: YES: factor > pc\n");
+ debug(22, 3, "refreshCheck: YES: factor > pc\n");
return 1;
}
return 0;
/*
- * $Id: stat.cc,v 1.94 1996/10/27 07:12:00 wessels Exp $
+ * $Id: stat.cc,v 1.95 1996/10/28 07:44:27 wessels Exp $
*
* DEBUG: section 18 Cache Manager Statistics
* AUTHOR: Harvest Derived
storeAppendPrintf(sentry,
"{Swap-Low %d \"# Low water mark disk cache (%%)\"}\n",
Config.Swap.lowWaterMark);
- storeAppendPrintf(sentry,
- "{HTTP-Max %d\"# Maximum size HTTP objects (KB)\"}\n",
- Config.Http.maxObjSize / (1 << 10));
- storeAppendPrintf(sentry,
- "{HTTP-TTL %d \"# Http object default TTL (hrs)\"}\n",
- Config.Http.defaultTtl / 3600);
- storeAppendPrintf(sentry,
- "{Gopher-Max %d \"# Maximum size gopher objects (KB)\"}\n",
- Config.Gopher.maxObjSize / (1 << 10));
- storeAppendPrintf(sentry,
- "{Gopher-TTL %d \"# TTL for gopher objects (hrs)\"}\n",
- Config.Gopher.defaultTtl / 3600);
- storeAppendPrintf(sentry,
- "{FTP-Max %d \"# Maximum size FTP objects (KB)\"}\n",
- Config.Ftp.maxObjSize / (1 << 10));
- storeAppendPrintf(sentry,
- "{FTP-TTL %d \"# TTL for FTP objects (hrs)\"}\n",
- Config.Ftp.defaultTtl / 3600);
storeAppendPrintf(sentry,
"{Neg-TTL %d \"# TTL for negative cache (s)\"}\n",
Config.negativeTtl);
switch (type) {
case LOG_TCP_HIT:
case LOG_TCP_IMS_HIT:
- case LOG_TCP_EXPIRED_HIT:
- case LOG_TCP_EXPIRED_FAIL_HIT:
+ case LOG_TCP_REFRESH_HIT:
+ case LOG_TCP_REFRESH_FAIL_HIT:
case LOG_UDP_HIT:
case LOG_UDP_HIT_OBJ:
obj->proto_stat_data[proto_id].hit++;
/*
- * $Id: stmem.cc,v 1.30 1996/10/10 18:48:52 wessels Exp $
+ * $Id: stmem.cc,v 1.31 1996/10/28 07:44:27 wessels Exp $
*
* DEBUG: section 19 Memory Primitives
* AUTHOR: Harvest Derived
return current_offset;
}
if (current_offset != target_offset) {
- debug(19, 1, "memFreeDataBehind: This shouldn't happen. Some odd condition.\n");
+ debug(19, 1, "memFreeDataUpto: This shouldn't happen. Some odd condition.\n");
debug(19, 1, " Current offset: %d Target offset: %d p: %p\n",
current_offset, target_offset, p);
}
return current_offset;
-
}
/*
- * $Id: store.cc,v 1.141 1996/10/27 07:12:01 wessels Exp $
+ * $Id: store.cc,v 1.142 1996/10/28 07:44:28 wessels Exp $
*
* DEBUG: section 20 Storeage Manager
* AUTHOR: Harvest Derived
#define STORE_LOG_SWAPOUT 2
#define STORE_LOG_RELEASE 3
+#define ENTRY_INMEM_SIZE(X) ((X)->e_current_len - (X)->e_lowest_offset)
+
static char *storeLogTags[] =
{
"CREATE",
static int storeCopy _PARAMS((StoreEntry *, int, int, char *, int *));
static int storeEntryLocked _PARAMS((StoreEntry *));
static int storeEntryValidLength _PARAMS((StoreEntry *));
-static int storeGetMemSpace _PARAMS((int));
+static void storeGetMemSpace _PARAMS((int));
static int storeHashDelete _PARAMS((StoreEntry *));
static int storeShouldPurgeMem _PARAMS((StoreEntry *));
static int storeSwapInHandle _PARAMS((int, char *, int, int, StoreEntry *, int));
static void destroy_MemObject _PARAMS((MemObject *));
static void destroy_MemObjectData _PARAMS((MemObject *));
static void destroy_StoreEntry _PARAMS((StoreEntry *));
-static void storeClientListAdd _PARAMS((StoreEntry *, int, int));
static void storeDeleteBehind _PARAMS((StoreEntry *));
static void storePurgeMem _PARAMS((StoreEntry *));
static void storeSanityCheck _PARAMS((void));
static int store_pages_high = 0;
static int store_pages_low = 0;
+static int store_pages_over_high = 0;
/* current file name, swap file, use number as a filename */
static int swapfileno = 0;
{
debug(20, 3, "destroy_MemObjectData: destroying %p, %d bytes\n",
mem->data, mem->e_current_len);
- store_mem_size -= mem->e_current_len - mem->e_lowest_offset;
+ store_mem_size -= ENTRY_INMEM_SIZE(mem);
if (mem->data) {
mem->data->mem_free(mem->data);
mem->data = NULL;
if (storelog_fd < 0)
return;
if (-1 < e->expires)
- t = e->expires - squid_curtime;
+ t = e->expires - squid_curtime;
if (e->mem_obj) {
code = e->mem_obj->reply->code;
expect_len = (int) e->mem_obj->reply->content_length;
int i;
int j;
MemObject *mem = e->mem_obj;
-
debug(20, 3, "storeRegister: FD %d '%s'\n", fd, e->key);
-
pe = xcalloc(1, sizeof(PendingEntry));
pe->fd = fd;
pe->handler = handler;
pe->data = data;
-
- /*
- * I've rewritten all this pendings stuff so that num_pending goes
- * away, and to fix all of the 'array bounds' problems we were having.
- * It's now a very simple array, with any NULL slot empty/avail.
- * If something needs to be added and there are no empty slots,
- * it'll grow the array.
- */
/* find an empty slot */
for (i = 0; i < (int) mem->pending_list_size; i++) {
if (mem->pending[i] == NULL)
break;
}
-
if (i == mem->pending_list_size) {
/* grow the array */
struct pentry **tmp = NULL;
-
old_size = mem->pending_list_size;
-
/* set list_size to an appropriate amount */
mem->pending_list_size += MIN_PENDING;
-
/* allocate, and copy old pending list over to the new one */
tmp = xcalloc(mem->pending_list_size, sizeof(struct pentry *));
for (j = 0; j < old_size; j++)
tmp[j] = mem->pending[j];
-
/* free the old list and set the new one */
safe_free(mem->pending);
mem->pending = tmp;
-
debug(20, 9, "storeRegister: grew pending list to %d for slot %d.\n",
mem->pending_list_size, i);
}
int i;
int freed = 0;
MemObject *mem = e->mem_obj;
- debug(20, 9, "storeUnregister: called for FD %d '%s'\n", fd, e->key);
+ if (mem == NULL)
+ return 0;
+ debug(20, 3, "storeUnregister: called for FD %d '%s'\n", fd, e->key);
/* look for entry in client_list */
if ((i = storeClientListSearch(mem, fd)) > -1) {
safe_free(mem->client_list[i]);
storeDeleteBehind(StoreEntry * e)
{
MemObject *mem = e->mem_obj;
- int free_up_to;
- int target_offset;
-
- debug(20, 3, "storeDeleteBehind: Object: %s\n", e->key);
- debug(20, 3, "storeDeleteBehind: Original Lowest Offset: %d\n",
- mem->e_lowest_offset);
-
- free_up_to = mem->e_lowest_offset;
- target_offset = storeGetLowestReaderOffset(e);
-
- debug(20, 3, "storeDeleteBehind: target offset: %d\n", target_offset);
- if (target_offset) {
- free_up_to = (int) mem->data->mem_free_data_upto(mem->data, target_offset);
- debug(20, 3, "--> Object is freed upto : %d\n", free_up_to);
- store_mem_size -= free_up_to - mem->e_lowest_offset;
- }
- debug(20, 3, "storeDeleteBehind: New lowest offset: %d\n", free_up_to);
- mem->e_lowest_offset = free_up_to;
+ int old_lowest_offset = mem->e_lowest_offset;
+ int new_lowest_offset;
+ int target_offset = storeGetLowestReaderOffset(e);
+ if (target_offset == 0)
+ return;
+ new_lowest_offset = (int) mem->data->mem_free_data_upto(mem->data,
+ target_offset);
+ store_mem_size -= new_lowest_offset - old_lowest_offset;
+ mem->e_lowest_offset = new_lowest_offset;
}
/* Call handlers waiting for data to be appended to E. */
void
storeStartDeleteBehind(StoreEntry * e)
{
- debug(20, 2, "storeStartDeleteBehind: Object: %s\n", e->key);
if (BIT_TEST(e->flag, DELETE_BEHIND))
return;
- debug(20, 2, "storeStartDeleteBehind:is now in delete behind mode.\n");
- /* change its key, so it can't be found by another client */
+ debug(20, 1, "storeStartDeleteBehind: '%s' at %d bytes\n", e->url,
+ e->mem_obj->e_current_len);
storeSetPrivateKey(e);
BIT_SET(e->flag, DELETE_BEHIND);
storeReleaseRequest(e);
void
storeAppend(StoreEntry * e, char *data, int len)
{
+ MemObject *mem;
/* sanity check */
if (e == NULL) {
debug_trap("storeAppend: NULL entry.");
return;
- } else if (e->mem_obj == NULL) {
+ } else if ((mem = e->mem_obj) == NULL) {
debug_trap("storeAppend: NULL entry->mem_obj");
return;
- } else if (e->mem_obj->data == NULL) {
+ } else if (mem->data == NULL) {
debug_trap("storeAppend: NULL entry->mem_obj->data");
return;
}
if (len) {
debug(20, 5, "storeAppend: appending %d bytes for '%s'\n", len, e->key);
- (void) storeGetMemSpace(len);
+ storeGetMemSpace(len);
+ if (store_pages_over_high) {
+ if (mem->e_current_len > Config.Store.maxObjectSize)
+ storeStartDeleteBehind(e);
+ }
store_mem_size += len;
- (void) e->mem_obj->data->mem_append(e->mem_obj->data, data, len);
- e->mem_obj->e_current_len += len;
+ (void) mem->data->mem_append(mem->data, data, len);
+ mem->e_current_len += len;
}
if (e->store_status != STORE_ABORTED && !BIT_TEST(e->flag, DELAY_SENDING))
InvokeHandlers(e);
if (store_rebuilding != STORE_REBUILDING_FAST) {
if (stat(swapfile, &sb) < 0) {
- debug(20, 3, "storeRebuildFromDisk: Swap file missing: <URL:%s>: %s: %s.\n", url, swapfile, xstrerror());
- if (opt_unlink_on_reload)
- safeunlink(swapfile, 1);
+ debug(20, 3, "storeRebuildFromDisk: Swap file missing: <URL:%s>: %s: %s.\n", url, swapfile, xstrerror());
+ if (opt_unlink_on_reload)
+ safeunlink(swapfile, 1);
continue;
}
/* Empty swap file? */
} else if (BIT_TEST(e->flag, ENTRY_NEGCACHED)) {
debug(20, 2, "storeCheckSwapable: NO: negative cached\n");
return 0; /* avoid release call below */
+ } else if (e->mem_obj->e_current_len > Config.Store.maxObjectSize) {
+ debug(20, 2, "storeCheckSwapable: NO: too big\n");
} else {
return 1;
}
/* Clear Memory storage to accommodate the given object len */
-static int
+static void
storeGetMemSpace(int size)
{
StoreEntry *e = NULL;
int pages_needed;
if (squid_curtime == last_check)
- return 0;
+ return;
last_check = squid_curtime;
pages_needed = (size / SM_PAGE_SIZE) + 1;
if (sm_stats.n_pages_in_use + pages_needed < sm_stats.max_pages)
- return 0;
+ return;
if (store_rebuilding == STORE_REBUILDING_FAST)
- return 0;
+ return;
debug(20, 2, "storeGetMemSpace: Starting, need %d pages\n", pages_needed);
list = xcalloc(meta_data.mem_obj_count, sizeof(ipcache_entry *));
i = 3;
if (sm_stats.n_pages_in_use + pages_needed > store_pages_high) {
+ store_pages_over_high = 1;
if (squid_curtime - last_warning > 600) {
debug(20, 0, "WARNING: Over store_pages high-water mark (%d > %d)\n",
sm_stats.n_pages_in_use + pages_needed, store_pages_high);
debug(20, 0, "Perhaps you should increase cache_mem?\n");
i = 0;
}
+ } else {
+ store_pages_over_high = 0;
}
debug(20, i, "storeGetMemSpace stats:\n");
debug(20, i, " %6d objects locked in memory\n", n_locked);
debug(20, i, " %6d were purged\n", n_purged);
debug(20, i, " %6d were released\n", n_released);
xfree(list);
- return 0;
}
static int
if (e->method == METHOD_GET) {
hkey = storeGeneratePublicKey(e->url, METHOD_HEAD);
if ((hentry = (StoreEntry *) hash_lookup(store_table, hkey)))
- storeExpireNow(hentry);
+ storeExpireNow(hentry);
}
if (store_rebuilding == STORE_REBUILDING_FAST) {
debug(20, 2, "storeRelease: Delaying release until store is rebuilt: '%s'\n",
}
/* add client with fd to client list */
-static void
+void
storeClientListAdd(StoreEntry * e, int fd, int last_offset)
{
int i;
/* same to storeCopy but also register client fd and last requested offset
* for each client */
int
-storeClientCopy(StoreEntry * e, int stateoffset, int maxSize, char *buf, int *size, int fd)
-{
- int next_offset;
- int client_list_index;
- int available_to_write = e->mem_obj->e_current_len - stateoffset;
+storeClientCopy(StoreEntry * e,
+ int stateoffset,
+ int maxSize,
+ char *buf,
+ int *size,
+ int fd)
+{
+ int ci;
+ int sz;
MemObject *mem = e->mem_obj;
-
+ int available_to_write = mem->e_current_len - stateoffset;
if (stateoffset < mem->e_lowest_offset) {
- /* this should not happen. Logic race !!! */
- debug(20, 1, "storeClientCopy: Client Request a chunk of data in area lower than the lowest_offset\n");
- debug(20, 1, " fd : %d\n", fd);
- debug(20, 1, " Current Lowest offset : %d\n", mem->e_lowest_offset);
- debug(20, 1, " Requested offset : %d\n", stateoffset);
- /* can't really do anything here. Client may hang until lifetime runout. */
+ debug_trap("storeClientCopy: requested offst < lowest offset");
+ debug(20, 0, "--> '%s'\n", e->url);
+ *size = 0;
return 0;
}
- *size = (available_to_write >= maxSize) ? maxSize : available_to_write;
-
- debug(20, 6, "storeCopy: avail_to_write=%d, store_offset=%d\n",
- *size, stateoffset);
-
- /* update the lowest requested offset */
- next_offset = (stateoffset + *size);
- if ((client_list_index = storeClientListSearch(mem, fd)) >= 0) {
- mem->client_list[client_list_index]->last_offset = next_offset;
- } else {
- storeClientListAdd(e, fd, next_offset);
+ if ((ci = storeClientListSearch(mem, fd)) < 0) {
+ debug_trap("storeClientCopy: Unregistered client");
+ debug(20, 0, "--> '%s'\n", e->url);
+ *size = 0;
+ return 0;
}
-
- if (*size > 0)
- (void) mem->data->mem_copy(mem->data, stateoffset, buf, *size);
-
+ sz = (available_to_write >= maxSize) ? maxSize : available_to_write;
+ /* update the lowest requested offset */
+ mem->client_list[ci]->last_offset = stateoffset + sz;
+ if (sz > 0)
+ (void) mem->data->mem_copy(mem->data, stateoffset, buf, sz);
/* see if we can get rid of some data if we are in "delete behind" mode . */
- if (BIT_TEST(e->flag, DELETE_BEHIND)) {
- /* call the handler to delete behind the lowest offset */
+ if (BIT_TEST(e->flag, DELETE_BEHIND))
storeDeleteBehind(e);
- }
- return *size;
+ *size = sz;
+ return sz;
}
static int
{
int i;
/* Calculate size of hash table (maximum currently 64k buckets). */
- i = Config.Swap.maxSize / Config.storeHash.avgObjectSize;
+ i = Config.Swap.maxSize / Config.Store.avgObjectSize;
debug(20, 1, "Swap maxSize %d, estimated %d objects\n",
Config.Swap.maxSize, i);
- i /= Config.storeHash.objectsPerBucket;
+ 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. */
/*
- * $Id: wais.cc,v 1.46 1996/10/11 23:11:19 wessels Exp $
+ * $Id: wais.cc,v 1.47 1996/10/28 07:44:30 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
entry->expires = squid_curtime;
storeComplete(entry);
comm_close(fd);
- } else if (((entry->mem_obj->e_current_len + len) > Config.Wais.maxObjSize) &&
- !(entry->flag & DELETE_BEHIND)) {
- /* accept data, but start to delete behind it */
- storeStartDeleteBehind(entry);
- storeAppend(entry, buf, len);
- commSetSelect(fd,
- COMM_SELECT_READ,
- (PF) waisReadReply,
- (void *) waisState, 0);
- commSetSelect(fd,
- COMM_SELECT_TIMEOUT,
- (PF) waisReadReplyTimeout,
- (void *) waisState,
- Config.readTimeout);
} else {
storeAppend(entry, buf, len);
commSetSelect(fd,