408
404
/* ----- INTERFACE BETWEEN STORAGE MANAGER AND HASH TABLE FUNCTIONS --------- */
411
storeHashInsert(StoreEntry * e, const cache_key * key)
407
StoreEntry::hashInsert(const cache_key * someKey)
413
debug(20, 3) ("storeHashInsert: Inserting Entry %p key '%s'\n",
414
e, storeKeyText(key));
415
e->key = storeKeyDup(key);
416
hash_join(store_table, e);
409
debugs(20, 3, "StoreEntry::hashInsert: Inserting Entry " << this << " key '" << storeKeyText(someKey) << "'");
410
key = storeKeyDup(someKey);
411
hash_join(store_table, this);
420
storeHashDelete(StoreEntry * e)
415
StoreEntry::hashDelete()
422
hash_remove_link(store_table, e);
423
storeKeyFree((const cache_key *)e->key);
417
hash_remove_link(store_table, this);
418
storeKeyFree((const cache_key *)key);
427
422
/* -------------------------------------------------------------------------- */
430
425
/* get rid of memory copy of the object */
432
storePurgeMem(StoreEntry * e)
427
StoreEntry::purgeMem()
434
if (e->mem_obj == NULL)
437
debug(20, 3) ("storePurgeMem: Freeing memory-copy of %s\n",
440
destroy_MemObject(e);
442
if (e->swap_status != SWAPOUT_DONE)
432
debugs(20, 3, "StoreEntry::purgeMem: Freeing memory-copy of " << getMD5Text());
436
if (swap_status != SWAPOUT_DONE)
446
440
/* RBC 20050104 this is wrong- memory ref counting
610
storeSetPrivateKey(StoreEntry * e)
603
StoreEntry::setPrivateKey()
612
605
const cache_key *newkey;
613
MemObject *mem = e->mem_obj;
615
if (e->key && EBIT_TEST(e->flags, KEY_PRIVATE))
607
if (key && EBIT_TEST(flags, KEY_PRIVATE))
616
608
return; /* is already private */
619
if (e->swap_filen > -1)
620
storeDirSwapLog(e, SWAP_LOG_DEL);
612
storeDirSwapLog(this, SWAP_LOG_DEL);
626
mem->id = getKeyCounter();
627
newkey = storeKeyPrivate(mem->url, mem->method, mem->id);
617
if (mem_obj != NULL) {
618
mem_obj->id = getKeyCounter();
619
newkey = storeKeyPrivate(mem_obj->url, mem_obj->method, mem_obj->id);
629
621
newkey = storeKeyPrivate("JUNK", METHOD_NONE, getKeyCounter());
632
624
assert(hash_lookup(store_table, newkey) == NULL);
633
EBIT_SET(e->flags, KEY_PRIVATE);
634
storeHashInsert(e, newkey);
625
EBIT_SET(flags, KEY_PRIVATE);
638
storeSetPublicKey(StoreEntry * e)
630
StoreEntry::setPublicKey()
640
632
StoreEntry *e2 = NULL;
641
633
const cache_key *newkey;
642
MemObject *mem = e->mem_obj;
644
if (e->key && !EBIT_TEST(e->flags, KEY_PRIVATE))
635
if (key && !EBIT_TEST(flags, KEY_PRIVATE))
645
636
return; /* is already public */
650
641
* We can't make RELEASE_REQUEST objects public. Depending on
654
645
* been freed from memory.
656
647
* If RELEASE_REQUEST is set, then ENTRY_CACHABLE should not
657
* be set, and storeSetPublicKey() should not be called.
648
* be set, and StoreEntry::setPublicKey() should not be called.
659
650
#if MORE_DEBUG_OUTPUT
661
if (EBIT_TEST(e->flags, RELEASE_REQUEST))
662
debug(20, 1) ("assertion failed: RELEASE key %s, url %s\n",
652
if (EBIT_TEST(flags, RELEASE_REQUEST))
653
debugs(20, 1, "assertion failed: RELEASE key " << key << ", url " << mem->url);
667
assert(!EBIT_TEST(e->flags, RELEASE_REQUEST));
670
HttpRequest *request = mem->request;
672
if (!mem->vary_headers) {
657
assert(!EBIT_TEST(flags, RELEASE_REQUEST));
659
if (mem_obj->request) {
660
HttpRequest *request = mem_obj->request;
662
if (!mem_obj->vary_headers) {
673
663
/* First handle the case where the object no longer varies */
674
664
safe_free(request->vary_headers);
676
if (request->vary_headers && strcmp(request->vary_headers, mem->vary_headers) != 0) {
666
if (request->vary_headers && strcmp(request->vary_headers, mem_obj->vary_headers) != 0) {
677
667
/* Oops.. the variance has changed. Kill the base object
678
668
* to record the new variance key
680
670
safe_free(request->vary_headers); /* free old "bad" variance key */
681
StoreEntry *pe = storeGetPublic(mem->url, mem->method);
671
StoreEntry *pe = storeGetPublic(mem_obj->url, mem_obj->method);
687
677
/* Make sure the request knows the variance status */
688
678
if (!request->vary_headers) {
689
const char *vary = httpMakeVaryMark(request, mem->getReply());
679
const char *vary = httpMakeVaryMark(request, mem_obj->getReply());
692
682
request->vary_headers = xstrdup(vary);
696
if (mem->vary_headers && !storeGetPublic(mem->url, mem->method)) {
686
if (mem_obj->vary_headers && !storeGetPublic(mem_obj->url, mem_obj->method)) {
697
687
/* Create "vary" base object */
699
StoreEntry *pe = storeCreateEntry(mem->url, mem->log_url, request->flags, request->method);
689
StoreEntry *pe = storeCreateEntry(mem_obj->url, mem_obj->log_url, request->flags, request->method);
700
690
HttpVersion version(1, 0);
701
691
/* We are allowed to do this typecast */
702
692
HttpReply *rep = new HttpReply;
703
693
rep->setHeaders(version, HTTP_OK, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
704
vary = mem->getReply()->header.getList(HDR_VARY);
694
vary = mem_obj->getReply()->header.getList(HDR_VARY);
706
696
if (vary.size()) {
707
697
/* Again, we own this structure layout */
953
storeCheckTooSmall(StoreEntry * e)
936
StoreEntry::checkTooSmall()
955
MemObject * const mem = e->mem_obj;
957
if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
938
if (EBIT_TEST(flags, ENTRY_SPECIAL))
960
if (STORE_OK == e->store_status)
961
if (mem->object_sz < 0 ||
962
static_cast<size_t>(mem->object_sz)
941
if (STORE_OK == store_status)
942
if (mem_obj->object_sz < 0 ||
943
static_cast<size_t>(mem_obj->object_sz)
963
944
< Config.Store.minObjectSize)
966
->content_length > -1)
968
->content_length < (int) Config.Store.minObjectSize)
946
if (getReply()->content_length > -1)
947
if (getReply()->content_length < (int) Config.Store.minObjectSize)
974
storeCheckCachable(StoreEntry * e)
953
StoreEntry::checkCachable()
976
955
#if CACHE_ALL_METHODS
978
if (e->mem_obj->method != METHOD_GET) {
979
debug(20, 2) ("storeCheckCachable: NO: non-GET method\n");
957
if (mem_obj->method != METHOD_GET) {
958
debugs(20, 2, "StoreEntry::checkCachable: NO: non-GET method");
980
959
store_check_cachable_hist.no.non_get++;
983
if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
984
debug(20, 2) ("storeCheckCachable: NO: wrong content-length\n");
962
if (store_status == STORE_OK && EBIT_TEST(flags, ENTRY_BAD_LENGTH)) {
963
debugs(20, 2, "StoreEntry::checkCachable: NO: wrong content-length");
985
964
store_check_cachable_hist.no.wrong_content_length++;
986
} else if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) {
987
debug(20, 2) ("storeCheckCachable: NO: not cachable\n");
965
} else if (!EBIT_TEST(flags, ENTRY_CACHABLE)) {
966
debugs(20, 2, "StoreEntry::checkCachable: NO: not cachable");
988
967
store_check_cachable_hist.no.not_entry_cachable++;
989
} else if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {
990
debug(20, 3) ("storeCheckCachable: NO: negative cached\n");
968
} else if (EBIT_TEST(flags, ENTRY_NEGCACHED)) {
969
debugs(20, 3, "StoreEntry::checkCachable: NO: negative cached");
991
970
store_check_cachable_hist.no.negative_cached++;
992
971
return 0; /* avoid release call below */
993
} else if ((e->getReply()->content_length > 0 &&
994
static_cast<size_t>(e->getReply()->content_length)
972
} else if ((getReply()->content_length > 0 &&
973
static_cast<size_t>(getReply()->content_length)
995
974
> Config.Store.maxObjectSize) ||
996
static_cast<size_t>(e->mem_obj->endOffset()) > Config.Store.maxObjectSize) {
997
debug(20, 2) ("storeCheckCachable: NO: too big\n");
998
store_check_cachable_hist.no.too_big++;
999
} else if (e->getReply()->content_length > (int) Config.Store.maxObjectSize) {
1001
("storeCheckCachable: NO: too big\n");
1002
store_check_cachable_hist.no.too_big++;
1003
} else if (storeCheckTooSmall(e)) {
1005
("storeCheckCachable: NO: too small\n");
975
static_cast<size_t>(mem_obj->endOffset()) > Config.Store.maxObjectSize) {
976
debugs(20, 2, "StoreEntry::checkCachable: NO: too big");
977
store_check_cachable_hist.no.too_big++;
978
} else if (getReply()->content_length > (int) Config.Store.maxObjectSize) {
979
debugs(20, 2, "StoreEntry::checkCachable: NO: too big");
980
store_check_cachable_hist.no.too_big++;
981
} else if (checkTooSmall()) {
982
debugs(20, 2, "StoreEntry::checkCachable: NO: too small");
1006
983
store_check_cachable_hist.no.too_small++;
1007
} else if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
1009
("storeCheckCachable: NO: private key\n");
984
} else if (EBIT_TEST(flags, KEY_PRIVATE)) {
985
debugs(20, 3, "StoreEntry::checkCachable: NO: private key");
1010
986
store_check_cachable_hist.no.private_key++;
1011
} else if (e->swap_status != SWAPOUT_NONE) {
987
} else if (swap_status != SWAPOUT_NONE) {
1013
989
* here we checked the swap_status because the remaining
1014
990
* cases are only relevant only if we haven't started swapping
1382
1360
const HttpReply *reply;
1383
1361
assert(mem_obj != NULL);
1384
1362
reply = getReply();
1385
debug(20, 3) ("storeEntryValidLength: Checking '%s'\n", getMD5Text());
1363
debugs(20, 3, "storeEntryValidLength: Checking '" << getMD5Text() << "'");
1386
1364
debugs(20, 5, "storeEntryValidLength: object_len = " <<
1388
debug(20, 5) ("storeEntryValidLength: hdr_sz = %d\n",
1390
debug(20, 5) ("storeEntryValidLength: content_length = %d\n",
1391
reply->content_length);
1366
debugs(20, 5, "storeEntryValidLength: hdr_sz = " << reply->hdr_sz);
1367
debugs(20, 5, "storeEntryValidLength: content_length = " << reply->content_length);
1393
1369
if (reply->content_length < 0) {
1394
debug(20, 5) ("storeEntryValidLength: Unspecified content length: %s\n",
1370
debugs(20, 5, "storeEntryValidLength: Unspecified content length: " << getMD5Text());
1399
1374
if (reply->hdr_sz == 0) {
1400
debug(20, 5) ("storeEntryValidLength: Zero header size: %s\n",
1375
debugs(20, 5, "storeEntryValidLength: Zero header size: " << getMD5Text());
1405
1379
if (mem_obj->method == METHOD_HEAD) {
1406
debug(20, 5) ("storeEntryValidLength: HEAD request: %s\n",
1380
debugs(20, 5, "storeEntryValidLength: HEAD request: " << getMD5Text());
1567
1535
if (squid_curtime > age)
1568
1536
served_date = squid_curtime - age;
1570
entry->expires = reply->expires;
1572
entry->lastmod = reply->last_modified;
1574
entry->timestamp = served_date;
1578
storeRegisterAbort(StoreEntry * e, STABH * cb, void *data)
1580
MemObject *mem = e->mem_obj;
1582
assert(mem->abort.callback == NULL);
1583
mem->abort.callback = cb;
1584
mem->abort.data = data;
1588
storeUnregisterAbort(StoreEntry * e)
1590
MemObject *mem = e->mem_obj;
1592
mem->abort.callback = NULL;
1596
storeEntryDump(const StoreEntry * e, int l)
1598
debug(20, l) ("StoreEntry->key: %s\n", e->getMD5Text());
1599
debug(20, l) ("StoreEntry->next: %p\n", e->next);
1600
debug(20, l) ("StoreEntry->mem_obj: %p\n", e->mem_obj);
1601
debug(20, l) ("StoreEntry->timestamp: %d\n", (int) e->timestamp);
1602
debug(20, l) ("StoreEntry->lastref: %d\n", (int) e->lastref);
1603
debug(20, l) ("StoreEntry->expires: %d\n", (int) e->expires);
1604
debug(20, l) ("StoreEntry->lastmod: %d\n", (int) e->lastmod);
1605
debug(20, l) ("StoreEntry->swap_file_sz: %d\n", (int) e->swap_file_sz);
1606
debug(20, l) ("StoreEntry->refcount: %d\n", e->refcount);
1607
debug(20, l) ("StoreEntry->flags: %s\n", storeEntryFlags(e));
1608
debug(20, l) ("StoreEntry->swap_dirn: %d\n", (int) e->swap_dirn);
1609
debug(20, l) ("StoreEntry->swap_filen: %d\n", (int) e->swap_filen);
1610
debug(20, l) ("StoreEntry->lock_count: %d\n", (int) e->lock_count);
1611
debug(20, l) ("StoreEntry->mem_status: %d\n", (int) e->mem_status);
1612
debug(20, l) ("StoreEntry->ping_status: %d\n", (int) e->ping_status);
1613
debug(20, l) ("StoreEntry->store_status: %d\n", (int) e->store_status);
1614
debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);
1538
if (reply->expires > 0 && reply->date > -1)
1539
expires = served_date + (reply->expires - reply->date);
1541
expires = reply->expires;
1543
lastmod = reply->last_modified;
1545
timestamp = served_date;
1549
StoreEntry::registerAbort(STABH * cb, void *data)
1552
assert(mem_obj->abort.callback == NULL);
1553
mem_obj->abort.callback = cb;
1554
mem_obj->abort.data = cbdataReference(data);
1558
StoreEntry::unregisterAbort()
1561
if (mem_obj->abort.callback) {
1562
mem_obj->abort.callback = NULL;
1563
cbdataReferenceDone(mem_obj->abort.data);
1568
StoreEntry::dump(int l) const
1570
debugs(20, l, "StoreEntry->key: " << getMD5Text());
1571
debugs(20, l, "StoreEntry->next: " << next);
1572
debugs(20, l, "StoreEntry->mem_obj: " << mem_obj);
1573
debugs(20, l, "StoreEntry->timestamp: " << timestamp);
1574
debugs(20, l, "StoreEntry->lastref: " << lastref);
1575
debugs(20, l, "StoreEntry->expires: " << expires);
1576
debugs(20, l, "StoreEntry->lastmod: " << lastmod);
1577
debugs(20, l, "StoreEntry->swap_file_sz: " << swap_file_sz);
1578
debugs(20, l, "StoreEntry->refcount: " << refcount);
1579
debugs(20, l, "StoreEntry->flags: " << storeEntryFlags(this));
1580
debugs(20, l, "StoreEntry->swap_dirn: " << swap_dirn);
1581
debugs(20, l, "StoreEntry->swap_filen: " << swap_filen);
1582
debugs(20, l, "StoreEntry->lock_count: " << lock_count);
1583
debugs(20, l, "StoreEntry->mem_status: " << mem_status);
1584
debugs(20, l, "StoreEntry->ping_status: " << ping_status);
1585
debugs(20, l, "StoreEntry->store_status: " << store_status);
1586
debugs(20, l, "StoreEntry->swap_status: " << swap_status);
1618
1590
* NOTE, this function assumes only two mem states
1621
storeSetMemStatus(StoreEntry * e, mem_status_t new_status)
1593
StoreEntry::setMemStatus(mem_status_t new_status)
1623
MemObject *mem = e->mem_obj;
1625
if (new_status == e->mem_status)
1595
if (new_status == mem_status)
1628
assert(mem != NULL);
1598
assert(mem_obj != NULL);
1630
1600
if (new_status == IN_MEMORY) {
1631
assert(mem->inmem_lo == 0);
1601
assert(mem_obj->inmem_lo == 0);
1633
if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
1634
debug(20, 4) ("storeSetMemStatus: not inserting special %s into policy\n",
1603
if (EBIT_TEST(flags, ENTRY_SPECIAL)) {
1604
debugs(20, 4, "StoreEntry::setMemStatus: not inserting special " << mem_obj->url << " into policy");
1637
mem_policy->Add(mem_policy, e, &mem->repl);
1638
debug(20, 4) ("storeSetMemStatus: inserted mem node %s\n",
1606
mem_policy->Add(mem_policy, this, &mem_obj->repl);
1607
debugs(20, 4, "StoreEntry::setMemStatus: inserted mem node " << mem_obj->url);
1642
1610
hot_obj_count++;
1644
if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
1645
debug(20, 4) ("storeSetMemStatus: special entry %s\n",
1612
if (EBIT_TEST(flags, ENTRY_SPECIAL)) {
1613
debugs(20, 4, "StoreEntry::setMemStatus: special entry " << mem_obj->url);
1648
mem_policy->Remove(mem_policy, e, &mem->repl);
1649
debug(20, 4) ("storeSetMemStatus: removed mem node %s\n",
1615
mem_policy->Remove(mem_policy, this, &mem_obj->repl);
1616
debugs(20, 4, "StoreEntry::setMemStatus: removed mem node " << mem_obj->url);
1653
1619
hot_obj_count--;
1656
e->mem_status = new_status;
1622
mem_status = new_status;
1660
storeUrl(const StoreEntry * e)
1626
StoreEntry::url() const
1663
1629
return "[null_entry]";
1664
else if (e->mem_obj == NULL)
1630
else if (mem_obj == NULL)
1665
1631
return "[null_mem_obj]";
1667
return e->mem_obj->url;
1633
return mem_obj->url;
1671
storeCreateMemObject(StoreEntry * e, const char *url, const char *log_url)
1637
StoreEntry::createMemObject(const char *url, const char *log_url)
1676
e->mem_obj = new MemObject(url, log_url);
1679
/* DEPRECATED: please use entry->buffer() */
1681
storeBuffer(StoreEntry * e)
1642
mem_obj = new MemObject(url, log_url);
1686
1645
/* this just sets DELAY_SENDING */
1931
1881
object_length = getReply()->content_length;
1933
1883
if (object_length < 0)
1934
object_length = contentLen(this);
1884
object_length = contentLen();
1936
1886
if (mod_time > request->ims) {
1937
debug(88, 3) ("--> YES: entry newer than client\n");
1887
debugs(88, 3, "--> YES: entry newer than client");
1939
1889
} else if (mod_time < request->ims) {
1940
debug(88, 3) ("--> NO: entry older than client\n");
1890
debugs(88, 3, "--> NO: entry older than client");
1942
1892
} else if (request->imslen < 0) {
1943
debug(88, 3) ("--> NO: same LMT, no client length\n");
1893
debugs(88, 3, "--> NO: same LMT, no client length");
1945
1895
} else if (request->imslen == object_length) {
1946
debug(88, 3) ("--> NO: same LMT, same length\n");
1896
debugs(88, 3, "--> NO: same LMT, same length");
1949
debug(88, 3) ("--> YES: same LMT, different length\n");
1899
debugs(88, 3, "--> YES: same LMT, different length");