22 debugs(54, 5,
"attached map [" <<
path <<
"] created: " <<
31 debugs(54, 5,
"new map [" << path <<
"] created: " << limit);
38 return Init(path, limit, 0);
45 <<
" for writing in map [" << path <<
']');
46 const int idx = slotIndexByKey(key);
48 if (
Slot *slot = openForWritingAt(idx)) {
59 Slot &s = shared->slots[fileno];
68 debugs(54, 5,
"cannot open existing entry " << fileno <<
69 " for writing " << path);
80 debugs(54, 5,
"opened slot at " << fileno <<
81 " for writing in map [" << path <<
']');
85 debugs(54, 5,
"failed to open slot at " << fileno <<
86 " for writing in map [" << path <<
']');
93 debugs(54, 5,
"stop writing slot at " << fileno <<
94 " in map [" << path <<
']');
96 Slot &s = shared->slots[fileno];
104 debugs(54, 5,
"switching writing slot at " << fileno <<
105 " to reading in map [" << path <<
']');
107 Slot &s = shared->slots[fileno];
116 debugs(54, 5,
"abort writing slot at " << fileno <<
117 " in map [" << path <<
']');
119 Slot &s = shared->slots[fileno];
121 freeLocked(s,
false);
128 const Slot &s = shared->slots[fileno];
140 debugs(54, 5,
"marking slot at " << fileno <<
" to be freed in"
141 " map [" << path <<
']');
144 Slot &s = shared->slots[fileno];
147 freeLocked(s,
false);
156 <<
" for reading in map [" << path <<
']');
157 const int idx = slotIndexByKey(key);
158 if (
const Slot *slot = openForReadingAt(idx)) {
159 if (slot->sameKey(key)) {
161 debugs(54, 5,
"opened slot at " << fileno <<
" for key "
162 <<
storeKeyText(key) <<
" for reading in map [" << path <<
166 slot->lock.unlockShared();
169 <<
" for reading in map [" << path <<
']');
176 debugs(54, 5,
"trying to open slot at " << fileno <<
" for "
177 "reading in map [" << path <<
']');
179 Slot &s = shared->slots[fileno];
182 debugs(54, 5,
"failed to lock slot at " << fileno <<
" for "
183 "reading in map [" << path <<
']');
189 debugs(54, 7,
"empty slot at " << fileno <<
" for "
190 "reading in map [" << path <<
']');
196 debugs(54, 7,
"dirty slot at " << fileno <<
" for "
197 "reading in map [" << path <<
']');
201 debugs(54, 5,
"opened slot at " << fileno <<
" for reading in"
202 " map [" << path <<
']');
209 debugs(54, 5,
"closing slot at " << fileno <<
" for reading in "
210 "map [" << path <<
']');
212 Slot &s = shared->slots[fileno];
220 return shared->limit;
226 return shared->count;
232 return entryCount() >= entryLimit();
238 for (
int i = 0; i < shared->limit; ++i)
239 shared->slots[i].lock.updateStats(
stats);
245 return 0 <= pos && pos < entryLimit();
250hash_key(
const unsigned char *data,
unsigned int len,
unsigned int hashSize)
254 for (j = 0, n = 0; j < len; j++ ) {
258 return (n ^ (j * 271)) % hashSize;
264 const unsigned char *k =
reinterpret_cast<const unsigned char *
>(key);
271 return shared->slots[slotIndexByKey(key)];
278 if (!s.
empty() && cleaner)
279 cleaner->noteFreeMapSlot(&s - shared->slots.raw());
282 memset(s.
key, 0,
sizeof(s.
key));
286 debugs(54, 5,
"freed slot at " << (&s - shared->slots.raw()) <<
287 " in map [" << path <<
']');
295 memset(
key, 0,
sizeof(
key));
296 memset(
p, 0,
sizeof(
p));
302 memcpy(key, aKey,
sizeof(key));
304 memcpy(p, block, blockSize);
312 return (memcmp(key, aKey,
sizeof(key)) == 0);
318 for (
unsigned char const*u = key; u < key +
sizeof(key); ++u) {
328 limit(aLimit), extrasSize(anExtrasSize), count(0), slots(aLimit)
339 return SharedMemorySize(limit, extrasSize);
345 return sizeof(
Shared) + limit * (
sizeof(
Slot) + extrasSize);
static unsigned int hash_key(const unsigned char *data, unsigned int len, unsigned int hashSize)
#define MEMMAP_SLOT_KEY_SIZE
a MemMap basic element, holding basic shareable memory block info
bool sameKey(const cache_key *const aKey) const
void set(const unsigned char *aKey, const void *block, size_t blockSize, time_t expire=0)
std::atomic< uint8_t > waitingToBeFreed
may be accessed w/o a lock
ReadWriteLock lock
protects slot data below
unsigned char key[MEMMAP_SLOT_KEY_SIZE]
The entry key.
unsigned char p[MEMMAP_SLOT_DATA_SIZE]
The memory block;.
data shared across maps in different processes
static size_t SharedMemorySize(const int limit, const size_t anExtrasSize)
size_t sharedMemorySize() const
Shared(const int aLimit, const size_t anExtrasSize)
void free(const sfileno fileno)
mark the slot as waiting to be freed and, if possible, free it
const SBuf path
cache_dir path, used for logging
void updateStats(ReadWriteLockStats &stats) const
adds approximate current stats to the supplied ones
MemMap(const char *const aPath)
bool valid(const int n) const
whether n is a valid slot coordinate
Mem::Pointer< Shared > shared
void abortWriting(const sfileno fileno)
terminate writing the entry, freeing its slot for others to use
bool full() const
there are no empty slots left
int slotIndexByKey(const cache_key *const key) const
int entryLimit() const
maximum number of slots that can be used
void freeLocked(Slot &s, bool keepLocked)
unconditionally frees the already exclusively locked slot and releases lock
void closeForReading(const sfileno fileno)
close slot after reading, decrements read level
const Slot * openForReading(const cache_key *const key, sfileno &fileno)
open slot for reading, increments read level
void switchWritingToReading(const sfileno fileno)
stop writing the locked entry and start reading it
const Slot * openForReadingAt(const sfileno fileno)
open slot for reading, increments read level
Slot * openForWriting(const cache_key *const key, sfileno &fileno)
Slot & slotByKey(const cache_key *const key)
static Owner * Init(const char *const path, const int limit)
initialize shared memory
int entryCount() const
number of used slots
void closeForWriting(const sfileno fileno)
successfully finish writing the entry
const Slot * peekAtReader(const sfileno fileno) const
only works on locked entries; returns nil unless the slot is readable
Slot * openForWritingAt(sfileno fileno, bool overwriteExisting=true)
approximate stats of a set of ReadWriteLocks
void switchExclusiveToShared()
void unlockExclusive()
undo successful exclusiveLock()
bool lockExclusive()
lock for modification or return false
void unlockShared()
undo successful sharedLock()
bool lockShared()
lock for reading or return false
#define debugs(SECTION, LEVEL, CONTENT)
void Init(void)
prepares to parse ACLs configuration
class Ping::pingStats_ stats
unsigned char cache_key
Store key.
const char * storeKeyText(const cache_key *key)