StoreMap.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_IPC_STORE_MAP_H
10 #define SQUID_IPC_STORE_MAP_H
11 
12 #include "ipc/mem/FlexibleArray.h"
13 #include "ipc/mem/Pointer.h"
14 #include "ipc/ReadWriteLock.h"
15 #include "sbuf/SBuf.h"
16 #include "store/forward.h"
17 #include "store_key_md5.h"
18 
19 #include <functional>
20 
21 namespace Ipc
22 {
23 
24 typedef int32_t StoreMapSliceId;
25 
29 {
30 public:
31  typedef uint32_t Size;
32 
33  StoreMapSlice(): size(0), next(-1) {}
35  size.exchange(o.size);
36  next.exchange(o.next);
37  }
38 
40  size.store(o.size);
41  next.store(o.next);
42  return *this;
43  }
44 
45  std::atomic<Size> size;
46  std::atomic<StoreMapSliceId> next;
47 };
48 
54 {
55 public:
57 
59  void set(const StoreEntry &anEntry);
60 
61  void setKey(const cache_key *const aKey);
62  bool sameKey(const cache_key *const aKey) const;
63 
65  void rewind();
66 
67  /* entry state may change immediately after calling these methods unless
68  * the caller holds an appropriate lock */
69  bool empty() const { return !key[0] && !key[1]; }
70  bool reading() const { return lock.readers; }
71  bool writing() const { return lock.writing; }
72  bool complete() const { return !empty() && !writing(); }
73 
74 public:
75  mutable ReadWriteLock lock;
76  std::atomic<uint8_t> waitingToBeFreed;
77 
78  // fields marked with [app] can be modified when appending-while-reading
79  // fields marked with [update] can be modified when updating-while-reading
80 
81  uint64_t key[2];
82 
83  // STORE_META_STD TLV field from StoreEntry
84  struct Basics {
85  time_t timestamp;
86  time_t lastref;
87  time_t expires;
88  time_t lastmod;
89  std::atomic<uint64_t> swap_file_sz; // [app]
90  uint16_t refcount;
91  uint16_t flags;
92  } basics;
93 
95  std::atomic<StoreMapSliceId> start;
96 
99  std::atomic<StoreMapSliceId> splicingPoint;
100 };
101 
104 template <class C>
106 {
107 public:
108  typedef C Item;
110 
111  explicit StoreMapItems(const int aCapacity): capacity(aCapacity), items(aCapacity) {}
112 
113  size_t sharedMemorySize() const { return SharedMemorySize(capacity); }
114  static size_t SharedMemorySize(const int aCapacity) { return sizeof(StoreMapItems<Item>) + aCapacity*sizeof(Item); }
115 
116  const int capacity;
118 };
119 
122 
126 {
127 public:
129 
130  explicit StoreMapAnchors(const int aCapacity);
131 
132  size_t sharedMemorySize() const;
133  static size_t SharedMemorySize(const int anAnchorLimit);
134 
135  std::atomic<int32_t> count;
136  std::atomic<uint32_t> victim;
137  const int capacity;
139 };
140 // TODO: Find an elegant way to use StoreMapItems in StoreMapAnchors
141 
144 
147 {
148 public:
150  class Edition
151  {
152  public:
153  Edition(): anchor(nullptr), fileNo(-1), name(-1), splicingPoint(-1) {}
154 
156  explicit operator bool() const { return anchor; }
157 
161 
164  };
165 
166  explicit StoreMapUpdate(StoreEntry *anEntry);
167  StoreMapUpdate(const StoreMapUpdate &other);
168  ~StoreMapUpdate();
169 
170  StoreMapUpdate &operator =(const StoreMapUpdate &other) = delete;
171 
175 };
176 
177 class StoreMapCleaner;
178 
183 class StoreMap
184 {
185 public:
189  typedef sfileno AnchorId;
194 
195 public:
197  class Owner
198  {
199  public:
200  Owner();
201  ~Owner();
205  private:
206  Owner(const Owner &); // not implemented
207  Owner &operator =(const Owner &); // not implemented
208  };
209 
211  static Owner *Init(const SBuf &path, const int slotLimit);
212 
213  StoreMap(const SBuf &aPath);
214 
216  sfileno fileNoByKey(const cache_key *const key) const;
217 
221  int compareVersions(const sfileno oldFileno, time_t newVersion) const;
222 
225  Anchor *openForWriting(const cache_key *const key, sfileno &fileno);
228  Anchor *openForWritingAt(sfileno fileno, bool overwriteExisting = true);
230  void startAppending(const sfileno fileno);
232  void closeForWriting(const sfileno fileno, bool lockForReading = false);
235  void forgetWritingEntry(const sfileno fileno);
236 
238  bool openForUpdating(Update &update, sfileno fileNoHint);
240  void closeForUpdating(Update &update);
242  void abortUpdating(Update &update);
243 
245  const Anchor *peekAtReader(const sfileno fileno) const;
246 
248  const Anchor &peekAtEntry(const sfileno fileno) const;
249 
251  void freeEntry(const sfileno fileno);
254  void freeEntryByKey(const cache_key *const key);
255 
257  const Anchor *openForReading(const cache_key *const key, sfileno &fileno);
259  const Anchor *openForReadingAt(const sfileno fileno);
261  void closeForReading(const sfileno fileno);
262 
264  Slice &writeableSlice(const AnchorId anchorId, const SliceId sliceId);
266  const Slice &readableSlice(const AnchorId anchorId, const SliceId sliceId) const;
268  Anchor &writeableEntry(const AnchorId anchorId);
270  const Anchor &readableEntry(const AnchorId anchorId) const;
271 
275  SliceId sliceContaining(const sfileno fileno, const uint64_t nth) const;
276 
278  void abortWriting(const sfileno fileno);
279 
281  bool purgeOne();
282 
284  void importSlice(const SliceId sliceId, const Slice &slice);
285 
286  /* SwapFilenMax limits the number of entries, but not slices or slots */
287  bool validEntry(const int n) const;
288  bool validSlice(const int n) const;
289  int entryCount() const;
290  int entryLimit() const;
291  int sliceLimit() const;
292 
294  void updateStats(ReadWriteLockStats &stats) const;
295 
297 
298 protected:
299  const SBuf path;
303 
304 private:
306  sfileno nameByKey(const cache_key *const key) const;
308  sfileno fileNoByName(const sfileno name) const;
309  void relocate(const sfileno name, const sfileno fileno);
310 
311  Anchor &anchorAt(const sfileno fileno);
312  const Anchor &anchorAt(const sfileno fileno) const;
313  Anchor &anchorByKey(const cache_key *const key);
314 
315  Slice &sliceAt(const SliceId sliceId);
316  const Slice &sliceAt(const SliceId sliceId) const;
318  bool openKeyless(Update::Edition &edition);
319  void closeForUpdateFinal(Update &update);
320 
321  typedef std::function<bool (const sfileno name)> NameFilter; // a "name"-based test
322  bool visitVictims(const NameFilter filter);
323 
324  void freeChain(const sfileno fileno, Anchor &inode, const bool keepLock);
325  void freeChainAt(SliceId sliceId, const SliceId splicingPoint);
326 };
327 
330 {
331 public:
332  virtual ~StoreMapCleaner() {}
333 
335  virtual void noteFreeMapSlice(const StoreMapSliceId sliceId) = 0;
336 };
337 
338 } // namespace Ipc
339 
340 // We do not reuse FileMap because we cannot control its size,
341 // resulting in sfilenos that are pointing beyond the database.
342 
343 #endif /* SQUID_IPC_STORE_MAP_H */
344 
virtual void noteFreeMapSlice(const StoreMapSliceId sliceId)=0
adjust slice-linked state before a locked Readable slice is erased
Mem::Pointer< StoreMapAnchors > anchors
entry inodes (starting blocks)
Definition: StoreMap.h:301
const Anchor * peekAtReader(const sfileno fileno) const
only works on locked entries; returns nil unless the slice is readable
Definition: StoreMap.cc:239
sfileno fileNo
StoreMap::fileNos[name], for convenience/speed.
Definition: StoreMap.h:159
sfileno fileNoByKey(const cache_key *const key) const
computes map entry anchor position for a given entry key
Definition: StoreMap.cc:699
bool validSlice(const int n) const
whether n is a valid slice coordinate
Definition: StoreMap.cc:653
const Anchor * openForReadingAt(const sfileno fileno)
opens entry (identified by sfileno) for reading, increments read level
Definition: StoreMap.cc:370
std::atomic< uint64_t > swap_file_sz
Definition: StoreMap.h:89
void importSlice(const SliceId sliceId, const Slice &slice)
copies slice to its designated position
Definition: StoreMap.cc:611
bool complete() const
Definition: StoreMap.h:72
struct Ipc::StoreMapAnchor::Basics basics
Slices::Owner * slices
Definition: StoreMap.h:204
Anchors::Owner * anchors
Definition: StoreMap.h:203
void closeForWriting(const sfileno fileno, bool lockForReading=false)
successfully finish creating or updating the entry at fileno pos
Definition: StoreMap.cc:157
std::atomic< StoreMapSliceId > next
ID of the next entry slice.
Definition: StoreMap.h:46
virtual ~StoreMapCleaner()
Definition: StoreMap.h:332
StoreMapSlice & operator=(const StoreMapSlice &o)
Definition: StoreMap.h:39
Aggregates information required for updating entry metadata and headers.
Definition: StoreMap.h:146
void rewind()
undo the effects of set(), setKey(), etc., but keep locks and state
Definition: StoreMap.cc:761
std::atomic< uint8_t > waitingToBeFreed
may be accessed w/o a lock
Definition: StoreMap.h:76
size_t sharedMemorySize() const
Definition: StoreMap.h:113
int entryLimit() const
maximum entryCount() possible
Definition: StoreMap.cc:622
Definition: SBuf.h:87
std::atomic< Size > size
slice contents size
Definition: StoreMap.h:45
unsigned char cache_key
Store key.
Definition: forward.h:29
std::function< bool(const sfileno name)> NameFilter
Definition: StoreMap.h:321
Anchor & anchorByKey(const cache_key *const key)
Definition: StoreMap.cc:706
void freeEntryByKey(const cache_key *const key)
Definition: StoreMap.cc:270
StoreMapAnchors Anchors
Definition: StoreMap.h:188
bool visitVictims(const NameFilter filter)
Definition: StoreMap.cc:574
void abortUpdating(Update &update)
undoes partial update, unlocks, and cleans up
Definition: StoreMap.cc:221
class Ping::pingStats_ stats
StoreMap(const SBuf &aPath)
Definition: StoreMap.cc:49
Slice & sliceAt(const SliceId sliceId)
Definition: StoreMap.cc:712
StoreMapCleaner * cleaner
notified before a readable entry is freed
Definition: StoreMap.h:296
StoreMapSliceId SliceId
Definition: StoreMap.h:192
approximate stats of a set of ReadWriteLocks
Definition: ReadWriteLock.h:56
uint32_t Size
Definition: StoreMap.h:31
StoreMapUpdate Update
Definition: StoreMap.h:193
static Owner * Init(const SBuf &path, const int slotLimit)
initialize shared memory
Definition: StoreMap.cc:37
bool openForUpdating(Update &update, sfileno fileNoHint)
finds and locks the Update entry for an exclusive metadata update
Definition: StoreMap.cc:409
std::atomic< int32_t > count
current number of entries
Definition: StoreMap.h:135
bool validEntry(const int n) const
whether n is a valid slice coordinate
Definition: StoreMap.cc:647
StoreMapSlices Slices
Definition: StoreMap.h:191
void closeForUpdateFinal(Update &update)
API for adjusting external state when dirty map slice is being freed.
Definition: StoreMap.h:329
StoreMapItems(const int aCapacity)
Definition: StoreMap.h:111
bool sameKey(const cache_key *const aKey) const
Definition: StoreMap.cc:740
StoreMapItems< StoreMapSlice > StoreMapSlices
StoreMapSlices indexed by their slice ID.
Definition: StoreMap.h:121
static size_t SharedMemorySize(const int aCapacity)
Definition: StoreMap.h:114
void forgetWritingEntry(const sfileno fileno)
Definition: StoreMap.cc:78
StoreMapFileNos FileNos
Definition: StoreMap.h:186
sfileno fileNoByName(const sfileno name) const
computes anchor position for a given entry name
Definition: StoreMap.cc:681
void startAppending(const sfileno fileno)
restrict opened for writing entry to appending operations; allow reads
Definition: StoreMap.cc:148
bool openKeyless(Update::Edition &edition)
Definition: StoreMap.cc:479
StoreMapAnchors(const int aCapacity)
Definition: StoreMap.cc:811
Slice & writeableSlice(const AnchorId anchorId, const SliceId sliceId)
writeable slice within an entry chain created by openForWriting()
Definition: StoreMap.cc:174
int32_t StoreMapSliceId
Definition: StoreMap.h:24
SliceId sliceContaining(const sfileno fileno, const uint64_t nth) const
Definition: StoreMap.cc:334
void updateStats(ReadWriteLockStats &stats) const
adds approximate current stats to the supplied ones
Definition: StoreMap.cc:640
Ipc::Mem::FlexibleArray< Item > items
storage
Definition: StoreMap.h:117
Anchor & writeableEntry(const AnchorId anchorId)
writeable anchor for the entry created by openForWriting()
Definition: StoreMap.cc:190
sfileno nameByKey(const cache_key *const key) const
computes entry name (i.e., key hash) for a given entry key
Definition: StoreMap.cc:672
std::atomic< StoreMapSliceId > splicingPoint
Definition: StoreMap.h:99
void set(const StoreEntry &anEntry)
store StoreEntry key and basics for an inode slot
Definition: StoreMap.cc:747
const int capacity
total number of anchors
Definition: StoreMap.h:137
void abortWriting(const sfileno fileno)
stop writing the entry, freeing its slot for others to use if possible
Definition: StoreMap.cc:204
StoreMapAnchor * anchor
StoreMap::anchors[fileNo], for convenience/speed.
Definition: StoreMap.h:158
signed_int32_t sfileno
Definition: forward.h:22
StoreMapUpdate(StoreEntry *anEntry)
Definition: StoreMap.cc:774
StoreMapItems< std::atomic< sfileno > > StoreMapFileNos
StoreMapAnchor positions, indexed by entry "name" (i.e., the entry key hash)
Definition: StoreMap.h:143
StoreMapSlice Slice
Definition: StoreMap.h:190
StoreMapAnchor Anchor
Definition: StoreMap.h:187
bool empty() const
Definition: StoreMap.h:69
size_t sharedMemorySize() const
Definition: StoreMap.cc:820
static size_t SharedMemorySize(const int anAnchorLimit)
Definition: StoreMap.cc:826
const Anchor & peekAtEntry(const sfileno fileno) const
only works on locked entries; returns the corresponding Anchor
Definition: StoreMap.cc:251
void freeEntry(const sfileno fileno)
free the entry if possible or mark it as waiting to be freed if not
Definition: StoreMap.cc:257
void freeChain(const sfileno fileno, Anchor &inode, const bool keepLock)
unconditionally frees an already locked chain of slots, unlocking if needed
Definition: StoreMap.cc:295
int sliceLimit() const
maximum number of slices possible
Definition: StoreMap.cc:634
bool writing() const
Definition: StoreMap.h:71
int compareVersions(const sfileno oldFileno, time_t newVersion) const
Definition: StoreMap.cc:62
void freeChainAt(SliceId sliceId, const SliceId splicingPoint)
unconditionally frees an already locked chain of slots; no anchor maintenance
Definition: StoreMap.cc:311
Ipc::Mem::FlexibleArray< StoreMapAnchor > items
anchors storage
Definition: StoreMap.h:138
const Anchor * openForReading(const cache_key *const key, sfileno &fileno)
opens entry (identified by key) for reading, increments read level
Definition: StoreMap.cc:353
std::atomic< uint32_t > victim
starting point for purge search
Definition: StoreMap.h:136
const Anchor & readableEntry(const AnchorId anchorId) const
readable anchor for the entry created by openForReading()
Definition: StoreMap.cc:197
Edition stale
old anchor and chain being updated
Definition: StoreMap.h:173
Edition fresh
new anchor and updated chain prefix
Definition: StoreMap.h:174
aggregates anchor and slice owners for Init() caller convenience
Definition: StoreMap.h:197
bool reading() const
Definition: StoreMap.h:70
sfileno name
StoreEntry position in StoreMap::fileNos, for swapping Editions.
Definition: StoreMap.h:160
Owner & operator=(const Owner &)
uint64_t key[2]
StoreEntry key.
Definition: StoreMap.h:81
Ipc::Mem::Owner< StoreMapItems< Item > > Owner
Definition: StoreMap.h:109
void const cache_key * key
const SBuf path
cache_dir path or similar cache name; for logging
Definition: StoreMap.h:299
Mem::Pointer< StoreMapFileNos > fileNos
entry inodes (starting blocks)
Definition: StoreMap.h:300
bool purgeOne()
either finds and frees an entry with at least 1 slice or returns false
Definition: StoreMap.cc:591
std::atomic< uint32_t > readers
number of reading users
Definition: ReadWriteLock.h:45
StoreMapSlice(const StoreMapSlice &o)
Definition: StoreMap.h:34
const Slice & readableSlice(const AnchorId anchorId, const SliceId sliceId) const
readable slice within an entry chain opened by openForReading()
Definition: StoreMap.cc:182
Anchor * openForWritingAt(sfileno fileno, bool overwriteExisting=true)
Definition: StoreMap.cc:112
std::atomic< bool > writing
there is a writing user (there can be at most 1)
Definition: ReadWriteLock.h:46
StoreMapSliceId splicingPoint
the last slice in the chain still containing metadata/headers
Definition: StoreMap.h:163
ReadWriteLock lock
protects slot data below
Definition: StoreMap.h:75
Ipc::Mem::Owner< StoreMapAnchors > Owner
Definition: StoreMap.h:128
Anchor * openForWriting(const cache_key *const key, sfileno &fileno)
Definition: StoreMap.cc:97
void closeForReading(const sfileno fileno)
closes open entry after reading, decrements read level
Definition: StoreMap.cc:400
std::atomic< StoreMapSliceId > start
where the chain of StoreEntry slices begins [app]
Definition: StoreMap.h:95
int entryCount() const
number of writeable and readable entries
Definition: StoreMap.cc:628
void relocate(const sfileno name, const sfileno fileno)
map name to fileNo
Definition: StoreMap.cc:692
Anchor & anchorAt(const sfileno fileno)
Definition: StoreMap.cc:659
sfileno AnchorId
Definition: StoreMap.h:189
StoreMapUpdate & operator=(const StoreMapUpdate &other)=delete
FileNos::Owner * fileNos
Definition: StoreMap.h:202
Mem::Pointer< StoreMapSlices > slices
chained entry pieces positions
Definition: StoreMap.h:302
During an update, the stored entry has two editions: stale and fresh.
Definition: StoreMap.h:150
void closeForUpdating(Update &update)
makes updated info available to others, unlocks, and cleans up
Definition: StoreMap.cc:497
StoreEntry * entry
the store entry being updated
Definition: StoreMap.h:172
void setKey(const cache_key *const aKey)
Definition: StoreMap.cc:734
const int capacity
total number of items
Definition: StoreMap.h:116

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors