/*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
static DeferredRead::DeferrableRead DeferReader;
bool checkDeferRead(int fd) const;
- virtual const char *getMD5Text() const;
+ const char *getMD5Text() const;
StoreEntry();
virtual ~StoreEntry();
- virtual HttpReply const *getReply() const;
- virtual void write (StoreIOBuffer);
+ MemObject &mem() { assert(mem_obj); return *mem_obj; }
+ const MemObject &mem() const { assert(mem_obj); return *mem_obj; }
+
+ /// \retval * the address of freshest reply (if mem_obj exists)
+ /// \retval nullptr when mem_obj does not exist
+ /// \see MemObject::freshestReply()
+ const HttpReply *hasFreshestReply() const { return mem_obj ? &mem_obj->freshestReply() : nullptr; }
+
+ void write(StoreIOBuffer);
- /** Check if the Store entry is emtpty
+ /** Check if the Store entry is empty
* \retval true Store contains 0 bytes of data.
* \retval false Store contains 1 or more bytes of data.
* \retval false Store contains negative content !!!!!!
*/
- virtual bool isEmpty() const {
- assert (mem_obj);
- return mem_obj->endOffset() == 0;
- }
- virtual bool isAccepting() const;
- virtual size_t bytesWanted(Range<size_t> const aRange, bool ignoreDelayPool = false) const;
+ bool isEmpty() const { return mem().endOffset() == 0; }
+ bool isAccepting() const;
+ size_t bytesWanted(Range<size_t> const aRange, bool ignoreDelayPool = false) const;
/// flags [truncated or too big] entry with ENTRY_BAD_LENGTH and releases it
void lengthWentBad(const char *reason);
- virtual void complete();
- virtual store_client_t storeClientType() const;
- virtual char const *getSerialisedMetaData();
+ void complete();
+ store_client_t storeClientType() const;
+ /// \returns a malloc()ed buffer containing a length-long packed swap header
+ const char *getSerialisedMetaData(size_t &length) const;
/// Store a prepared error response. MemObject locks the reply object.
void storeErrorResponse(HttpReply *reply);
- void replaceHttpReply(HttpReply *, bool andStartWriting = true);
+ void replaceHttpReply(const HttpReplyPointer &, const bool andStartWriting = true);
void startWriting(); ///< pack and write reply headers and, maybe, body
/// whether we may start writing to disk (now or in the future)
- virtual bool mayStartSwapOut();
- virtual void trimMemory(const bool preserveSwappable);
+ bool mayStartSwapOut();
+ void trimMemory(const bool preserveSwappable);
// called when a decision to cache in memory has been made
void memOutDecision(const bool willCacheInRam);
bool swappingOut() const { return swap_status == SWAPOUT_WRITING; }
/// whether the entire entry is now on disk (possibly marked for deletion)
bool swappedOut() const { return swap_status == SWAPOUT_DONE; }
+ /// whether we failed to write this entry to disk
+ bool swapoutFailed() const { return swap_status == SWAPOUT_FAILED; }
void swapOutFileClose(int how);
const char *url() const;
/// Satisfies cachability requirements shared among disk and RAM caches.
/// TODO: Rename and make private so only those two methods can call this.
bool checkCachable();
int checkNegativeHit() const;
- int locked() const;
+ int locked() const { return lock_count; }
int validToSend() const;
bool memoryCachable(); ///< checkCachable() and can be cached in memory
/// whether this entry has an ETag; if yes, puts ETag value into parameter
bool hasEtag(ETag &etag) const;
+ /// Updates easily-accessible non-Store-specific parts of the entry.
+ /// Use Controller::updateOnNotModified() instead of this helper.
+ /// \returns whether anything was actually updated
+ bool updateOnNotModified(const StoreEntry &e304);
+
/// the disk this entry is [being] cached on; asserts for entries w/o a disk
Store::Disk &disk() const;
/// whether one of this StoreEntry owners has locked the corresponding
/// whether there is a corresponding locked shared memory table entry
bool hasMemStore() const { return mem_obj && mem_obj->memCache.index >= 0; }
- /// whether this is a collapsed forwarding-created public entry that still
- /// has not received its response headers; new requests may collapse on it
- bool collapsingInitiator() const;
+ /// whether this entry can feed collapsed requests and only them
+ bool hittingRequiresCollapsing() const { return EBIT_TEST(flags, ENTRY_REQUIRES_COLLAPSING); }
+
+ /// allow or forbid collapsed requests feeding
+ void setCollapsingRequirement(const bool required);
MemObject *mem_obj;
RemovalPolicyNode repl;
static void getPublicByRequest(StoreClient * aClient, HttpRequest * request);
static void getPublic(StoreClient * aClient, const char *uri, const HttpRequestMethod& method);
- virtual bool isNull() const { return false; } // TODO: Replace with nullptr.
-
void *operator new(size_t byteCount);
void operator delete(void *address);
#if USE_SQUID_ESI
ESIElement::Pointer cachedESITree;
#endif
- virtual int64_t objectLen() const;
- virtual int64_t contentLen() const;
+ int64_t objectLen() const { return mem().object_sz; }
+ int64_t contentLen() const { return objectLen() - mem().baseReply().hdr_sz; }
/// claim shared ownership of this entry (for use in a given context)
/// matching lock() and unlock() contexts eases leak triage but is optional
/// Removes all unlocked (and marks for eventual removal all locked) Store
/// entries, including attached and unattached entries that have our key.
/// Also destroys us if we are unlocked or makes us private otherwise.
- /// TODO: remove virtual.
- virtual void release(const bool shareable = false);
+ void release(const bool shareable = false);
/// One of the three methods to get rid of an unlocked StoreEntry object.
/// May destroy this object if it is unlocked; does nothing otherwise.
std::ostream &operator <<(std::ostream &os, const StoreEntry &e);
-/// \ingroup StoreAPI
-class NullStoreEntry:public StoreEntry
-{
-
-public:
- static NullStoreEntry *getInstance();
-
- const char *getMD5Text() const;
- HttpReply const *getReply() const { return NULL; }
- void write (StoreIOBuffer) {}
-
- bool isEmpty () const {return true;}
-
- /* StoreEntry API */
- virtual bool isNull() const { return true; }
- virtual size_t bytesWanted(Range<size_t> const aRange, bool) const { return aRange.end; }
-
- void operator delete(void *address);
- void complete() {}
-
-private:
- store_client_t storeClientType() const {return STORE_MEM_CLIENT;}
-
- char const *getSerialisedMetaData();
- virtual bool mayStartSwapOut() { return false; }
-
- void trimMemory(const bool) {}
-
- static NullStoreEntry _instance;
-};
-
/// \ingroup StoreAPI
typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata);