2 +----------------------------------------------------------------------+
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"
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
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);
49 size_t getMemSize(const StringData
* string
) {
50 return string
->isStatic() ? 0 : sizeof(StringData
) + string
->size();
54 size_t getMemSize(const APCString
* string
) {
55 return sizeof(APCString
) + getMemSize(string
->getStringData());
58 //////////////////////////////////////////////////////////////////////
65 * Detailed stats about APC, controlled by a runtime config flag.
67 struct 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
);
85 void addType(const APCHandle
* handle
);
86 void removeType(const APCHandle
* handle
);
87 ServiceData::ExportedCounter
* counterFor(const APCHandle
*);
94 // Number of uncounted types, where uncounted means primitives
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.
157 static APCStats
& getAPCStats() {
158 return *s_apcStats
.get();
160 static bool IsCreated(){
161 return s_apcStats
!= nullptr;
164 static void Create();
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
) {
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
) {
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
) {
191 m_primedEntries
->increment();
195 // A value of a certain size was added to the primed set that is mapped
197 void addInFileValue(size_t size
) {
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();
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
,
233 APCHandle
* oldHandle
,
237 assert(handle
&& size
> 0 && oldHandle
&& oldSize
> 0);
238 auto diff
= size
- oldSize
;
240 m_valueSize
->addValue(diff
);
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
,
256 m_valueSize
->addValue(-size
);
257 if (handle
->isUncounted()) {
258 m_uncountedEntries
->decrement();
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
);
278 static std::unique_ptr
<APCStats
> s_apcStats
;
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
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
;
314 APCDetailedStats
* m_detailedStats
;