Skip to content

Commit 78b6c78

Browse files
committed
Remove _api.h headers
Instead of having apc_cache.h which includes apc_cache_api.h, just define everything directly in apc_cache.h. I don't see a point in having two header pairs for everything.
1 parent 3e9e5df commit 78b6c78

11 files changed

+460
-573
lines changed

TECHNOTES.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ form of a quick-start guide to start hacking on APC.
4848

4949
apc_sma_malloc, apc_sma_realloc, apc_sma_strdup and apc_sma_free
5050
behave to the caller just like malloc, realloc, strdup and free, they are
51-
generated from macros in apc_sma_api.h
51+
generated from macros in apc_sma.h
5252

53-
Note: apc_sma_api.h is formatted and designed such that the SMA APCu
53+
Note: apc_sma.h is formatted and designed such that the SMA APCu
5454
uses can be used by third parties in their own extensions without
5555
interfering with, or consuming the resources of APCu itself
5656

apc_api.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
#define APC_API_H
2121

2222
#include "apc.h"
23-
#include "apc_lock_api.h"
24-
#include "apc_sma_api.h"
25-
#include "apc_cache_api.h"
23+
#include "apc_lock.h"
24+
#include "apc_sma.h"
25+
#include "apc_cache.h"
2626

2727
#endif

apc_cache.h

+240-2
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,247 @@
3434
#include "apc_lock.h"
3535
#include "TSRM.h"
3636

