]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2025 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_SRC_FS_ROCK_ROCKREBUILD_H | |
10 | #define SQUID_SRC_FS_ROCK_ROCKREBUILD_H | |
11 | ||
12 | #include "base/AsyncJob.h" | |
13 | #include "base/RunnersRegistry.h" | |
14 | #include "cbdata.h" | |
15 | #include "fs/rock/forward.h" | |
16 | #include "ipc/mem/Pointer.h" | |
17 | #include "ipc/StoreMap.h" | |
18 | #include "MemBuf.h" | |
19 | #include "store_rebuild.h" | |
20 | ||
21 | namespace Rock | |
22 | { | |
23 | ||
24 | class LoadingEntry; | |
25 | class LoadingSlot; | |
26 | class LoadingParts; | |
27 | ||
28 | /// \ingroup Rock | |
29 | /// manages store rebuild process: loading meta information from db on disk | |
30 | class Rebuild: public AsyncJob, private IndependentRunner | |
31 | { | |
32 | CBDATA_CHILD(Rebuild); | |
33 | ||
34 | public: | |
35 | /// cache_dir indexing statistics shared across same-kid process restarts | |
36 | class Stats | |
37 | { | |
38 | public: | |
39 | static SBuf Path(const char *dirPath); | |
40 | static Ipc::Mem::Owner<Stats> *Init(const SwapDir &); | |
41 | ||
42 | static size_t SharedMemorySize() { return sizeof(Stats); } | |
43 | size_t sharedMemorySize() const { return SharedMemorySize(); } | |
44 | ||
45 | /// whether the rebuild is finished already | |
46 | bool completed(const SwapDir &) const; | |
47 | ||
48 | StoreRebuildData counts; | |
49 | }; | |
50 | ||
51 | /// starts indexing the given cache_dir if that indexing is necessary | |
52 | /// \returns whether the indexing was necessary (and, hence, started) | |
53 | static bool Start(SwapDir &dir); | |
54 | ||
55 | /* AsyncJob API */ | |
56 | virtual void callException(const std::exception &) override; | |
57 | ||
58 | protected: | |
59 | /// whether the current kid is responsible for rebuilding the given cache_dir | |
60 | static bool IsResponsible(const SwapDir &); | |
61 | ||
62 | Rebuild(SwapDir *dir, const Ipc::Mem::Pointer<Stats> &); | |
63 | ~Rebuild() override; | |
64 | ||
65 | /* Registered Runner API */ | |
66 | void startShutdown() override; | |
67 | ||
68 | /* AsyncJob API */ | |
69 | void start() override; | |
70 | bool doneAll() const override; | |
71 | void swanSong() override; | |
72 | ||
73 | bool doneLoading() const; | |
74 | bool doneValidating() const; | |
75 | ||
76 | private: | |
77 | void checkpoint(); | |
78 | void steps(); | |
79 | void loadingSteps(); | |
80 | void validationSteps(); | |
81 | void loadOneSlot(); | |
82 | void validateOneEntry(const sfileno fileNo); | |
83 | void validateOneSlot(const SlotId slotId); | |
84 | bool importEntry(Ipc::StoreMapAnchor &anchor, const sfileno slotId, const DbCellHeader &header); | |
85 | void freeBadEntry(const sfileno fileno, const char *eDescription); | |
86 | ||
87 | void failure(const char *msg, int errNo = 0); | |
88 | ||
89 | LoadingEntry loadingEntry(const sfileno fileNo); | |
90 | void startNewEntry(const sfileno fileno, const SlotId slotId, const DbCellHeader &header); | |
91 | void primeNewEntry(Ipc::StoreMapAnchor &anchor, const sfileno fileno, const DbCellHeader &header); | |
92 | void finalizeOrFree(const sfileno fileNo, LoadingEntry &le); | |
93 | void finalizeOrThrow(const sfileno fileNo, LoadingEntry &le); | |
94 | void addSlotToEntry(const sfileno fileno, const SlotId slotId, const DbCellHeader &header); | |
95 | void useNewSlot(const SlotId slotId, const DbCellHeader &header); | |
96 | ||
97 | LoadingSlot loadingSlot(const SlotId slotId); | |
98 | void mapSlot(const SlotId slotId, const DbCellHeader &header); | |
99 | void freeUnusedSlot(const SlotId slotId, const bool invalid); | |
100 | void freeSlot(const SlotId slotId, const bool invalid); | |
101 | ||
102 | template <class SlotIdType> | |
103 | void chainSlots(SlotIdType &from, const SlotId to); | |
104 | ||
105 | bool sameEntry(const sfileno fileno, const DbCellHeader &header) const; | |
106 | ||
107 | SBuf progressDescription() const; | |
108 | ||
109 | SwapDir *sd; | |
110 | LoadingParts *parts; ///< parts of store entries being loaded from disk | |
111 | ||
112 | Ipc::Mem::Pointer<Stats> stats; ///< indexing statistics in shared memory | |
113 | ||
114 | int64_t dbSize; | |
115 | int dbSlotSize; ///< the size of a db cell, including the cell header | |
116 | int64_t dbSlotLimit; ///< total number of db cells | |
117 | int64_t dbEntryLimit; ///< maximum number of entries that can be stored in db | |
118 | ||
119 | int fd; // store db file descriptor | |
120 | int64_t dbOffset; // TODO: calculate in a method, using loadingPos | |
121 | int64_t loadingPos; ///< index of the db slot being loaded from disk now | |
122 | int64_t validationPos; ///< index of the loaded db slot being validated now | |
123 | MemBuf buf; ///< space to load current db slot (and entry metadata) into | |
124 | ||
125 | StoreRebuildData &counts; ///< a reference to the shared memory counters | |
126 | ||
127 | /// whether we have started indexing this cache_dir before, | |
128 | /// presumably in the previous process performing the same-kid role | |
129 | const bool resuming; | |
130 | ||
131 | static void Steps(void *data); | |
132 | }; | |
133 | ||
134 | } // namespace Rock | |
135 | ||
136 | #endif /* SQUID_SRC_FS_ROCK_ROCKREBUILD_H */ | |
137 |