]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/StoreMap.h
Polish: correct debug text about ACL 'AND' list match state
[thirdparty/squid.git] / src / ipc / StoreMap.h
CommitLineData
44c95fcf
AR
1#ifndef SQUID_IPC_STORE_MAP_H
2#define SQUID_IPC_STORE_MAP_H
3
4#include "ipc/ReadWriteLock.h"
68353d5a 5#include "ipc/mem/Pointer.h"
7f6748c8 6#include "typedefs.h"
44c95fcf 7
9199139f
AR
8namespace Ipc
9{
44c95fcf
AR
10
11/// a StoreMap element, holding basic shareable StoreEntry info
9199139f
AR
12class StoreMapSlot
13{
44c95fcf
AR
14public:
15 StoreMapSlot();
16
17 /// store StoreEntry key and basics
18 void set(const StoreEntry &anEntry);
19
20 void setKey(const cache_key *const aKey);
21 bool sameKey(const cache_key *const aKey) const;
22
23public:
24 mutable ReadWriteLock lock; ///< protects slot data below
794d4c0c 25 Atomic::WordT<uint8_t> waitingToBeFreed; ///< may be accessed w/o a lock
44c95fcf
AR
26
27 uint64_t key[2]; ///< StoreEntry key
28
29 // STORE_META_STD TLV field from StoreEntry
30 struct Basics {
31 time_t timestamp;
32 time_t lastref;
33 time_t expires;
34 time_t lastmod;
35 uint64_t swap_file_sz;
89924985
AR
36 uint16_t refcount;
37 uint16_t flags;
9199139f 38 } basics;
44c95fcf
AR
39
40 /// possible persistent states
41 typedef enum {
42 Empty, ///< ready for writing, with nothing of value
43 Writeable, ///< transitions from Empty to Readable
44 Readable, ///< ready for reading
9199139f 45 } State;
44c95fcf
AR
46 State state; ///< current state
47};
48
7f6748c8
AR
49class StoreMapCleaner;
50
9199139f 51/// map of StoreMapSlots indexed by their keys, with read/write slot locking
44c95fcf
AR
52/// kids extend to store custom data
53class StoreMap
54{
55public:
56 typedef StoreMapSlot Slot;
57
f8f98441 58 /// data shared across maps in different processes
fc3921ec
A
59 class Shared
60 {
f8f98441 61 public:
68353d5a
DK
62 Shared(const int aLimit, const size_t anExtrasSize);
63 size_t sharedMemorySize() const;
64 static size_t SharedMemorySize(const int limit, const size_t anExtrasSize);
65
66 const int limit; ///< maximum number of map slots
67 const size_t extrasSize; ///< size of slot extra data
794d4c0c 68 Atomic::Word count; ///< current number of map slots
68353d5a
DK
69 Slot slots[]; ///< slots storage
70 };
71
72public:
73 typedef Mem::Owner<Shared> Owner;
74
75 /// initialize shared memory
76 static Owner *Init(const char *const path, const int limit);
77
78 StoreMap(const char *const aPath);
44c95fcf
AR
79
80 /// finds, reservers space for writing a new entry or returns nil
81 Slot *openForWriting(const cache_key *const key, sfileno &fileno);
82 /// successfully finish writing the entry
83 void closeForWriting(const sfileno fileno, bool lockForReading = false);
84
85 /// only works on locked entries; returns nil unless the slot is readable
86 const Slot *peekAtReader(const sfileno fileno) const;
87
88 /// mark the slot as waiting to be freed and, if possible, free it
89 void free(const sfileno fileno);
90
91 /// open slot for reading, increments read level
92 const Slot *openForReading(const cache_key *const key, sfileno &fileno);
93 /// open slot for reading, increments read level
94 const Slot *openForReadingAt(const sfileno fileno);
95 /// close slot after reading, decrements read level
96 void closeForReading(const sfileno fileno);
97
98 /// called by lock holder to terminate either slot writing or reading
99 void abortIo(const sfileno fileno);
100
101 bool full() const; ///< there are no empty slots left
68353d5a 102 bool valid(const int n) const; ///< whether n is a valid slot coordinate
44c95fcf
AR
103 int entryCount() const; ///< number of used slots
104 int entryLimit() const; ///< maximum number of slots that can be used
105
106 /// adds approximate current stats to the supplied ones
107 void updateStats(ReadWriteLockStats &stats) const;
108
7f6748c8
AR
109 StoreMapCleaner *cleaner; ///< notified before a readable entry is freed
110
44c95fcf 111protected:
68353d5a 112 static Owner *Init(const char *const path, const int limit, const size_t extrasSize);
44c95fcf 113
44c95fcf 114 const String path; ///< cache_dir path, used for logging
68353d5a 115 Mem::Pointer<Shared> shared;
44c95fcf
AR
116
117private:
118 int slotIndexByKey(const cache_key *const key) const;
119 Slot &slotByKey(const cache_key *const key);
120
9199139f 121 Slot *openForReading(Slot &s);
44c95fcf
AR
122 void abortWriting(const sfileno fileno);
123 void freeIfNeeded(Slot &s);
124 void freeLocked(Slot &s, bool keepLocked);
68353d5a 125};
44c95fcf 126
68353d5a
DK
127/// StoreMap with extra slot data
128/// Note: ExtrasT must be POD, it is initialized with zeroes, no
129/// constructors or destructors are called
130template <class ExtrasT>
131class StoreMapWithExtras: public StoreMap
132{
133public:
134 typedef ExtrasT Extras;
135
136 /// initialize shared memory
137 static Owner *Init(const char *const path, const int limit);
138
139 StoreMapWithExtras(const char *const path);
140
141 /// write access to the extras; call openForWriting() first!
142 ExtrasT &extras(const sfileno fileno);
143 /// read-only access to the extras; call openForReading() first!
144 const ExtrasT &extras(const sfileno fileno) const;
145
146protected:
147
148 ExtrasT *sharedExtras; ///< pointer to extras in shared memory
44c95fcf
AR
149};
150
7f6748c8
AR
151/// API for adjusting external state when dirty map slot is being freed
152class StoreMapCleaner
153{
154public:
155 virtual ~StoreMapCleaner() {}
156
157 /// adjust slot-linked state before a locked Readable slot is erased
158 virtual void cleanReadable(const sfileno fileno) = 0;
159};
160
68353d5a
DK
161// StoreMapWithExtras implementation
162
163template <class ExtrasT>
164StoreMap::Owner *
165StoreMapWithExtras<ExtrasT>::Init(const char *const path, const int limit)
166{
167 return StoreMap::Init(path, limit, sizeof(Extras));
168}
169
170template <class ExtrasT>
171StoreMapWithExtras<ExtrasT>::StoreMapWithExtras(const char *const path):
9199139f 172 StoreMap(path)
68353d5a
DK
173{
174 const size_t sharedSizeWithoutExtras =
175 Shared::SharedMemorySize(entryLimit(), 0);
176 sharedExtras = reinterpret_cast<Extras *>(reinterpret_cast<char *>(shared.getRaw()) + sharedSizeWithoutExtras);
177}
178
179template <class ExtrasT>
180ExtrasT &
181StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno)
182{
183 return const_cast<ExtrasT &>(const_cast<const StoreMapWithExtras *>(this)->extras(fileno));
184}
185
186template <class ExtrasT>
187const ExtrasT &
188StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno) const
189{
190 assert(sharedExtras);
191 assert(valid(fileno));
192 return sharedExtras[fileno];
193}
194
7f6748c8 195
44c95fcf
AR
196} // namespace Ipc
197
198// We do not reuse struct _fileMap because we cannot control its size,
199// resulting in sfilenos that are pointing beyond the database.
200
201#endif /* SQUID_IPC_STORE_MAP_H */