Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / apc-stats.h
blob01bdd6d91fb904e54d8243574a6099419bed22af
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_APC_STATS_H_
18 #define incl_HPHP_APC_STATS_H_
20 #include "hphp/runtime/base/apc-string.h"
21 #include "hphp/util/service-data.h"
23 namespace HPHP {
25 struct APCHandle;
26 struct APCArray;
27 struct APCObject;
28 struct APCString;
29 struct StringData;
30 struct ArrayData;
32 //////////////////////////////////////////////////////////////////////
35 * The following functions are used to get a count of the number of bytes
36 * used by the different kind of objects that can be stored via APC in the
37 * ConcurrentTableSharedStore.
38 * The number returned should include the header for each of the object and
39 * the data. Any space used by the memory allocator does not have to be
40 * included.
42 size_t getMemSize(const APCHandle*);
43 size_t getMemSize(const APCArray*);
44 size_t getMemSize(const APCObject*);
45 /* Recurses on array/object values iff 'recurse'. Always includes strings. */
46 size_t getMemSize(const ArrayData*, bool recurse = true);
48 inline
49 size_t getMemSize(const StringData* string) {
50 return string->isStatic() ? 0 : sizeof(StringData) + string->size();
53 inline
54 size_t getMemSize(const APCString* string) {
55 return sizeof(APCString) + getMemSize(string->getStringData());
58 //////////////////////////////////////////////////////////////////////
61 * Stats and ODS API
65 * Detailed stats about APC, controlled by a runtime config flag.
67 struct APCDetailedStats {
68 APCDetailedStats();
70 // Return a formatted string with info about APC usage.
71 std::string getStatsInfo() const;
72 // adds stats to the given collection
73 void collectStats(std::map<const StringData*, int64_t>& stats) const;
75 // A new value was added to APC. This is a fresh value not replacing
76 // an existing value. However the key may exists already a be a primed
77 // mapped to file entry
78 void addAPCValue(APCHandle* handle);
79 // A new value replaces an existing one
80 void updateAPCValue(APCHandle* handle, APCHandle* oldHandle, bool expired);
81 // A value is removed. The entry may still exists if it is a primed entry
82 void removeAPCValue(APCHandle* handle, bool expired);
84 private:
85 void addType(const APCHandle* handle);
86 void removeType(const APCHandle* handle);
87 ServiceData::ExportedCounter* counterFor(const APCHandle*);
89 private:
91 * Data type counters
94 // Number of uncounted types, where uncounted means primitives
95 // and static string
96 ServiceData::ExportedCounter* m_uncounted;
97 // Number of APC strings
98 ServiceData::ExportedCounter* m_apcString;
99 // Number of uncounted strings. Uncounted strings are kind of
100 // static strings whose lifetime is controlled by the treadmill
101 ServiceData::ExportedCounter* m_uncString;
102 // Number of serialized arrays
103 ServiceData::ExportedCounter* m_serArray;
104 // Number of serialized vecs
105 ServiceData::ExportedCounter* m_serVec;
106 // Number of serialized dicts
107 ServiceData::ExportedCounter* m_serDict;
108 // Number of serialized keysets
109 ServiceData::ExportedCounter* m_serKeyset;
110 // Number of APC arrays
111 ServiceData::ExportedCounter* m_apcArray;
112 // Number of APC vecs
113 ServiceData::ExportedCounter* m_apcVec;
114 // Number of APC dicts
115 ServiceData::ExportedCounter* m_apcDict;
116 // Number of APC keysets
117 ServiceData::ExportedCounter* m_apcKeyset;
118 // Number of uncounted arrays. Uncounted arrays are kind of
119 // static arrays whose lifetime is controlled by the treadmill
120 ServiceData::ExportedCounter* m_uncArray;
121 // Number of uncounted vecs. Uncounted vecs are kind of
122 // static vecs whose lifetime is controlled by the treadmill
123 ServiceData::ExportedCounter* m_uncVec;
124 // Number of uncounted dicts. Uncounted dicts are kind of
125 // static dicts whose lifetime is controlled by the treadmill
126 ServiceData::ExportedCounter* m_uncDict;
127 // Number of uncounted keysets. Uncounted keysets are kind of
128 // static keysets whose lifetime is controlled by the treadmill
129 ServiceData::ExportedCounter* m_uncKeyset;
130 // Number of serialized objects
131 ServiceData::ExportedCounter* m_serObject;
132 // Number of APC objects
133 ServiceData::ExportedCounter* m_apcObject;
136 * Operation counters.
139 // Number of overall set values
140 ServiceData::ExportedCounter* m_setValues;
141 // Number of overall deleted operations
142 ServiceData::ExportedCounter* m_delValues;
143 // number of overall replaced values
144 ServiceData::ExportedCounter* m_replValues;
145 // Number of overall expired values
146 ServiceData::ExportedCounter* m_expValues;
150 * Class that wraps the ODS counters and offers a simple API to
151 * update the counters.
152 * The counters are also used by the admin port by the PHP APC stats API
153 * to get basic info about APC.
155 struct APCStats {
157 static APCStats& getAPCStats() {
158 return *s_apcStats.get();
160 static bool IsCreated(){
161 return s_apcStats != nullptr;
164 static void Create();
166 APCStats();
167 ~APCStats();
169 // Return a formatted string with info about APC usage.
170 std::string getStatsInfo() const;
171 // adds stats to the given collection
172 void collectStats(std::map<const StringData*, int64_t>& stats) const;
174 // A new key is added. Value is added through addAPCValue()
175 void addKey(size_t len) {
176 assert(len > 0);
177 m_entries->increment();
178 m_keySize->addValue(len);
181 // A key is removed. Value is removed through removeAPCValue()
182 void removeKey(size_t len) {
183 assert(len > 0);
184 m_entries->decrement();
185 m_keySize->addValue(-len);
188 // A primed key is added. Implies a key is added as well.
189 void addPrimedKey(size_t len) {
190 assert(len > 0);
191 m_primedEntries->increment();
192 addKey(len);
195 // A value of a certain size was added to the primed set that is mapped
196 // to file
197 void addInFileValue(size_t size) {
198 assert(size > 0);
199 m_inFileSize->addValue(size);
202 // Only call this method from ::MakeUncounted()
203 void addAPCUncountedBlock() {
204 m_uncountedBlocks->increment();
207 // Only call this method from ::ReleaseUncounted()
208 void removeAPCUncountedBlock() {
209 m_uncountedBlocks->decrement();
212 // A new value was added to APC. This is a fresh value not replacing
213 // an existing value. However the key may exists already a be a primed
214 // mapped to file entry
215 void addAPCValue(APCHandle* handle, size_t size, bool livePrimed) {
216 assert(handle && size > 0);
217 m_valueSize->addValue(size);
218 if (handle->isUncounted()) {
219 m_uncountedEntries->increment();
221 if (livePrimed) {
222 m_livePrimedSize->addValue(size);
223 m_livePrimedEntries->increment();
225 if (m_detailedStats) {
226 m_detailedStats->addAPCValue(handle);
230 // A new value replaces an existing one
231 void updateAPCValue(APCHandle* handle,
232 size_t size,
233 APCHandle* oldHandle,
234 size_t oldSize,
235 bool livePrimed,
236 bool expired) {
237 assert(handle && size > 0 && oldHandle && oldSize > 0);
238 auto diff = size - oldSize;
239 if (diff != 0) {
240 m_valueSize->addValue(diff);
241 if (livePrimed) {
242 m_livePrimedSize->addValue(diff);
245 if (m_detailedStats) {
246 m_detailedStats->updateAPCValue(handle, oldHandle, expired);
250 // A value is removed. The entry may still exists if it is a primed entry
251 void removeAPCValue(size_t size,
252 APCHandle* handle,
253 bool livePrimed,
254 bool expired) {
255 assert(size > 0);
256 m_valueSize->addValue(-size);
257 if (handle->isUncounted()) {
258 m_uncountedEntries->decrement();
260 if (livePrimed) {
261 m_livePrimedSize->addValue(-size);
262 m_livePrimedEntries->decrement();
264 if (m_detailedStats) {
265 m_detailedStats->removeAPCValue(handle, expired);
269 void addPendingDelete(size_t size) {
270 m_pendingDeleteSize->addValue(size);
273 void removePendingDelete(size_t size) {
274 m_pendingDeleteSize->addValue(-size);
277 private:
278 static std::unique_ptr<APCStats> s_apcStats;
280 private:
282 * Memory size counters
285 // Keep track of the overall memory usage from all live values
286 ServiceData::ExportedCounter* m_valueSize;
287 // Keep track of the overall memory usage of all keys
288 ServiceData::ExportedCounter* m_keySize;
289 // Size of data stored in the paged out in memory file. This
290 // is basically the size of the primed data that goes into the file
291 ServiceData::ExportedCounter* m_inFileSize;
292 // Size of primed data that is brought to life, that is, that goes
293 // into memory
294 ServiceData::ExportedCounter* m_livePrimedSize;
295 // Size of the APC data pending deletes in the treadmill
296 ServiceData::ExportedCounter* m_pendingDeleteSize;
299 * Number of entry counters
302 // Number of entries (keys)
303 ServiceData::ExportedCounter* m_entries;
304 // Number of primed entries
305 ServiceData::ExportedCounter* m_primedEntries;
306 // Number of live primed entries
307 ServiceData::ExportedCounter* m_livePrimedEntries;
308 // Number of uncounted entries
309 ServiceData::ExportedCounter* m_uncountedEntries;
310 // Number of uncounted blocks
311 ServiceData::ExportedCounter* m_uncountedBlocks;
313 // detailed info
314 APCDetailedStats* m_detailedStats;
320 #endif