]> git.ipfire.org Git - thirdparty/squid.git/blame - src/Store.h
Use "standard" STUB macros/API. Also marked the file as unused.
[thirdparty/squid.git] / src / Store.h
CommitLineData
e6ccf245 1/*
bde978a6 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
e6ccf245 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
e6ccf245 7 */
bbc27441 8
e6ccf245 9#ifndef SQUID_STORE_H
10#define SQUID_STORE_H
11
0f33a01d 12#include "base/Packable.h"
8bf217bd 13#include "base/RefCount.h"
3e4bebf8 14#include "comm/forward.h"
582c2af2 15#include "CommRead.h"
c6983ec7 16#include "hash.h"
f35c0145 17#include "http/forward.h"
c24f7fb6 18#include "http/RequestMethod.h"
43ca19e0 19#include "HttpReply.h"
04ebce55 20#include "MemObject.h"
582c2af2 21#include "Range.h"
aa839030 22#include "RemovalPolicy.h"
e1ba42a4 23#include "store_key_md5.h"
582c2af2 24#include "StoreIOBuffer.h"
93bc1434 25#include "StoreStats.h"
528b2c61 26
f41735ea 27#if USE_SQUID_ESI
f99c2cfe 28#include "esi/Element.h"
43ae1d95 29#endif
30
27e059d4 31#include <ostream>
27e059d4 32
65517dc8 33class AsyncCall;
582c2af2 34class HttpRequest;
71b673d4 35class RequestFlags;
582c2af2 36class StoreClient;
c8f4eac4 37class StoreSearch;
7d3c4ca1 38class SwapDir;
c8f4eac4 39
8822ebee
AR
40extern StoreIoStats store_io_stats;
41
051dedf9
AR
42/// maximum number of entries per cache_dir
43enum { SwapFilenMax = 0xFFFFFF }; // keep in sync with StoreEntry::swap_filen
44
0f33a01d 45class StoreEntry : public hash_link, public Packable
62e76326 46{
91574db5 47 MEMPROXY_CLASS(StoreEntry);
62e76326 48
332dafa2 49public:
a46d2c0e 50 static DeferredRead::DeferrableRead DeferReader;
51 bool checkDeferRead(int fd) const;
62e76326 52
528b2c61 53 virtual const char *getMD5Text() const;
c8f4eac4 54 StoreEntry();
6d8d05b5 55 virtual ~StoreEntry();
43ae1d95 56
528b2c61 57 virtual HttpReply const *getReply() const;
58 virtual void write (StoreIOBuffer);
04ebce55
FC
59
60 /** Check if the Store entry is emtpty
61 * \retval true Store contains 0 bytes of data.
62 * \retval false Store contains 1 or more bytes of data.
63 * \retval false Store contains negative content !!!!!!
64 */
65 virtual bool isEmpty() const {
66 assert (mem_obj);
67 return mem_obj->endOffset() == 0;
68 }
aa18a4ca 69 virtual bool isAccepting() const;
384a7590 70 virtual size_t bytesWanted(Range<size_t> const aRange, bool ignoreDelayPool = false) const;
7224ca5a
AR
71 /// flags [truncated or too big] entry with ENTRY_BAD_LENGTH and releases it
72 void lengthWentBad(const char *reason);
528b2c61 73 virtual void complete();
74 virtual store_client_t storeClientType() const;
75 virtual char const *getSerialisedMetaData();
eacfca83
AR
76 /// Store a prepared error response. MemObject locks the reply object.
77 void storeErrorResponse(HttpReply *reply);
3756e5c0
AR
78 void replaceHttpReply(HttpReply *, bool andStartWriting = true);
79 void startWriting(); ///< pack and write reply headers and, maybe, body
5b55f1f1
CT
80 /// whether we may start writing to disk (now or in the future)
81 virtual bool mayStartSwapOut();
82 virtual void trimMemory(const bool preserveSwappable);
0cdcf3d7 83
2da4bfe6 84 // called when a decision to cache in memory has been made
0cdcf3d7
AR
85 void memOutDecision(const bool willCacheInRam);
86 // called when a decision to cache on disk has been made
87 void swapOutDecision(const MemObject::SwapOut::Decision &decision);
88
bfb55b6f 89 void abort();
c8f4eac4 90 void unlink();
5ed72359 91 void makePublic();
92 void makePrivate();
d88e3c49 93 void setPublicKey();
94 void setPrivateKey();
95 void expireNow();
96 void releaseRequest();
97 void negativeCache();
f53969cc 98 void cacheNegatively(); /** \todo argh, why both? */
d88e3c49 99 void invokeHandlers();
100 void purgeMem();
9487bae9 101 void cacheInMemory(); ///< start or continue storing in memory cache
c07cbbf4 102 void swapOut();
5b55f1f1
CT
103 /// whether we are in the process of writing this entry to disk
104 bool swappingOut() const { return swap_status == SWAPOUT_WRITING; }
aa1a691e 105 void swapOutFileClose(int how);
3900307b 106 const char *url() const;
7015a149
AR
107 /// Satisfies cachability requirements shared among disk and RAM caches.
108 /// Encapsulates common checks of mayStartSwapOut() and memoryCachable().
109 /// TODO: Rename and make private so only those two methods can call this.
110 bool checkCachable();
3900307b 111 int checkNegativeHit() const;
112 int locked() const;
113 int validToSend() const;
97754f5a 114 bool memoryCachable(); ///< checkCachable() and can be cached in memory
4475555f 115
c877c0bc
AR
116 /// if needed, initialize mem_obj member w/o URI-related information
117 MemObject *makeMemObject();
118
119 /// initialize mem_obj member (if needed) and supply URI-related info
120 void createMemObject(const char *storeId, const char *logUri, const HttpRequestMethod &aMethod);
4475555f 121
3900307b 122 void dump(int debug_lvl) const;
123 void hashDelete();
124 void hashInsert(const cache_key *);
125 void registerAbort(STABH * cb, void *);
126 void reset();
127 void setMemStatus(mem_status_t);
128 void timestampsSet();
129 void unregisterAbort();
130 void destroyMemObject();
131 int checkTooSmall();
528b2c61 132
3e4bebf8 133 void delayAwareRead(const Comm::ConnectionPointer &conn, char *buf, int len, AsyncCall::Pointer callback);
43ae1d95 134
a46d2c0e 135 void setNoDelay (bool const);
190154cf 136 bool modifiedSince(HttpRequest * request) const;
79c8035e
AR
137 /// has ETag matching at least one of the If-Match etags
138 bool hasIfMatchEtag(const HttpRequest &request) const;
139 /// has ETag matching at least one of the If-None-Match etags
140 bool hasIfNoneMatchEtag(const HttpRequest &request) const;
46017fdd
CT
141 /// whether this entry has an ETag; if yes, puts ETag value into parameter
142 bool hasEtag(ETag &etag) const;
63be0a78 143
144 /** What store does this entry belong too ? */
7d3c4ca1 145 virtual RefCount<SwapDir> store() const;
a46d2c0e 146
e6ccf245 147 MemObject *mem_obj;
148 RemovalPolicyNode repl;
149 /* START OF ON-DISK STORE_META_STD TLV field */
150 time_t timestamp;
151 time_t lastref;
152 time_t expires;
153 time_t lastmod;
47f6e231 154 uint64_t swap_file_sz;
f45dd259
AJ
155 uint16_t refcount;
156 uint16_t flags;
e6ccf245 157 /* END OF ON-DISK STORE_META_STD */
62e76326 158
051dedf9
AR
159 /// unique ID inside a cache_dir for swapped out entries; -1 for others
160 sfileno swap_filen:25; // keep in sync with SwapFilenMax
d1398b75
HN
161
162 sdirno swap_dirn:7;
62e76326 163
d1398b75 164 mem_status_t mem_status:3;
62e76326 165
d1398b75 166 ping_status_t ping_status:3;
62e76326 167
d1398b75 168 store_status_t store_status:3;
62e76326 169
d1398b75 170 swap_status_t swap_status:3;
62e76326 171
e6ccf245 172public:
173 static size_t inUseCount();
60745f24 174 static void getPublicByRequestMethod(StoreClient * aClient, HttpRequest * request, const HttpRequestMethod& method);
190154cf 175 static void getPublicByRequest(StoreClient * aClient, HttpRequest * request);
60745f24 176 static void getPublic(StoreClient * aClient, const char *uri, const HttpRequestMethod& method);
528b2c61 177
26ac0430 178 virtual bool isNull() {
62e76326 179 return false;
63be0a78 180 };
62e76326 181
43ae1d95 182 void setReleaseFlag();
f41735ea 183#if USE_SQUID_ESI
43ae1d95 184
185 ESIElement::Pointer cachedESITree;
186#endif
47f6e231 187 virtual int64_t objectLen() const;
188 virtual int64_t contentLen() const;
c21ad0f5 189
18994992 190 /// claim shared ownership of this entry (for use in a given context)
acc5dc4c 191 /// matching lock() and unlock() contexts eases leak triage but is optional
18994992 192 void lock(const char *context);
1bfe9ade 193
18994992
AR
194 /// disclaim shared ownership; may remove entry from store and delete it
195 /// returns remaning lock level (zero for unlocked and possibly gone entry)
acc5dc4c 196 int unlock(const char *context);
1bfe9ade
AR
197
198 /// returns a local concurrent use counter, for debugging
199 int locks() const { return static_cast<int>(lock_count); }
200
18994992
AR
201 /// update last reference timestamp and related Store metadata
202 void touch();
203
5f33b71d 204 virtual void release();
62e76326 205
0ad2b63b
CT
206#if USE_ADAPTATION
207 /// call back producer when more buffer space is available
208 void deferProducer(const AsyncCall::Pointer &producer);
209 /// calls back producer registered with deferProducer
210 void kickProducer();
211#endif
212
0f33a01d
AJ
213 /* Packable API */
214 virtual void append(char const *, int);
215 virtual void vappendf(const char *, va_list);
7e10ac87
AJ
216 virtual void buffer();
217 virtual void flush();
0f33a01d 218
0cdcf3d7
AR
219protected:
220 void transientsAbandonmentCheck();
221
e6ccf245 222private:
2be042f6
AR
223 bool checkTooBig() const;
224
04eb0689 225 static MemAllocator *pool;
528b2c61 226
f53969cc 227 unsigned short lock_count; /* Assume < 65536! */
1bfe9ade 228
0ad2b63b
CT
229#if USE_ADAPTATION
230 /// producer callback registered with deferProducer
231 AsyncCall::Pointer deferredProducer;
232#endif
233
528b2c61 234 bool validLength() const;
79c8035e 235 bool hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) const;
e6ccf245 236};
237
2c4cd1ad
AR
238std::ostream &operator <<(std::ostream &os, const StoreEntry &e);
239
63be0a78 240/// \ingroup StoreAPI
3b13a8fd 241class NullStoreEntry:public StoreEntry
e6ccf245 242{
62e76326 243
e6ccf245 244public:
245 static NullStoreEntry *getInstance();
26ac0430 246 bool isNull() {
62e76326 247 return true;
e6ccf245 248 }
62e76326 249
332dafa2 250 const char *getMD5Text() const;
04ebce55 251 HttpReply const *getReply() const { return NULL; }
26ac0430 252 void write (StoreIOBuffer) {}
62e76326 253
528b2c61 254 bool isEmpty () const {return true;}
62e76326 255
ced8def3 256 virtual size_t bytesWanted(Range<size_t> const aRange, bool) const { return aRange.end; }
62e76326 257
e6ccf245 258 void operator delete(void *address);
26ac0430 259 void complete() {}
62e76326 260
261private:
26ac0430 262 store_client_t storeClientType() const {return STORE_MEM_CLIENT;}
62e76326 263
528b2c61 264 char const *getSerialisedMetaData();
97754f5a 265 virtual bool mayStartSwapOut() { return false; }
62e76326 266
ced8def3 267 void trimMemory(const bool) {}
528b2c61 268
e6ccf245 269 static NullStoreEntry _instance;
270};
271
63be0a78 272/// \ingroup StoreAPI
c8f4eac4 273typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata);
274
63be0a78 275/**
276 \ingroup StoreAPI
277 * Abstract base class that will replace the whole store and swapdir interface.
278 */
c8f4eac4 279class Store : public RefCountable
280{
281
282public:
63be0a78 283 /** The root store */
04ebce55
FC
284 static Store &Root() {
285 if (CurrentRoot == NULL)
286 fatal("No Store Root has been set");
287 return *CurrentRoot;
288 }
c8f4eac4 289 static void Root(Store *);
290 static void Root(RefCount<Store>);
291 static void Stats(StoreEntry * output);
292 static void Maintain(void *unused);
293
294 virtual ~Store() {}
295
63be0a78 296 /** Handle pending callbacks - called by the event loop. */
c8f4eac4 297 virtual int callback() = 0;
63be0a78 298
299 /** create the resources needed for this store to operate */
c8f4eac4 300 virtual void create();
63be0a78 301
302 /**
303 * Notify this store that its disk is full.
304 \todo XXX move into a protected api call between store files and their stores, rather than a top level api call
c8f4eac4 305 */
306 virtual void diskFull();
c8f4eac4 307
63be0a78 308 /** Retrieve a store entry from the store */
b21767da 309 virtual StoreEntry * get(const cache_key *) = 0;
c8f4eac4 310
63be0a78 311 /** \todo imeplement the async version */
b21767da 312 virtual void get(String const key , STOREGETCLIENT callback, void *cbdata) = 0;
c8f4eac4 313
314 /* prepare the store for use. The store need not be usable immediately,
315 * it should respond to readable() and writable() with true as soon
316 * as it can provide those services
317 */
318 virtual void init() = 0;
319
63be0a78 320 /**
321 * The maximum size the store will support in normal use. Inaccuracy is permitted,
322 * but may throw estimates for memory etc out of whack.
323 */
12e11a5c 324 virtual uint64_t maxSize() const = 0;
c8f4eac4 325
63be0a78 326 /** The minimum size the store will shrink to via normal housekeeping */
12e11a5c 327 virtual uint64_t minSize() const = 0;
c8f4eac4 328
57f583f1
DK
329 /** current store size */
330 virtual uint64_t currentSize() const = 0;
39c1e1d9
DK
331
332 /** the total number of objects stored */
333 virtual uint64_t currentCount() const = 0;
334
af2fda07
DK
335 /** the maximum object size that can be stored, -1 if unlimited */
336 virtual int64_t maxObjectSize() const = 0;
337
93bc1434
AR
338 /// collect cache storage-related statistics
339 virtual void getStats(StoreInfoStats &stats) const = 0;
340
63be0a78 341 /**
342 * Output stats to the provided store entry.
343 \todo make these calls asynchronous
344 */
345 virtual void stat(StoreEntry &) const = 0;
c8f4eac4 346
63be0a78 347 /** Sync the store prior to shutdown */
348 virtual void sync();
c8f4eac4 349
63be0a78 350 /** remove a Store entry from the store */
c8f4eac4 351 virtual void unlink (StoreEntry &);
352
353 /* search in the store */
30abd221 354 virtual StoreSearch *search(String const url, HttpRequest *) = 0;
c8f4eac4 355
356 /* pulled up from SwapDir for migration.... probably do not belong here */
f53969cc 357 virtual void reference(StoreEntry &) = 0; /* Reference this object */
c8f4eac4 358
4c973beb 359 /// Undo reference(), returning false iff idle e should be destroyed
ced8def3 360 virtual bool dereference(StoreEntry &, bool wantsLocalMemory) = 0;
c8f4eac4 361
362 virtual void maintain() = 0; /* perform regular maintenance should be private and self registered ... */
363
1bfe9ade
AR
364 // XXX: This method belongs to Store::Root/StoreController, but it is here
365 // to avoid casting Root() to StoreController until Root() API is fixed.
366 /// informs stores that this entry will be eventually unlinked
ced8def3 367 virtual void markForUnlink(StoreEntry &) {}
1bfe9ade 368
9487bae9
AR
369 // XXX: This method belongs to Store::Root/StoreController, but it is here
370 // because test cases use non-StoreController derivatives as Root
371 /// called when the entry is no longer needed by any transaction
ced8def3 372 virtual void handleIdleEntry(StoreEntry &) {}
9487bae9 373
96a7de88
DK
374 // XXX: This method belongs to Store::Root/StoreController, but it is here
375 // because test cases use non-StoreController derivatives as Root
376 /// called to get rid of no longer needed entry data in RAM, if any
ced8def3 377 virtual void memoryOut(StoreEntry &, const bool /*preserveSwappable*/) {}
96a7de88 378
9a9954ba
AR
379 // XXX: This method belongs to Store::Root/StoreController, but it is here
380 // to avoid casting Root() to StoreController until Root() API is fixed.
381 /// makes the entry available for collapsing future requests
ced8def3 382 virtual void allowCollapsing(StoreEntry *, const RequestFlags &, const HttpRequestMethod &) {}
9a9954ba 383
99921d9d
AR
384 // XXX: This method belongs to Store::Root/StoreController, but it is here
385 // to avoid casting Root() to StoreController until Root() API is fixed.
386 /// marks the entry completed for collapsed requests
ced8def3 387 virtual void transientsCompleteWriting(StoreEntry &) {}
99921d9d 388
ce49546e
AR
389 // XXX: This method belongs to Store::Root/StoreController, but it is here
390 // to avoid casting Root() to StoreController until Root() API is fixed.
391 /// Update local intransit entry after changes made by appending worker.
ced8def3 392 virtual void syncCollapsed(const sfileno) {}
ce49546e 393
4475555f
AR
394 // XXX: This method belongs to Store::Root/StoreController, but it is here
395 // to avoid casting Root() to StoreController until Root() API is fixed.
396 /// calls Root().transients->abandon() if transients are tracked
ced8def3 397 virtual void transientsAbandon(StoreEntry &) {}
4475555f
AR
398
399 // XXX: This method belongs to Store::Root/StoreController, but it is here
d366a7fa
AR
400 // to avoid casting Root() to StoreController until Root() API is fixed.
401 /// number of the transient entry readers some time ago
ced8def3 402 virtual int transientReaders(const StoreEntry &) const { return 0; }
d366a7fa
AR
403
404 // XXX: This method belongs to Store::Root/StoreController, but it is here
4475555f
AR
405 // to avoid casting Root() to StoreController until Root() API is fixed.
406 /// disassociates the entry from the intransit table
ced8def3 407 virtual void transientsDisconnect(MemObject &) {}
4475555f 408
ce49546e
AR
409 // XXX: This method belongs to Store::Root/StoreController, but it is here
410 // to avoid casting Root() to StoreController until Root() API is fixed.
411 /// removes the entry from the memory cache
ced8def3 412 virtual void memoryUnlink(StoreEntry &) {}
ce49546e 413
4475555f
AR
414 // XXX: This method belongs to Store::Root/StoreController, but it is here
415 // to avoid casting Root() to StoreController until Root() API is fixed.
416 /// disassociates the entry from the memory cache, preserving cached data
ced8def3 417 virtual void memoryDisconnect(StoreEntry &) {}
4475555f
AR
418
419 /// If the entry is not found, return false. Otherwise, return true after
420 /// tying the entry to this cache and setting inSync to updateCollapsed().
ced8def3 421 virtual bool anchorCollapsed(StoreEntry &, bool &/*inSync*/) { return false; }
ce49546e
AR
422
423 /// update a local collapsed entry with fresh info from this cache (if any)
ced8def3 424 virtual bool updateCollapsed(StoreEntry &) { return false; }
96a7de88 425
c8f4eac4 426private:
427 static RefCount<Store> CurrentRoot;
428};
429
63be0a78 430/// \ingroup StoreAPI
c8f4eac4 431typedef RefCount<Store> StorePointer;
432
63be0a78 433/// \ingroup StoreAPI
71b673d4 434size_t storeEntryInUse();
63be0a78 435
436/// \ingroup StoreAPI
71b673d4 437const char *storeEntryFlags(const StoreEntry *);
63be0a78 438
439/// \ingroup StoreAPI
71b673d4 440void storeEntryReplaceObject(StoreEntry *, HttpReply *);
e6ccf245 441
63be0a78 442/// \ingroup StoreAPI
71b673d4 443StoreEntry *storeGetPublic(const char *uri, const HttpRequestMethod& method);
63be0a78 444
445/// \ingroup StoreAPI
71b673d4 446StoreEntry *storeGetPublicByRequest(HttpRequest * request);
63be0a78 447
448/// \ingroup StoreAPI
71b673d4 449StoreEntry *storeGetPublicByRequestMethod(HttpRequest * request, const HttpRequestMethod& method);
63be0a78 450
451/// \ingroup StoreAPI
1bfe9ade 452/// Like storeCreatePureEntry(), but also locks the entry and sets entry key.
71b673d4 453StoreEntry *storeCreateEntry(const char *, const char *, const RequestFlags &, const HttpRequestMethod&);
63be0a78 454
1bfe9ade
AR
455/// \ingroup StoreAPI
456/// Creates a new StoreEntry with mem_obj and sets initial flags/states.
457StoreEntry *storeCreatePureEntry(const char *storeId, const char *logUrl, const RequestFlags &, const HttpRequestMethod&);
458
63be0a78 459/// \ingroup StoreAPI
71b673d4 460void storeInit(void);
63be0a78 461
63be0a78 462/// \ingroup StoreAPI
71b673d4 463void storeConfigure(void);
63be0a78 464
465/// \ingroup StoreAPI
71b673d4 466void storeFreeMemory(void);
63be0a78 467
468/// \ingroup StoreAPI
71b673d4 469int expiresMoreThan(time_t, time_t);
63be0a78 470
63be0a78 471/// \ingroup StoreAPI
71b673d4 472void storeAppendPrintf(StoreEntry *, const char *,...) PRINTF_FORMAT_ARG2;
63be0a78 473
474/// \ingroup StoreAPI
71b673d4 475void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
63be0a78 476
477/// \ingroup StoreAPI
71b673d4 478int storeTooManyDiskFilesOpen(void);
63be0a78 479
e1f7507e 480class SwapDir;
63be0a78 481/// \ingroup StoreAPI
71b673d4 482void storeHeapPositionUpdate(StoreEntry *, SwapDir *);
63be0a78 483
484/// \ingroup StoreAPI
71b673d4 485void storeSwapFileNumberSet(StoreEntry * e, sfileno filn);
63be0a78 486
487/// \ingroup StoreAPI
71b673d4 488void storeFsInit(void);
63be0a78 489
490/// \ingroup StoreAPI
71b673d4 491void storeFsDone(void);
63be0a78 492
493/// \ingroup StoreAPI
71b673d4 494void storeReplAdd(const char *, REMOVALPOLICYCREATE *);
63be0a78 495
496/// \ingroup StoreAPI
c8f4eac4 497extern FREE destroyStoreEntry;
e6ccf245 498
6d3c2758 499/// \ingroup StoreAPI
71b673d4 500void storeGetMemSpace(int size);
6d3c2758 501
e6ccf245 502#endif /* SQUID_STORE_H */
f53969cc 503