]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
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. | |
7 | */ | |
8 | ||
ff9d9458 FC |
9 | #ifndef SQUID_SRC_MEMSTORE_H |
10 | #define SQUID_SRC_MEMSTORE_H | |
9487bae9 | 11 | |
68353d5a | 12 | #include "ipc/mem/Page.h" |
06684a9b | 13 | #include "ipc/mem/PageStack.h" |
68353d5a | 14 | #include "ipc/StoreMap.h" |
9487bae9 | 15 | #include "Store.h" |
2745fea5 | 16 | #include "store/Controlled.h" |
68353d5a DK |
17 | |
18 | // StoreEntry restoration info not already stored by Ipc::StoreMap | |
1860fbac | 19 | struct MemStoreMapExtraItem { |
6d68a230 | 20 | Ipc::Mem::PageId page; ///< shared memory page with entry slice content |
68353d5a | 21 | }; |
1860fbac AR |
22 | typedef Ipc::StoreMapItems<MemStoreMapExtraItem> MemStoreMapExtras; |
23 | typedef Ipc::StoreMap MemStoreMap; | |
9487bae9 | 24 | |
abf396ec AR |
25 | class ShmWriter; |
26 | ||
9487bae9 AR |
27 | /// Stores HTTP entities in RAM. Current implementation uses shared memory. |
28 | /// Unlike a disk store (SwapDir), operations are synchronous (and fast). | |
2745fea5 | 29 | class MemStore: public Store::Controlled, public Ipc::StoreMapCleaner |
9199139f | 30 | { |
9487bae9 AR |
31 | public: |
32 | MemStore(); | |
337b9aa4 | 33 | ~MemStore() override; |
9487bae9 | 34 | |
96a7de88 DK |
35 | /// whether e should be kept in local RAM for possible future caching |
36 | bool keepInLocalMemory(const StoreEntry &e) const; | |
37 | ||
4475555f AR |
38 | /// copy non-shared entry data of the being-cached entry to our cache |
39 | void write(StoreEntry &e); | |
40 | ||
41 | /// all data has been received; there will be no more write() calls | |
42 | void completeWriting(StoreEntry &e); | |
43 | ||
ce49546e | 44 | /// called when the entry is about to forget its association with mem cache |
29c56e41 | 45 | void disconnect(StoreEntry &e); |
ce49546e | 46 | |
2745fea5 | 47 | /* Storage API */ |
337b9aa4 AR |
48 | void create() override {} |
49 | void init() override; | |
50 | StoreEntry *get(const cache_key *) override; | |
51 | uint64_t maxSize() const override; | |
52 | uint64_t minSize() const override; | |
53 | uint64_t currentSize() const override; | |
54 | uint64_t currentCount() const override; | |
55 | int64_t maxObjectSize() const override; | |
56 | void getStats(StoreInfoStats &stats) const override; | |
57 | void stat(StoreEntry &e) const override; | |
58 | void reference(StoreEntry &e) override; | |
59 | bool dereference(StoreEntry &e) override; | |
60 | void updateHeaders(StoreEntry *e) override; | |
61 | void maintain() override; | |
62 | bool anchorToCache(StoreEntry &) override; | |
63 | bool updateAnchored(StoreEntry &) override; | |
64 | void evictCached(StoreEntry &) override; | |
65 | void evictIfFound(const cache_key *) override; | |
9487bae9 | 66 | |
daed75a9 EB |
67 | /// whether Squid is correctly configured to use a shared memory cache |
68 | static bool Enabled() { return EntryLimit() > 0; } | |
68353d5a | 69 | static int64_t EntryLimit(); |
daed75a9 EB |
70 | /// whether Squid is configured to use a shared memory cache |
71 | /// (it may still be disabled due to the implicit minimum entry size limit) | |
72 | static bool Requested(); | |
a4555399 | 73 | |
9487bae9 | 74 | protected: |
abf396ec AR |
75 | friend ShmWriter; |
76 | ||
97754f5a | 77 | bool shouldCache(StoreEntry &e) const; |
4475555f | 78 | bool startCaching(StoreEntry &e); |
9487bae9 | 79 | |
4475555f | 80 | void copyToShm(StoreEntry &e); |
abf396ec | 81 | void copyToShmSlice(StoreEntry &e, Ipc::StoreMapAnchor &anchor, Ipc::StoreMap::Slice &slice); |
06684a9b | 82 | bool copyFromShm(StoreEntry &e, const sfileno index, const Ipc::StoreMapAnchor &anchor); |
122a6e3c | 83 | void copyFromShmSlice(StoreEntry &, const StoreIOBuffer &); |
ce49546e | 84 | |
abf396ec AR |
85 | void updateHeadersOrThrow(Ipc::StoreMapUpdate &update); |
86 | ||
ce49546e | 87 | void anchorEntry(StoreEntry &e, const sfileno index, const Ipc::StoreMapAnchor &anchor); |
4310f8b0 | 88 | bool updateAnchoredWith(StoreEntry &, const sfileno, const Ipc::StoreMapAnchor &); |
06684a9b | 89 | |
abf396ec AR |
90 | Ipc::Mem::PageId pageForSlice(Ipc::StoreMapSliceId sliceId); |
91 | Ipc::StoreMap::Slice &nextAppendableSlice(const sfileno entryIndex, sfileno &sliceOffset); | |
06684a9b | 92 | sfileno reserveSapForWriting(Ipc::Mem::PageId &page); |
9487bae9 | 93 | |
7f6748c8 | 94 | // Ipc::StoreMapCleaner API |
337b9aa4 | 95 | void noteFreeMapSlice(const Ipc::StoreMapSliceId sliceId) override; |
7f6748c8 | 96 | |
9487bae9 | 97 | private: |
06684a9b AR |
98 | // TODO: move freeSlots into map |
99 | Ipc::Mem::Pointer<Ipc::Mem::PageStack> freeSlots; ///< unused map slot IDs | |
9487bae9 | 100 | MemStoreMap *map; ///< index of mem-cached entries |
06684a9b | 101 | |
1860fbac AR |
102 | typedef MemStoreMapExtras Extras; |
103 | Ipc::Mem::Pointer<Extras> extras; ///< IDs of pages with slice data | |
104 | ||
06684a9b AR |
105 | /// the last allocate slice for writing a store entry (during copyToShm) |
106 | sfileno lastWritingSlice; | |
107 | ||
108 | /// temporary storage for slot and page ID pointers; for the waiting cache | |
9d4e9cfb AR |
109 | class SlotAndPage |
110 | { | |
06684a9b | 111 | public: |
aee3523a | 112 | SlotAndPage(): slot(nullptr), page(nullptr) {} |
06684a9b AR |
113 | bool operator !() const { return !slot && !page; } |
114 | Ipc::Mem::PageId *slot; ///< local slot variable, waiting to be filled | |
115 | Ipc::Mem::PageId *page; ///< local page variable, waiting to be filled | |
116 | }; | |
117 | SlotAndPage waitingFor; ///< a cache for a single "hot" free slot and page | |
9487bae9 AR |
118 | }; |
119 | ||
120 | // Why use Store as a base? MemStore and SwapDir are both "caches". | |
121 | ||
122 | // Why not just use a SwapDir API? That would not help much because Store has | |
123 | // to check/update memory cache separately from the disk cache. And same API | |
124 | // would hurt because we can support synchronous get/put, unlike the disks. | |
125 | ||
ff9d9458 | 126 | #endif /* SQUID_SRC_MEMSTORE_H */ |
f53969cc | 127 |