]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/StoreMap.h
1 #ifndef SQUID_IPC_STORE_MAP_H
2 #define SQUID_IPC_STORE_MAP_H
4 #include "ipc/ReadWriteLock.h"
5 #include "ipc/mem/Pointer.h"
11 /// a StoreMap element, holding basic shareable StoreEntry info
17 /// store StoreEntry key and basics
18 void set(const StoreEntry
&anEntry
);
20 void setKey(const cache_key
*const aKey
);
21 bool sameKey(const cache_key
*const aKey
) const;
24 mutable ReadWriteLock lock
; ///< protects slot data below
25 Atomic::WordT
<uint8_t> waitingToBeFreed
; ///< may be accessed w/o a lock
27 uint64_t key
[2]; ///< StoreEntry key
29 // STORE_META_STD TLV field from StoreEntry
35 uint64_t swap_file_sz
;
40 /// possible persistent states
42 Empty
, ///< ready for writing, with nothing of value
43 Writeable
, ///< transitions from Empty to Readable
44 Readable
, ///< ready for reading
46 State state
; ///< current state
49 class StoreMapCleaner
;
51 /// map of StoreMapSlots indexed by their keys, with read/write slot locking
52 /// kids extend to store custom data
56 typedef StoreMapSlot Slot
;
58 /// data shared across maps in different processes
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
);
67 const int limit
; ///< maximum number of map slots
68 const size_t extrasSize
; ///< size of slot extra data
69 Atomic::Word count
; ///< current number of map slots
70 Slot
*slots
; ///< slots storage
73 Shared
&operator=(const Shared
&); //disabled
74 Shared(const Shared
&); //disabled
78 typedef Mem::Owner
<Shared
> Owner
;
80 /// initialize shared memory
81 static Owner
*Init(const char *const path
, const int limit
);
83 StoreMap(const char *const aPath
);
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);
90 /// only works on locked entries; returns nil unless the slot is readable
91 const Slot
*peekAtReader(const sfileno fileno
) const;
93 /// mark the slot as waiting to be freed and, if possible, free it
94 void free(const sfileno fileno
);
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
);
103 /// called by lock holder to terminate either slot writing or reading
104 void abortIo(const sfileno fileno
);
106 bool full() const; ///< there are no empty slots left
107 bool valid(const int n
) const; ///< whether n is a valid slot coordinate
108 int entryCount() const; ///< number of used slots
109 int entryLimit() const; ///< maximum number of slots that can be used
111 /// adds approximate current stats to the supplied ones
112 void updateStats(ReadWriteLockStats
&stats
) const;
114 StoreMapCleaner
*cleaner
; ///< notified before a readable entry is freed
117 static Owner
*Init(const char *const path
, const int limit
, const size_t extrasSize
);
119 const String path
; ///< cache_dir path, used for logging
120 Mem::Pointer
<Shared
> shared
;
123 int slotIndexByKey(const cache_key
*const key
) const;
124 Slot
&slotByKey(const cache_key
*const key
);
126 Slot
*openForReading(Slot
&s
);
127 void abortWriting(const sfileno fileno
);
128 void freeIfNeeded(Slot
&s
);
129 void freeLocked(Slot
&s
, bool keepLocked
);
132 /// StoreMap with extra slot data
133 /// Note: ExtrasT must be POD, it is initialized with zeroes, no
134 /// constructors or destructors are called
135 template <class ExtrasT
>
136 class StoreMapWithExtras
: public StoreMap
139 typedef ExtrasT Extras
;
141 /// initialize shared memory
142 static Owner
*Init(const char *const path
, const int limit
);
144 StoreMapWithExtras(const char *const path
);
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;
153 ExtrasT
*sharedExtras
; ///< pointer to extras in shared memory
156 /// API for adjusting external state when dirty map slot is being freed
157 class StoreMapCleaner
160 virtual ~StoreMapCleaner() {}
162 /// adjust slot-linked state before a locked Readable slot is erased
163 virtual void cleanReadable(const sfileno fileno
) = 0;
166 // StoreMapWithExtras implementation
168 template <class ExtrasT
>
170 StoreMapWithExtras
<ExtrasT
>::Init(const char *const path
, const int limit
)
172 return StoreMap::Init(path
, limit
, sizeof(Extras
));
175 template <class ExtrasT
>
176 StoreMapWithExtras
<ExtrasT
>::StoreMapWithExtras(const char *const path
):
179 const size_t sharedSizeWithoutExtras
=
180 Shared::SharedMemorySize(entryLimit(), 0);
181 sharedExtras
= reinterpret_cast<Extras
*>(reinterpret_cast<char *>(shared
.getRaw()) + sharedSizeWithoutExtras
);
184 template <class ExtrasT
>
186 StoreMapWithExtras
<ExtrasT
>::extras(const sfileno fileno
)
188 return const_cast<ExtrasT
&>(const_cast<const StoreMapWithExtras
*>(this)->extras(fileno
));
191 template <class ExtrasT
>
193 StoreMapWithExtras
<ExtrasT
>::extras(const sfileno fileno
) const
195 assert(sharedExtras
);
196 assert(valid(fileno
));
197 return sharedExtras
[fileno
];
202 // We do not reuse FileMap because we cannot control its size,
203 // resulting in sfilenos that are pointing beyond the database.
205 #endif /* SQUID_IPC_STORE_MAP_H */