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