Go to the documentation of this file.
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();
250 hash_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);
ReadWriteLock lock
protects slot data below
approximate stats of a set of ReadWriteLocks
size_t sharedMemorySize() const
int entryCount() const
number of used slots
a MemMap basic element, holding basic shareable memory block info
unsigned char cache_key
Store key.
bool lockShared()
lock for reading or return false
const SBuf path
cache_dir path, used for logging
const Slot * openForReading(const cache_key *const key, sfileno &fileno)
open slot for reading, increments read level
static unsigned int hash_key(const unsigned char *data, unsigned int len, unsigned int hashSize)
Slot * openForWritingAt(sfileno fileno, bool overwriteExisting=true)
bool lockExclusive()
lock for modification or return false
void closeForWriting(const sfileno fileno)
successfully finish writing the entry
Mem::Pointer< Shared > shared
void updateStats(ReadWriteLockStats &stats) const
adds approximate current stats to the supplied ones
void unlockShared()
undo successful sharedLock()
void abortWriting(const sfileno fileno)
terminate writing the entry, freeing its slot for others to use
void unlockExclusive()
undo successful exclusiveLock()
#define MEMMAP_SLOT_KEY_SIZE
const Slot * peekAtReader(const sfileno fileno) const
only works on locked entries; returns nil unless the slot is readable
MemMap(const char *const aPath)
bool valid(const int n) const
whether n is a valid slot coordinate
int entryLimit() const
maximum number of slots that can be used
void switchWritingToReading(const sfileno fileno)
stop writing the locked entry and start reading it
int slotIndexByKey(const cache_key *const key) const
static Owner * Init(const char *const path, const int limit)
initialize shared memory
const Slot * openForReadingAt(const sfileno fileno)
open slot for reading, increments read level
unsigned char key[MEMMAP_SLOT_KEY_SIZE]
The entry key.
data shared across maps in different processes
unsigned char p[MEMMAP_SLOT_DATA_SIZE]
The memory block;.
void set(const unsigned char *aKey, const void *block, size_t blockSize, time_t expire=0)
Slot * openForWriting(const cache_key *const key, sfileno &fileno)
void freeLocked(Slot &s, bool keepLocked)
unconditionally frees the already exclusively locked slot and releases lock
Slot & slotByKey(const cache_key *const key)
const char * storeKeyText(const cache_key *key)
void free(const sfileno fileno)
mark the slot as waiting to be freed and, if possible, free it
void switchExclusiveToShared()
static size_t SharedMemorySize(const int limit, const size_t anExtrasSize)
#define debugs(SECTION, LEVEL, CONTENT)
void Init(void)
prepares to parse ACLs configuration
bool sameKey(const cache_key *const aKey) const
Shared(const int aLimit, const size_t anExtrasSize)
void closeForReading(const sfileno fileno)
close slot after reading, decrements read level
std::atomic< uint8_t > waitingToBeFreed
may be accessed w/o a lock
bool full() const
there are no empty slots left