]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/StoreMap.h
SourceFormat Enforcement
[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);
2cde0303 65 ~Shared();
68353d5a
DK
66
67 const int limit; ///< maximum number of map slots
68 const size_t extrasSize; ///< size of slot extra data
794d4c0c 69 Atomic::Word count; ///< current number of map slots
2cde0303
FC
70 Slot *slots; ///< slots storage
71 private:
72 Shared(); //disabled
73 Shared &operator=(const Shared&); //disabled
74 Shared(const Shared&); //disabled
68353d5a
DK
75 };
76
77public:
78 typedef Mem::Owner<Shared> Owner;
79
80 /// initialize shared memory
81 static Owner *Init(const char *const path, const int limit);
82
83 StoreMap(const char *const aPath);
44c95fcf
AR
84
85 /// finds, reservers space for writing a new entry or returns nil
86 Slot *openForWriting(const cache_key *const key, sfileno &fileno);
87 /// successfully finish writing the entry
88 void closeForWriting(const sfileno fileno, bool lockForReading = false);
89
90 /// only works on locked entries; returns nil unless the slot is readable
91 const Slot *peekAtReader(const sfileno fileno) const;
92
93 /// mark the slot as waiting to be freed and, if possible, free it
94 void free(const sfileno fileno);
95
96 /// open slot for reading, increments read level
97 const Slot *openForReading(const cache_key *const key, sfileno &fileno);
98 /// open slot for reading, increments read level
99 const Slot *openForReadingAt(const sfileno fileno);
100 /// close slot after reading, decrements read level
101 void closeForReading(const sfileno fileno);
102
103 /// called by lock holder to terminate either slot writing or reading
104 void abortIo(const sfileno fileno);
105
106 bool full() const; ///< there are no empty slots left
68353d5a 107 bool valid(const int n) const; ///< whether n is a valid slot coordinate
44c95fcf
AR
108 int entryCount() const; ///< number of used slots
109 int entryLimit() const; ///< maximum number of slots that can be used
110
111 /// adds approximate current stats to the supplied ones
112 void updateStats(ReadWriteLockStats &stats) const;
113
7f6748c8
AR
114 StoreMapCleaner *cleaner; ///< notified before a readable entry is freed
115
44c95fcf 116protected:
68353d5a 117 static Owner *Init(const char *const path, const int limit, const size_t extrasSize);
44c95fcf 118
44c95fcf 119 const String path; ///< cache_dir path, used for logging
68353d5a 120 Mem::Pointer<Shared> shared;
44c95fcf
AR
121
122private:
123 int slotIndexByKey(const cache_key *const key) const;
124 Slot &slotByKey(const cache_key *const key);
125
9199139f 126 Slot *openForReading(Slot &s);
44c95fcf
AR
127 void abortWriting(const sfileno fileno);
128 void freeIfNeeded(Slot &s);
129 void freeLocked(Slot &s, bool keepLocked);
68353d5a 130};
44c95fcf 131
68353d5a
DK
132/// StoreMap with extra slot data
133/// Note: ExtrasT must be POD, it is initialized with zeroes, no
134/// constructors or destructors are called
135template <class ExtrasT>
136class StoreMapWithExtras: public StoreMap
137{
138public:
139 typedef ExtrasT Extras;
140
141 /// initialize shared memory
142 static Owner *Init(const char *const path, const int limit);
143
144 StoreMapWithExtras(const char *const path);
145
146 /// write access to the extras; call openForWriting() first!
147 ExtrasT &extras(const sfileno fileno);
148 /// read-only access to the extras; call openForReading() first!
149 const ExtrasT &extras(const sfileno fileno) const;
150
151protected:
152
153 ExtrasT *sharedExtras; ///< pointer to extras in shared memory
44c95fcf
AR
154};
155
7f6748c8
AR
156/// API for adjusting external state when dirty map slot is being freed
157class StoreMapCleaner
158{
159public:
160 virtual ~StoreMapCleaner() {}
161
162 /// adjust slot-linked state before a locked Readable slot is erased
163 virtual void cleanReadable(const sfileno fileno) = 0;
164};
165
68353d5a
DK
166// StoreMapWithExtras implementation
167
168template <class ExtrasT>
169StoreMap::Owner *
170StoreMapWithExtras<ExtrasT>::Init(const char *const path, const int limit)
171{
172 return StoreMap::Init(path, limit, sizeof(Extras));
173}
174
175template <class ExtrasT>
176StoreMapWithExtras<ExtrasT>::StoreMapWithExtras(const char *const path):
9199139f 177 StoreMap(path)
68353d5a
DK
178{
179 const size_t sharedSizeWithoutExtras =
180 Shared::SharedMemorySize(entryLimit(), 0);
181 sharedExtras = reinterpret_cast<Extras *>(reinterpret_cast<char *>(shared.getRaw()) + sharedSizeWithoutExtras);
182}
183
184template <class ExtrasT>
185ExtrasT &
186StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno)
187{
188 return const_cast<ExtrasT &>(const_cast<const StoreMapWithExtras *>(this)->extras(fileno));
189}
190
191template <class ExtrasT>
192const ExtrasT &
193StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno) const
194{
195 assert(sharedExtras);
196 assert(valid(fileno));
197 return sharedExtras[fileno];
198}
199
44c95fcf
AR
200} // namespace Ipc
201
75f8f9a2 202// We do not reuse FileMap because we cannot control its size,
44c95fcf
AR
203// resulting in sfilenos that are pointing beyond the database.
204
205#endif /* SQUID_IPC_STORE_MAP_H */