37-
#ifndef APC_CACHE_API_H
38-
# include "apc_cache_api.h"
37+
typedef struct apc_cache_slam_key_t apc_cache_slam_key_t;
38+
struct apc_cache_slam_key_t {
39+
zend_ulong hash; /* hash of the key */
40+
size_t len; /* length of the key */
41+
time_t mtime; /* creation time of this key */
42+
pid_t owner_pid; /* the pid that created this key */
43+
#ifdef ZTS
44+
void ***owner_thread; /* TSRMLS cache of thread that created this key */
3945
#endif
46+
};
47+
48+
/* {{{ struct definition: apc_cache_entry_t */
49+
typedef struct apc_cache_entry_t apc_cache_entry_t;
50+
struct apc_cache_entry_t {
51+
zend_string *key; /* entry key */
52+
zval val; /* the zval copied at store time */
53+
apc_cache_entry_t *next; /* next entry in linked list */
54+
zend_long ttl; /* the ttl on this specific entry */
55+
zend_long ref_count; /* the reference count of this entry */
56+
zend_long nhits; /* number of hits to this entry */
57+
time_t ctime; /* time entry was initialized */
58+
time_t mtime; /* the mtime of this cached entry */
59+
time_t dtime; /* time entry was removed from cache */
60+
time_t atime; /* time entry was last accessed */
61+
zend_long mem_size; /* memory used */
62+
};
63+
/* }}} */
64+
65+
/* {{{ struct definition: apc_cache_header_t
66+
Any values that must be shared among processes should go in here. */
67+
typedef struct _apc_cache_header_t {
68+
apc_lock_t lock; /* header lock */
69+
zend_long nhits; /* hit count */
70+
zend_long nmisses; /* miss count */
71+
zend_long ninserts; /* insert count */
72+
zend_long nexpunges; /* expunge count */
73+
zend_long nentries; /* entry count */
74+
zend_long mem_size; /* used */
75+
time_t stime; /* start time */
76+
unsigned short state; /* cache state */
77+
apc_cache_slam_key_t lastkey; /* last key inserted (not necessarily without error) */
78+
apc_cache_entry_t *gc; /* gc list */
79+
} apc_cache_header_t; /* }}} */
80+
81+
/* {{{ struct definition: apc_cache_t */
82+
typedef struct _apc_cache_t {
83+
void* shmaddr; /* process (local) address of shared cache */
84+
apc_cache_header_t* header; /* cache header (stored in SHM) */
85+
apc_cache_entry_t** slots; /* array of cache slots (stored in SHM) */
86+
apc_sma_t* sma; /* shared memory allocator */
87+
apc_serializer_t* serializer; /* serializer */
88+
zend_long nslots; /* number of slots in cache */
89+
zend_long gc_ttl; /* maximum time on GC list for a entry */
90+
zend_long ttl; /* if slot is needed and entry's access time is older than this ttl, remove it */
91+
zend_long smart; /* smart parameter for gc */
92+
zend_bool defend; /* defense parameter for runtime */
93+
} apc_cache_t; /* }}} */
94+
95+
/* {{{ typedef: apc_cache_updater_t */
96+
typedef zend_bool (*apc_cache_updater_t)(apc_cache_t*, apc_cache_entry_t*, void* data); /* }}} */
97+
98+
/* {{{ typedef: apc_cache_atomic_updater_t */
99+
typedef zend_bool (*apc_cache_atomic_updater_t)(apc_cache_t*, zend_long*, void* data); /* }}} */
100+
101+
/*
102+
* apc_cache_create creates the shared memory cache.
103+
*
104+
* This function should be called once per process per cache
105+
*
106+
* serializer for APCu is set by globals on MINIT and ensured with apc_cache_serializer
107+
* during execution. Using apc_cache_serializer avoids race conditions between MINIT/RINIT of
108+
* APCU and the third party serializer. API users can choose to leave this null to use default
109+
* PHP serializers, or search the list of serializers for the preferred serializer
110+
*
111+
* size_hint is a "hint" at the total number entries that will be expected.
112+
* It determines the physical size of the hash table. Passing 0 for
113+
* this argument will use a reasonable default value
114+
*
115+
* gc_ttl is the maximum time a cache entry may speed on the garbage
116+
* collection list. This is basically a work around for the inherent
117+
* unreliability of our reference counting mechanism (see apc_cache_release).
118+
*
119+
* ttl is the maximum time a cache entry can idle in a slot in case the slot
120+
* is needed. This helps in cleaning up the cache and ensuring that entries
121+
* hit frequently stay cached and ones not hit very often eventually disappear.
122+
*
123+
* for an explanation of smart, see apc_cache_default_expunge
124+
*
125+
* defend enables/disables slam defense for this particular cache
126+
*/
127+
PHP_APCU_API apc_cache_t* apc_cache_create(
128+
apc_sma_t* sma, apc_serializer_t* serializer, zend_long size_hint,
129+
zend_long gc_ttl, zend_long ttl, zend_long smart, zend_bool defend);
130+
/*
131+
* apc_cache_preload preloads the data at path into the specified cache
132+
*/
133+
PHP_APCU_API zend_bool apc_cache_preload(apc_cache_t* cache, const char* path);
134+
135+
/*
136+
* apc_cache_detach detaches from the shared memory cache and cleans up
137+
* local allocations. Under apache, this function can be safely called by
138+
* the child processes when they exit.
139+
*/
140+
PHP_APCU_API void apc_cache_detach(apc_cache_t* cache);
141+
142+
/*
143+
* apc_cache_clear empties a cache. This can safely be called at any time.
144+
*/
145+
PHP_APCU_API void apc_cache_clear(apc_cache_t* cache);
146+
147+
/*
148+
* apc_cache_store creates key, entry and context in which to make an insertion of val into the specified cache
149+
*/
150+
PHP_APCU_API zend_bool apc_cache_store(
151+
apc_cache_t* cache, zend_string *key, const zval *val,
152+
const int32_t ttl, const zend_bool exclusive);
153+
/*
154+
* apc_cache_update updates an entry in place. The updater function must not bailout.
155+
* The update is performed under write-lock and doesn't have to be atomic.
156+
*/
157+
PHP_APCU_API zend_bool apc_cache_update(
158+
apc_cache_t *cache, zend_string *key, apc_cache_updater_t updater, void *data,
159+
zend_bool insert_if_not_found, zend_long ttl);
160+
161+
/*
162+
* apc_cache_atomic_update_long updates an integer entry in place. The updater function must
163+
* perform the update atomically, as the update is performed under read-lock.
164+
*/
165+
PHP_APCU_API zend_bool apc_cache_atomic_update_long(
166+
apc_cache_t *cache, zend_string *key, apc_cache_atomic_updater_t updater, void *data,
167+
zend_bool insert_if_not_found, zend_long ttl);
168+
169+
/*
170+
* apc_cache_find searches for a cache entry by its hashed identifier,
171+
* and returns a pointer to the entry if found, NULL otherwise.
172+
*
173+
*/
174+
PHP_APCU_API apc_cache_entry_t* apc_cache_find(apc_cache_t* cache, zend_string *key, time_t t);
175+
176+
/*
177+
* apc_cache_fetch fetches an entry from the cache directly into dst
178+
*
179+
*/
180+
PHP_APCU_API zend_bool apc_cache_fetch(apc_cache_t* cache, zend_string *key, time_t t, zval *dst);
181+
182+
/*
183+
* apc_cache_exists searches for a cache entry by its hashed identifier,
184+
* and returns whether the entry exists.
185+
*/
186+
PHP_APCU_API zend_bool apc_cache_exists(apc_cache_t* cache, zend_string *key, time_t t);
187+
188+
/*
189+
* apc_cache_delete and apc_cache_delete finds an entry in the cache and deletes it.
190+
*/
191+
PHP_APCU_API zend_bool apc_cache_delete(apc_cache_t* cache, zend_string *key);
192+
193+
/* apc_cache_fetch_zval copies a cache entry value to be usable at runtime.
194+
*/
195+
PHP_APCU_API zend_bool apc_cache_entry_fetch_zval(
196+
apc_cache_t *cache, apc_cache_entry_t *entry, zval *dst);
197+
198+
/*
199+
* apc_cache_entry_release decrements the reference count associated with a cache
200+
* entry. Calling apc_cache_find automatically increments the reference count,
201+
* and this function must be called post-execution to return the count to its
202+
* original value. Failing to do so will prevent the entry from being
203+
* garbage-collected.
204+
*
205+
* entry is the cache entry whose ref count you want to decrement.
206+
*/
207+
PHP_APCU_API void apc_cache_entry_release(apc_cache_t *cache, apc_cache_entry_t *entry);
208+
209+
/*
210+
fetches information about the cache provided for userland status functions
211+
*/
212+
PHP_APCU_API zend_bool apc_cache_info(zval *info, apc_cache_t *cache, zend_bool limited);
213+
214+
/*
215+
fetches information about the key provided
216+
*/
217+
PHP_APCU_API void apc_cache_stat(apc_cache_t *cache, zend_string *key, zval *stat);
218+
219+
/*
220+
* apc_cache_defense: guard against slamming a key
221+
* will return true if the following conditions are met:
222+
* the key provided has a matching hash and length to the last key inserted into cache
223+
* the last key has a different owner
224+
* in ZTS mode, TSRM determines owner
225+
* in non-ZTS mode, PID determines owner
226+
* Note: this function sets the owner of key during execution
227+
*/
228+
PHP_APCU_API zend_bool apc_cache_defense(apc_cache_t *cache, zend_string *key, time_t t);
229+
230+
/*
231+
* apc_cache_serializer
232+
* sets the serializer for a cache, and by proxy contexts created for the cache
233+
* Note: this avoids race conditions between third party serializers and APCu
234+
*/
235+
PHP_APCU_API void apc_cache_serializer(apc_cache_t* cache, const char* name);
236+
237+
/*
238+
* The remaining functions allow a third party to reimplement expunge
239+
*
240+
* Look at the source of apc_cache_default_expunge for what is expected of this function
241+
*
242+
* The default behaviour of expunge is explained below, should no combination of those options
243+
* be suitable, you will need to reimplement apc_cache_default_expunge and pass it to your
244+
* call to apc_sma_api_impl, this will replace the default functionality.
245+
* The functions below you can use during your own implementation of expunge to gain more
246+
* control over how the expunge process works ...
247+
*
248+
* Note: beware of locking (copy it exactly), setting states is also important
249+
*/
250+
251+
/* {{{ apc_cache_default_expunge
252+
* Where smart is not set:
253+
* Where no ttl is set on cache:
254+
* 1) Perform cleanup of stale entries
255+
* 2) Expunge if available memory is less than sma->size/2
256+
* Where ttl is set on cache:
257+
* 1) Perform cleanup of stale entries
258+
* 2) If available memory if less than the size requested, run full expunge
259+
*
260+
* Where smart is set:
261+
* Where no ttl is set on cache:
262+
* 1) Perform cleanup of stale entries
263+
* 2) Expunge is available memory is less than size * smart
264+
* Where ttl is set on cache:
265+
* 1) Perform cleanup of stale entries
266+
* 2) If available memory if less than the size requested, run full expunge
267+
*
268+
* The TTL of an entry takes precedence over the TTL of a cache
269+
*/
270+
PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size);
271+
272+
/*
273+
* apc_cache_entry: generate and create or fetch an entry
274+
*
275+
* @see https://github.com/krakjoe/apcu/issues/142
276+
*/
277+
PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zend_string *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zend_long now, zval *return_value);
40278

41279
#endif
42280

0 commit comments

Comments
 (0)