Codebase list php-yac / 34d4dc7
New upstream version 2.3.1++ Ondřej Surý 10 months ago
39 changed file(s) with 0 addition(s) and 5153 deletion(s). Raw diff Collapse all Expand all
+0
-136
package-5.xml less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <package packagerversion="1.9.4" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
2 <name>yac</name>
3 <channel>pecl.php.net</channel>
4 <summary>lockless user data cache</summary>
5 <description>yac is a shared memory user data cache for PHP. it can be used to replace APC or local memcached.
6
7 yac is lockless, that means, it is very fast, but there could be a chance you will get a wrong data(depends on how many key slots are allocated and how many keys are stored), so you&apos;d better make sure that your product is not very sensitive to that.</description>
8 <lead>
9 <name>Xinchen Hui</name>
10 <user>laruence</user>
11 <email>laruence@php.net</email>
12 <active>yes</active>
13 </lead>
14 <lead>
15 <name>Wei Dai</name>
16 <user>Demon</user>
17 <email>zxcvdavid@gmail.com</email>
18 <active>yes</active>
19 </lead>
20 <date>2014-10-22</date>
21 <time>14:03:48</time>
22 <version>
23 <release>0.9.2</release>
24 <api>0.9.2</api>
25 </version>
26 <stability>
27 <release>beta</release>
28 <api>beta</api>
29 </stability>
30 <license uri="http://www.php.net/license">PHP</license>
31 <notes>
32 - Add --with-system-fastlz option
33 </notes>
34 <contents>
35 <dir name="/">
36 <file md5sum="4e7edfc9fadfe1c6b97f21d9c8f416f0" name="storage/allocator/allocators/createfilemapping.c" role="src" />
37 <file md5sum="ee1c48e027892678bab8ec40c1efd7c5" name="storage/allocator/allocators/mmap.c" role="src" />
38 <file md5sum="d719e0643e649a89ad307ee41b82e0fd" name="storage/allocator/allocators/shm.c" role="src" />
39 <file md5sum="3874d9d9784c77ec4e3acd1cd0027f1f" name="storage/allocator/allocators/posix.c" role="src" />
40 <file md5sum="9594fb0a459719d3f9b354ee7105330f" name="storage/allocator/allocators/win32.c" role="src" />
41 <file md5sum="5aa4302988e0a26b7673741de836a4d2" name="storage/allocator/yac_allocator.h" role="src" />
42 <file md5sum="a550a7e1b7e8e888400133e6b4179a9b" name="storage/allocator/yac_allocator.c" role="src" />
43 <file md5sum="6a45b887b874e2341f0d4123016d2a50" name="storage/yac_storage.h" role="src" />
44 <file md5sum="e2c10004be49e913180b28d25e006b7b" name="storage/yac_storage.c" role="src" />
45 <file md5sum="543b3b1b8571c4b9c02eafee4a6f3fa3" name="compressor/fastlz/LICENSE" role="doc" />
46 <file md5sum="fa4d2340c50946340603066b02f7e6dd" name="compressor/fastlz/README.TXT" role="doc" />
47 <file md5sum="d49275e3dcc1d23d6ce0041648be8e14" name="compressor/fastlz/fastlz.h" role="src" />
48 <file md5sum="89384a08695fc238e9fbc41b0a14b5a7" name="compressor/fastlz/fastlz.c" role="src" />
49 <file md5sum="ad8dd340dfb67d0bd65a2ec608a49c1d" name="serializer/yac_serializer.h" role="src" />
50 <file md5sum="15fc773312442c45e1eb64bbb7efea63" name="serializer/php.c" role="src" />
51 <file md5sum="bcf581d9110dbe9caf28bfe6b70f9d90" name="serializer/msgpack.c" role="src" />
52 <file md5sum="4ff407df4fb138f1fdefa97a72e4769f" name="tests/001.phpt" role="test" />
53 <file md5sum="ad4a91d346d21c285ab21b4befcb538e" name="tests/002.phpt" role="test" />
54 <file md5sum="59f0d14be6b86915ded044110b9148da" name="tests/003.phpt" role="test" />
55 <file md5sum="69b6eab19f3e907097fd41ec6dfc024a" name="tests/004.phpt" role="test" />
56 <file md5sum="bf0340a9a20b5fe5dc300f3ec907a2dc" name="tests/005.phpt" role="test" />
57 <file md5sum="44354a5ac454a1bce3b00d8f5f9d6c4c" name="tests/006.phpt" role="test" />
58 <file md5sum="10ec3265916ceaeb4cdd56efce701eb0" name="tests/007.phpt" role="test" />
59 <file md5sum="f567e7205b3eb0ea757cb09dcd55cc7e" name="tests/008.phpt" role="test" />
60 <file md5sum="c9000c4ff1b00520cfb14c0e45508b30" name="tests/009.phpt" role="test" />
61 <file md5sum="1bf41dadf4a96d8730d37d89fb8257a6" name="tests/010.phpt" role="test" />
62 <file md5sum="0f47511cd434d57d01f78ad8a65a13cb" name="tests/011.phpt" role="test" />
63 <file md5sum="4c3a616f6563f090ccf781ed6a4671af" name="tests/012.phpt" role="test" />
64 <file md5sum="717d306b5ea2e5ae1aaef6894c3aaf2a" name="tests/013.phpt" role="test" />
65 <file md5sum="56f31a4a48c4d28a14e3939ce87abdb3" name="tests/014.phpt" role="test" />
66 <file md5sum="88ff06bab70e76cc0aa6e79aa4ee7e21" name="tests/015.phpt" role="test" />
67 <file md5sum="4c4242640be3dfdccf4b46600dbe3682" name="tests/issue012.phpt" role="test" />
68 <file md5sum="ac36c858a802d2d8c791b4de479adb59" name="config.w32" role="src" />
69 <file md5sum="dd34a70236f008af999de817b93a5e3a" name="LICENSE" role="doc" />
70 <file md5sum="a3392e4d97b0d057a57453dbbad0313d" name="CREDITS" role="doc" />
71 <file md5sum="43345d5aee118e3bbc9427e5b0abbef9" name="config.m4" role="src" />
72 <file md5sum="32570599c961b469ee64b816231b58b9" name="yac.c" role="src" />
73 <file md5sum="0cafee01376ba581bf522a7764263bcd" name="php_yac.h" role="src" />
74 </dir>
75 </contents>
76 <dependencies>
77 <required>
78 <php>
79 <min>5.2.0</min>
80 </php>
81 <pearinstaller>
82 <min>1.4.0</min>
83 </pearinstaller>
84 </required>
85 </dependencies>
86 <providesextension>yac</providesextension>
87 <extsrcrelease />
88 <changelog>
89 <release>
90 <date>2014-10-22</date>
91 <version>
92 <release>0.9.2</release>
93 <api>0.9.2</api>
94 </version>
95 <stability>
96 <release>beta</release>
97 <api>beta</api>
98 </stability>
99 <license uri="http://www.php.net/license">PHP License</license>
100 <notes>
101 - Add --with-system-fastlz option
102 </notes>
103 </release>
104 <release>
105 <date>2014-07-25</date>
106 <version>
107 <release>0.9.1</release>
108 <api>0.9.1</api>
109 </version>
110 <stability>
111 <release>beta</release>
112 <api>beta</api>
113 </stability>
114 <license uri="http://www.php.net/license">PHP License</license>
115 <notes>
116 - Try to fix windows build
117 </notes>
118 </release>
119 <release>
120 <date>2014-07-24</date>
121 <version>
122 <release>0.9.0</release>
123 <api>0.9.0</api>
124 </version>
125 <stability>
126 <release>beta</release>
127 <api>beta</api>
128 </stability>
129 <license uri="http://www.php.net/license">PHP License</license>
130 <notes>
131 - first release
132 </notes>
133 </release>
134 </changelog>
135 </package>
+0
-1
yac-0.9.2/CREDITS less more
0 yac
+0
-68
yac-0.9.2/LICENSE less more
0 --------------------------------------------------------------------
1 The PHP License, version 3.01
2 Copyright (c) 1999 - 2011 The PHP Group. All rights reserved.
3 --------------------------------------------------------------------
4
5 Redistribution and use in source and binary forms, with or without
6 modification, is permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 3. The name "PHP" must not be used to endorse or promote products
18 derived from this software without prior written permission. For
19 written permission, please contact group@php.net.
20
21 4. Products derived from this software may not be called "PHP", nor
22 may "PHP" appear in their name, without prior written permission
23 from group@php.net. You may indicate that your software works in
24 conjunction with PHP by saying "Foo for PHP" instead of calling
25 it "PHP Foo" or "phpfoo"
26
27 5. The PHP Group may publish revised and/or new versions of the
28 license from time to time. Each version will be given a
29 distinguishing version number.
30 Once covered code has been published under a particular version
31 of the license, you may always continue to use it under the terms
32 of that version. You may also choose to use such covered code
33 under the terms of any subsequent version of the license
34 published by the PHP Group. No one other than the PHP Group has
35 the right to modify the terms applicable to covered code created
36 under this License.
37
38 6. Redistributions of any form whatsoever must retain the following
39 acknowledgment:
40 "This product includes PHP software, freely available from
41 <http://www.php.net/software/>".
42
43 THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
44 ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
45 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
46 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
47 DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
48 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 OF THE POSSIBILITY OF SUCH DAMAGE.
55
56 --------------------------------------------------------------------
57
58 This software consists of voluntary contributions made by many
59 individuals on behalf of the PHP Group.
60
61 The PHP Group can be contacted via Email at group@php.net.
62
63 For more information on the PHP Group and the PHP project,
64 please see <http://www.php.net>.
65
66 PHP includes the Zend Engine, freely available at
67 <http://www.zend.com>.
+0
-24
yac-0.9.2/compressor/fastlz/LICENSE less more
0 FastLZ - lightning-fast lossless compression library
1
2 Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
3 Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
4 Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23
+0
-75
yac-0.9.2/compressor/fastlz/README.TXT less more
0 FastLZ - lightning-fast lossless compression library
1
2 Author: Ariya Hidayat
3 Official website: http://www.fastlz.org
4
5 FastLZ is distributed using the MIT license, see file LICENSE
6 for details.
7
8 FastLZ consists of two files: fastlz.h and fastlz.c. Just add these
9 files to your project in order to use FastLZ. For information on
10 compression and decompression routines, see fastlz.h.
11
12 A simple file compressor called 6pack is included as an example
13 on how to use FastLZ. The corresponding decompressor is 6unpack.
14
15 To compile using GCC:
16
17 gcc -o 6pack 6pack.c fastlz.c
18 gcc -o 6unpack 6unpack.c fastlz.c
19
20 To compile using MinGW:
21
22 mingw32-gcc -o 6pack 6pack.c fastlz.c
23 mingw32-gcc -o 6unpack 6unpack.c fastlz.c
24
25 To compile using Microsoft Visual C++:
26
27 cl 6pack.c fastlz.c
28 cl 6unpack.c fastlz.c
29
30 To compile using Borland C++:
31
32 bcc32 6pack.c fastlz.c
33 bcc32 6unpack.c fastlz.c
34
35 To compile using OpenWatcom C/C++:
36
37 cl386 6pack.c fastlz.c
38 cl386 6unpack.c fastlz.c
39
40 To compile using Intel C++ compiler for Windows:
41
42 icl 6pack.c fastlz.c
43 icl 6unpack.c fastlz.c
44
45 To compile using Intel C++ compiler for Linux:
46
47 icc -o 6pack 6pack.c fastlz.c
48 icc -o 6unpack 6unpack.c fastlz.c
49
50 To compile 6pack using LCC-Win32:
51
52 lc 6pack.c fastlz.c
53 lc 6unpack.c fastlz.c
54
55 To compile 6pack using Pelles C:
56
57 pocc 6pack.c
58 pocc 6unpack.c
59 pocc fastlz.c
60 polink 6pack.obj fastlz.obj
61 polink 6unpack.obj fastlz.obj
62
63 For speed optimization, always use proper compile flags for optimization options.
64 Typical compiler flags are given below:
65
66 * GCC (pre 4.2): -march=pentium -O3 -fomit-frame-pointer -mtune=pentium
67 * GCC 4.2 or later: -march=pentium -O3 -fomit-frame-pointer -mtune=generic
68 * Digital Mars C/C++: -o+all -5
69 * Intel C++ (Windows): /O3 /Qipo
70 * Intel C++ (Linux): -O2 -march=pentium -mtune=pentium
71 * Borland C++: -O2 -5
72 * LCC-Win32: -O
73 * Pelles C: /O2
74
+0
-551
yac-0.9.2/compressor/fastlz/fastlz.c less more
0 /*
1 FastLZ - lightning-fast lossless compression library
2
3 Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
4 Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
5 Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.
24 */
25
26 #if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
27
28 /*
29 * Always check for bound when decompressing.
30 * Generally it is best to leave it defined.
31 */
32 #define FASTLZ_SAFE
33
34 /*
35 * Give hints to the compiler for branch prediction optimization.
36 */
37 #if defined(__GNUC__) && (__GNUC__ > 2)
38 #define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
39 #define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
40 #else
41 #define FASTLZ_EXPECT_CONDITIONAL(c) (c)
42 #define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
43 #endif
44
45 /*
46 * Use inlined functions for supported systems.
47 */
48 #if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
49 #define FASTLZ_INLINE inline
50 #elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
51 #define FASTLZ_INLINE __inline
52 #else
53 #define FASTLZ_INLINE
54 #endif
55
56 /*
57 * Prevent accessing more than 8-bit at once, except on x86 architectures.
58 */
59 #if !defined(FASTLZ_STRICT_ALIGN)
60 #define FASTLZ_STRICT_ALIGN
61 #if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
62 #undef FASTLZ_STRICT_ALIGN
63 #elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
64 #undef FASTLZ_STRICT_ALIGN
65 #elif defined(_M_IX86) /* Intel, MSVC */
66 #undef FASTLZ_STRICT_ALIGN
67 #elif defined(__386)
68 #undef FASTLZ_STRICT_ALIGN
69 #elif defined(_X86_) /* MinGW */
70 #undef FASTLZ_STRICT_ALIGN
71 #elif defined(__I86__) /* Digital Mars */
72 #undef FASTLZ_STRICT_ALIGN
73 #endif
74 #endif
75
76 /*
77 * FIXME: use preprocessor magic to set this on different platforms!
78 */
79 typedef unsigned char flzuint8;
80 typedef unsigned short flzuint16;
81 typedef unsigned int flzuint32;
82
83 /* prototypes */
84 int fastlz_compress(const void* input, int length, void* output);
85 int fastlz_compress_level(int level, const void* input, int length, void* output);
86 int fastlz_decompress(const void* input, int length, void* output, int maxout);
87
88 #define MAX_COPY 32
89 #define MAX_LEN 264 /* 256 + 8 */
90 #define MAX_DISTANCE 8192
91
92 #if !defined(FASTLZ_STRICT_ALIGN)
93 #define FASTLZ_READU16(p) *((const flzuint16*)(p))
94 #else
95 #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
96 #endif
97
98 #define HASH_LOG 13
99 #define HASH_SIZE (1<< HASH_LOG)
100 #define HASH_MASK (HASH_SIZE-1)
101 #define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
102
103 #undef FASTLZ_LEVEL
104 #define FASTLZ_LEVEL 1
105
106 #undef FASTLZ_COMPRESSOR
107 #undef FASTLZ_DECOMPRESSOR
108 #define FASTLZ_COMPRESSOR fastlz1_compress
109 #define FASTLZ_DECOMPRESSOR fastlz1_decompress
110 static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
111 static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
112 #include "fastlz.c"
113
114 #undef FASTLZ_LEVEL
115 #define FASTLZ_LEVEL 2
116
117 #undef MAX_DISTANCE
118 #define MAX_DISTANCE 8191
119 #define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
120
121 #undef FASTLZ_COMPRESSOR
122 #undef FASTLZ_DECOMPRESSOR
123 #define FASTLZ_COMPRESSOR fastlz2_compress
124 #define FASTLZ_DECOMPRESSOR fastlz2_decompress
125 static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
126 static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
127 #include "fastlz.c"
128
129 int fastlz_compress(const void* input, int length, void* output)
130 {
131 /* for short block, choose fastlz1 */
132 if(length < 65536)
133 return fastlz1_compress(input, length, output);
134
135 /* else... */
136 return fastlz2_compress(input, length, output);
137 }
138
139 int fastlz_decompress(const void* input, int length, void* output, int maxout)
140 {
141 /* magic identifier for compression level */
142 int level = ((*(const flzuint8*)input) >> 5) + 1;
143
144 if(level == 1)
145 return fastlz1_decompress(input, length, output, maxout);
146 if(level == 2)
147 return fastlz2_decompress(input, length, output, maxout);
148
149 /* unknown level, trigger error */
150 return 0;
151 }
152
153 int fastlz_compress_level(int level, const void* input, int length, void* output)
154 {
155 if(level == 1)
156 return fastlz1_compress(input, length, output);
157 if(level == 2)
158 return fastlz2_compress(input, length, output);
159
160 return 0;
161 }
162
163 #else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
164
165 static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
166 {
167 const flzuint8* ip = (const flzuint8*) input;
168 const flzuint8* ip_bound = ip + length - 2;
169 const flzuint8* ip_limit = ip + length - 12;
170 flzuint8* op = (flzuint8*) output;
171
172 const flzuint8* htab[HASH_SIZE];
173 const flzuint8** hslot;
174 flzuint32 hval;
175
176 flzuint32 copy;
177
178 /* sanity check */
179 if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
180 {
181 if(length)
182 {
183 /* create literal copy only */
184 *op++ = length-1;
185 ip_bound++;
186 while(ip <= ip_bound)
187 *op++ = *ip++;
188 return length+1;
189 }
190 else
191 return 0;
192 }
193
194 /* initializes hash table */
195 for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
196 *hslot = ip;
197
198 /* we start with literal copy */
199 copy = 2;
200 *op++ = MAX_COPY-1;
201 *op++ = *ip++;
202 *op++ = *ip++;
203
204 /* main loop */
205 while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
206 {
207 const flzuint8* ref;
208 flzuint32 distance;
209
210 /* minimum match length */
211 flzuint32 len = 3;
212
213 /* comparison starting-point */
214 const flzuint8* anchor = ip;
215
216 /* check for a run */
217 #if FASTLZ_LEVEL==2
218 if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
219 {
220 distance = 1;
221 ip += 3;
222 ref = anchor - 1 + 3;
223 goto match;
224 }
225 #endif
226
227 /* find potential match */
228 HASH_FUNCTION(hval,ip);
229 hslot = htab + hval;
230 ref = htab[hval];
231
232 /* calculate distance to the match */
233 distance = anchor - ref;
234
235 /* update hash table */
236 *hslot = anchor;
237
238 /* is this a match? check the first 3 bytes */
239 if(distance==0 ||
240 #if FASTLZ_LEVEL==1
241 (distance >= MAX_DISTANCE) ||
242 #else
243 (distance >= MAX_FARDISTANCE) ||
244 #endif
245 *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
246 goto literal;
247
248 #if FASTLZ_LEVEL==2
249 /* far, needs at least 5-byte match */
250 if(distance >= MAX_DISTANCE)
251 {
252 if(*ip++ != *ref++ || *ip++!= *ref++)
253 goto literal;
254 len += 2;
255 }
256
257 match:
258 #endif
259
260 /* last matched byte */
261 ip = anchor + len;
262
263 /* distance is biased */
264 distance--;
265
266 if(!distance)
267 {
268 /* zero distance means a run */
269 flzuint8 x = ip[-1];
270 while(ip < ip_bound)
271 if(*ref++ != x) break; else ip++;
272 }
273 else
274 for(;;)
275 {
276 /* safe because the outer check against ip limit */
277 if(*ref++ != *ip++) break;
278 if(*ref++ != *ip++) break;
279 if(*ref++ != *ip++) break;
280 if(*ref++ != *ip++) break;
281 if(*ref++ != *ip++) break;
282 if(*ref++ != *ip++) break;
283 if(*ref++ != *ip++) break;
284 if(*ref++ != *ip++) break;
285 while(ip < ip_bound)
286 if(*ref++ != *ip++) break;
287 break;
288 }
289
290 /* if we have copied something, adjust the copy count */
291 if(copy)
292 /* copy is biased, '0' means 1 byte copy */
293 *(op-copy-1) = copy-1;
294 else
295 /* back, to overwrite the copy count */
296 op--;
297
298 /* reset literal counter */
299 copy = 0;
300
301 /* length is biased, '1' means a match of 3 bytes */
302 ip -= 3;
303 len = ip - anchor;
304
305 /* encode the match */
306 #if FASTLZ_LEVEL==2
307 if(distance < MAX_DISTANCE)
308 {
309 if(len < 7)
310 {
311 *op++ = (len << 5) + (distance >> 8);
312 *op++ = (distance & 255);
313 }
314 else
315 {
316 *op++ = (7 << 5) + (distance >> 8);
317 for(len-=7; len >= 255; len-= 255)
318 *op++ = 255;
319 *op++ = len;
320 *op++ = (distance & 255);
321 }
322 }
323 else
324 {
325 /* far away, but not yet in the another galaxy... */
326 if(len < 7)
327 {
328 distance -= MAX_DISTANCE;
329 *op++ = (len << 5) + 31;
330 *op++ = 255;
331 *op++ = distance >> 8;
332 *op++ = distance & 255;
333 }
334 else
335 {
336 distance -= MAX_DISTANCE;
337 *op++ = (7 << 5) + 31;
338 for(len-=7; len >= 255; len-= 255)
339 *op++ = 255;
340 *op++ = len;
341 *op++ = 255;
342 *op++ = distance >> 8;
343 *op++ = distance & 255;
344 }
345 }
346 #else
347
348 if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
349 while(len > MAX_LEN-2)
350 {
351 *op++ = (7 << 5) + (distance >> 8);
352 *op++ = MAX_LEN - 2 - 7 -2;
353 *op++ = (distance & 255);
354 len -= MAX_LEN-2;
355 }
356
357 if(len < 7)
358 {
359 *op++ = (len << 5) + (distance >> 8);
360 *op++ = (distance & 255);
361 }
362 else
363 {
364 *op++ = (7 << 5) + (distance >> 8);
365 *op++ = len - 7;
366 *op++ = (distance & 255);
367 }
368 #endif
369
370 /* update the hash at match boundary */
371 HASH_FUNCTION(hval,ip);
372 htab[hval] = ip++;
373 HASH_FUNCTION(hval,ip);
374 htab[hval] = ip++;
375
376 /* assuming literal copy */
377 *op++ = MAX_COPY-1;
378
379 continue;
380
381 literal:
382 *op++ = *anchor++;
383 ip = anchor;
384 copy++;
385 if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
386 {
387 copy = 0;
388 *op++ = MAX_COPY-1;
389 }
390 }
391
392 /* left-over as literal copy */
393 ip_bound++;
394 while(ip <= ip_bound)
395 {
396 *op++ = *ip++;
397 copy++;
398 if(copy == MAX_COPY)
399 {
400 copy = 0;
401 *op++ = MAX_COPY-1;
402 }
403 }
404
405 /* if we have copied something, adjust the copy length */
406 if(copy)
407 *(op-copy-1) = copy-1;
408 else
409 op--;
410
411 #if FASTLZ_LEVEL==2
412 /* marker for fastlz2 */
413 *(flzuint8*)output |= (1 << 5);
414 #endif
415
416 return op - (flzuint8*)output;
417 }
418
419 static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
420 {
421 const flzuint8* ip = (const flzuint8*) input;
422 const flzuint8* ip_limit = ip + length;
423 flzuint8* op = (flzuint8*) output;
424 flzuint8* op_limit = op + maxout;
425 flzuint32 ctrl = (*ip++) & 31;
426 int loop = 1;
427
428 do
429 {
430 const flzuint8* ref = op;
431 flzuint32 len = ctrl >> 5;
432 flzuint32 ofs = (ctrl & 31) << 8;
433
434 if(ctrl >= 32)
435 {
436 #if FASTLZ_LEVEL==2
437 flzuint8 code;
438 #endif
439 len--;
440 ref -= ofs;
441 if (len == 7-1)
442 #if FASTLZ_LEVEL==1
443 len += *ip++;
444 ref -= *ip++;
445 #else
446 do
447 {
448 code = *ip++;
449 len += code;
450 } while (code==255);
451 code = *ip++;
452 ref -= code;
453
454 /* match from 16-bit distance */
455 if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
456 if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
457 {
458 ofs = (*ip++) << 8;
459 ofs += *ip++;
460 ref = op - ofs - MAX_DISTANCE;
461 }
462 #endif
463
464 #ifdef FASTLZ_SAFE
465 if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
466 return 0;
467
468 if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
469 return 0;
470 #endif
471
472 if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
473 ctrl = *ip++;
474 else
475 loop = 0;
476
477 if(ref == op)
478 {
479 /* optimize copy for a run */
480 flzuint8 b = ref[-1];
481 *op++ = b;
482 *op++ = b;
483 *op++ = b;
484 for(; len; --len)
485 *op++ = b;
486 }
487 else
488 {
489 #if !defined(FASTLZ_STRICT_ALIGN)
490 const flzuint16* p;
491 flzuint16* q;
492 #endif
493 /* copy from reference */
494 ref--;
495 *op++ = *ref++;
496 *op++ = *ref++;
497 *op++ = *ref++;
498
499 #if !defined(FASTLZ_STRICT_ALIGN)
500 /* copy a byte, so that now it's word aligned */
501 if(len & 1)
502 {
503 *op++ = *ref++;
504 len--;
505 }
506
507 /* copy 16-bit at once */
508 q = (flzuint16*) op;
509 op += len;
510 p = (const flzuint16*) ref;
511 for(len>>=1; len > 4; len-=4)
512 {
513 *q++ = *p++;
514 *q++ = *p++;
515 *q++ = *p++;
516 *q++ = *p++;
517 }
518 for(; len; --len)
519 *q++ = *p++;
520 #else
521 for(; len; --len)
522 *op++ = *ref++;
523 #endif
524 }
525 }
526 else
527 {
528 ctrl++;
529 #ifdef FASTLZ_SAFE
530 if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
531 return 0;
532 if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
533 return 0;
534 #endif
535
536 *op++ = *ip++;
537 for(--ctrl; ctrl; ctrl--)
538 *op++ = *ip++;
539
540 loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
541 if(loop)
542 ctrl = *ip++;
543 }
544 }
545 while(FASTLZ_EXPECT_CONDITIONAL(loop));
546
547 return op - (flzuint8*)output;
548 }
549
550 #endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
+0
-100
yac-0.9.2/compressor/fastlz/fastlz.h less more
0 /*
1 FastLZ - lightning-fast lossless compression library
2
3 Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
4 Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
5 Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.
24 */
25
26 #ifndef FASTLZ_H
27 #define FASTLZ_H
28
29 #define FASTLZ_VERSION 0x000100
30
31 #define FASTLZ_VERSION_MAJOR 0
32 #define FASTLZ_VERSION_MINOR 0
33 #define FASTLZ_VERSION_REVISION 0
34
35 #define FASTLZ_VERSION_STRING "0.1.0"
36
37 #if defined (__cplusplus)
38 extern "C" {
39 #endif
40
41 /**
42 Compress a block of data in the input buffer and returns the size of
43 compressed block. The size of input buffer is specified by length. The
44 minimum input buffer size is 16.
45
46 The output buffer must be at least 5% larger than the input buffer
47 and can not be smaller than 66 bytes.
48
49 If the input is not compressible, the return value might be larger than
50 length (input buffer size).
51
52 The input buffer and the output buffer can not overlap.
53 */
54
55 int fastlz_compress(const void* input, int length, void* output);
56
57 /**
58 Decompress a block of compressed data and returns the size of the
59 decompressed block. If error occurs, e.g. the compressed data is
60 corrupted or the output buffer is not large enough, then 0 (zero)
61 will be returned instead.
62
63 The input buffer and the output buffer can not overlap.
64
65 Decompression is memory safe and guaranteed not to write the output buffer
66 more than what is specified in maxout.
67 */
68
69 int fastlz_decompress(const void* input, int length, void* output, int maxout);
70
71 /**
72 Compress a block of data in the input buffer and returns the size of
73 compressed block. The size of input buffer is specified by length. The
74 minimum input buffer size is 16.
75
76 The output buffer must be at least 5% larger than the input buffer
77 and can not be smaller than 66 bytes.
78
79 If the input is not compressible, the return value might be larger than
80 length (input buffer size).
81
82 The input buffer and the output buffer can not overlap.
83
84 Compression level can be specified in parameter level. At the moment,
85 only level 1 and level 2 are supported.
86 Level 1 is the fastest compression and generally useful for short data.
87 Level 2 is slightly slower but it gives better compression ratio.
88
89 Note that the compressed data, regardless of the level, can always be
90 decompressed using the function fastlz_decompress above.
91 */
92
93 int fastlz_compress_level(int level, const void* input, int length, void* output);
94
95 #if defined (__cplusplus)
96 }
97 #endif
98
99 #endif /* FASTLZ_H */
+0
-212
yac-0.9.2/config.m4 less more
0 dnl $Id$
1 dnl config.m4 for extension yac
2
3 PHP_ARG_ENABLE(yac, whether to enable yac support,
4 [ --enable-yac Enable yac support])
5
6 PHP_ARG_WITH(system-fastlz, wheter to use system FastLZ bibrary,
7 [ --with-system-fastlz Use system FastLZ bibrary], no, no)
8
9 dnl PHP_ARG_ENABLE(yac, whether to use msgpack as serializer,
10 dnl [ --enable-msgpack Use Messagepack as serializer])
11
12 dnl copied from Zend Optimizer Plus
13 AC_MSG_CHECKING(for sysvipc shared memory support)
14 AC_TRY_RUN([
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <sys/ipc.h>
18 #include <sys/shm.h>
19 #include <unistd.h>
20 #include <string.h>
21
22 int main() {
23 pid_t pid;
24 int status;
25 int ipc_id;
26 char *shm;
27 struct shmid_ds shmbuf;
28
29 ipc_id = shmget(IPC_PRIVATE, 4096, (IPC_CREAT | SHM_R | SHM_W));
30 if (ipc_id == -1) {
31 return 1;
32 }
33
34 shm = shmat(ipc_id, NULL, 0);
35 if (shm == (void *)-1) {
36 shmctl(ipc_id, IPC_RMID, NULL);
37 return 2;
38 }
39
40 if (shmctl(ipc_id, IPC_STAT, &shmbuf) != 0) {
41 shmdt(shm);
42 shmctl(ipc_id, IPC_RMID, NULL);
43 return 3;
44 }
45
46 shmbuf.shm_perm.uid = getuid();
47 shmbuf.shm_perm.gid = getgid();
48 shmbuf.shm_perm.mode = 0600;
49
50 if (shmctl(ipc_id, IPC_SET, &shmbuf) != 0) {
51 shmdt(shm);
52 shmctl(ipc_id, IPC_RMID, NULL);
53 return 4;
54 }
55
56 shmctl(ipc_id, IPC_RMID, NULL);
57
58 strcpy(shm, "hello");
59
60 pid = fork();
61 if (pid < 0) {
62 return 5;
63 } else if (pid == 0) {
64 strcpy(shm, "bye");
65 return 6;
66 }
67 if (wait(&status) != pid) {
68 return 7;
69 }
70 if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
71 return 8;
72 }
73 if (strcmp(shm, "bye") != 0) {
74 return 9;
75 }
76 return 0;
77 }
78 ],dnl
79 AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
80 msg=yes,msg=no,msg=no)
81 AC_MSG_RESULT([$msg])
82
83 AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support)
84 AC_TRY_RUN([
85 #include <sys/types.h>
86 #include <sys/wait.h>
87 #include <sys/mman.h>
88 #include <unistd.h>
89 #include <string.h>
90
91 #ifndef MAP_ANON
92 # ifdef MAP_ANONYMOUS
93 # define MAP_ANON MAP_ANONYMOUS
94 # endif
95 #endif
96 #ifndef MAP_FAILED
97 # define MAP_FAILED ((void*)-1)
98 #endif
99
100 int main() {
101 pid_t pid;
102 int status;
103 char *shm;
104
105 shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
106 if (shm == MAP_FAILED) {
107 return 1;
108 }
109
110 strcpy(shm, "hello");
111
112 pid = fork();
113 if (pid < 0) {
114 return 5;
115 } else if (pid == 0) {
116 strcpy(shm, "bye");
117 return 6;
118 }
119 if (wait(&status) != pid) {
120 return 7;
121 }
122 if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
123 return 8;
124 }
125 if (strcmp(shm, "bye") != 0) {
126 return 9;
127 }
128 return 0;
129 }
130 ],dnl
131 AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
132 msg=yes,msg=no,msg=no)
133 AC_MSG_RESULT([$msg])
134
135 AC_MSG_CHECKING(for mmap() using /dev/zero shared memory support)
136 AC_TRY_RUN([
137 #include <sys/types.h>
138 #include <sys/wait.h>
139 #include <sys/mman.h>
140 #include <sys/stat.h>
141 #include <fcntl.h>
142 #include <unistd.h>
143 #include <string.h>
144
145 #ifndef MAP_FAILED
146 # define MAP_FAILED ((void*)-1)
147 #endif
148
149 int main() {
150 pid_t pid;
151 int status;
152 int fd;
153 char *shm;
154
155 fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
156 if (fd == -1) {
157 return 1;
158 }
159
160 shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
161 if (shm == MAP_FAILED) {
162 return 2;
163 }
164
165 strcpy(shm, "hello");
166
167 pid = fork();
168 if (pid < 0) {
169 return 5;
170 } else if (pid == 0) {
171 strcpy(shm, "bye");
172 return 6;
173 }
174 if (wait(&status) != pid) {
175 return 7;
176 }
177 if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
178 return 8;
179 }
180 if (strcmp(shm, "bye") != 0) {
181 return 9;
182 }
183 return 0;
184 }
185 ],dnl
186 AC_DEFINE(HAVE_SHM_MMAP_ZERO, 1, [Define if you have mmap("/dev/zero") SHM support])
187 msg=yes,msg=no,msg=no)
188 AC_MSG_RESULT([$msg])
189
190 dnl if test "$PHP_MSGPACK" != "no"; then
191 dnl AC_DEFINE(ENABLE_MSGPACK,1,[enable msgpack packager])
192 dnl ifdef([PHP_ADD_EXTENSION_DEP],
193 dnl [
194 dnl PHP_ADD_EXTENSION_DEP(yac, msgpack, true)
195 dnl ])
196 dnl fi
197
198 YAC_FILES="yac.c storage/yac_storage.c storage/allocator/yac_allocator.c storage/allocator/allocators/shm.c storage/allocator/allocators/mmap.c serializer/php.c serializer/msgpack.c"
199 if test "$PHP_SYSTEM_FASTLZ" != "no"; then
200 AC_CHECK_HEADERS([fastlz.h])
201 PHP_CHECK_LIBRARY(fastlz, fastlz_compress,
202 [PHP_ADD_LIBRARY(fastlz, 1, YAC_SHARED_LIBADD)],
203 [AC_MSG_ERROR(FastLZ library not found)])
204 else
205 YAC_FILES="${YAC_FILES} compressor/fastlz/fastlz.c"
206 fi
207
208 if test "$PHP_YAC" != "no"; then
209 PHP_SUBST(YAC_SHARED_LIBADD)
210 PHP_NEW_EXTENSION(yac, ${YAC_FILES}, $ext_shared)
211 fi
+0
-28
yac-0.9.2/config.w32 less more
0 // $Id$
1 // vim:ft=javascript
2
3 ARG_ENABLE("yac", "enable yac support", "no");
4
5 if (PHP_YAC != "no") {
6 if( CHECK_HEADER_ADD_INCLUDE("fastlz.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\compressor\\fastlz") &&
7 CHECK_HEADER_ADD_INCLUDE("yac_serializer.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\serializer") &&
8 CHECK_HEADER_ADD_INCLUDE("yac_storage.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\storage") &&
9 CHECK_HEADER_ADD_INCLUDE("yac_allocator.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\storage\\allocator")) {
10
11 EXTENSION("yac", "yac.c");
12
13 ADD_SOURCES(configure_module_dirname + "\\compressor\\fastlz", "fastlz.c", "yac");
14 ADD_SOURCES(configure_module_dirname + "\\serializer", "php.c", "yac");
15 ADD_SOURCES(configure_module_dirname + "\\storage", "yac_storage.c", "yac");
16 ADD_SOURCES(configure_module_dirname + "\\storage\\allocator", "yac_allocator.c", "yac");
17 ADD_SOURCES(configure_module_dirname + "\\storage\\allocator\\allocators", "createfilemapping.c", "yac");
18
19 AC_DEFINE('HAVE_YAC', 1, 'Have yac library');
20
21 ADD_FLAG("CFLAGS_YAC", ' /I "' + configure_module_dirname + '" ');
22
23 } else {
24 WARNING("yac not enabled, headers not found");
25 }
26 }
27
+0
-80
yac-0.9.2/php_yac.h less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #ifndef PHP_YAC_H
21 #define PHP_YAC_H
22
23 extern zend_module_entry yac_module_entry;
24 #define phpext_yac_ptr &yac_module_entry
25
26 #ifdef PHP_WIN32
27 #define PHP_YAC_API __declspec(dllexport)
28 #else
29 #define PHP_YAC_API
30 #endif
31
32 #ifdef ZTS
33 #include "TSRM.h"
34 #endif
35
36 #define PHP_YAC_VERSION "0.9.2"
37
38 #define YAC_CLASS_PROPERTY_PREFIX "_prefix"
39 #define YAC_ENTRY_COMPRESSED 0x0020
40 #define YAC_ENTRY_TYPE_MASK 0x1f
41 #define YAC_ENTRY_ORIG_LEN_SHIT 6
42 #define YAC_ENTRY_MAX_ORIG_LEN ((1U << ((sizeof(int)*8 - YAC_ENTRY_ORIG_LEN_SHIT))) - 1)
43 #define YAC_MIN_COMPRESS_THRESHOLD 1024
44
45 ZEND_BEGIN_MODULE_GLOBALS(yac)
46 zend_bool enable;
47 zend_bool debug;
48 size_t k_msize;
49 size_t v_msize;
50 ulong compress_threshold;
51 zend_bool enable_cli;
52 #ifdef PHP_WIN32
53 char *mmap_base;
54 #endif
55 ZEND_END_MODULE_GLOBALS(yac)
56
57 PHP_MINIT_FUNCTION(yac);
58 PHP_MSHUTDOWN_FUNCTION(yac);
59 PHP_RINIT_FUNCTION(yac);
60 PHP_RSHUTDOWN_FUNCTION(yac);
61 PHP_MINFO_FUNCTION(yac);
62
63 #ifdef ZTS
64 #define YAC_G(v) TSRMG(yac_globals_id, zend_yac_globals *, v)
65 extern int yac_globals_id;
66 #else
67 #define YAC_G(v) (yac_globals.v)
68 extern zend_yac_globals yac_globals;
69 #endif
70
71 #endif /* PHP_YAC_H */
72 /*
73 * Local variables:
74 * tab-width: 4
75 * c-basic-offset: 4
76 * End:
77 * vim600: noet sw=4 ts=4 fdm=marker
78 * vim<600: noet sw=4 ts=4
79 */
+0
-58
yac-0.9.2/serializer/msgpack.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yar - Light, concurrent RPC framework |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2012-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 | Zhenyu Zhang <zhangzhenyu@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #ifdef ENABLE_MSGPACK
26
27 #include "php.h"
28 #include "ext/standard/php_smart_str.h" /* for smart_str */
29
30 #include "yac_serializer.h"
31
32 extern void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC);
33 extern void php_msgpack_unserialize(zval *return_value, char *str, size_t str_len TSRMLS_DC);
34
35 int yac_serializer_msgpack_pack(zval *pzval, smart_str *buf, char **msg TSRMLS_DC) /* {{{ */ {
36 php_msgpack_serialize(buf, pzval TSRMLS_CC);
37 return 1;
38 } /* }}} */
39
40 zval * yac_serializer_msgpack_unpack(char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ {
41 zval *return_value;
42 MAKE_STD_ZVAL(return_value);
43 ZVAL_NULL(return_value);
44 php_msgpack_unserialize(return_value, content, len TSRMLS_CC);
45 return return_value;
46 } /* }}} */
47
48 #endif
49
50 /*
51 * Local variables:
52 * tab-width: 4
53 * c-basic-offset: 4
54 * End:
55 * vim600: noet sw=4 ts=4 fdm=marker
56 * vim<600: noet sw=4 ts=4
57 */
+0
-72
yac-0.9.2/serializer/php.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #if !ENABLE_MSGPACK
25
26 #include "php.h"
27 #include "ext/standard/php_var.h" /* for serialize */
28 #include "ext/standard/php_smart_str.h" /* for smart_str */
29
30 #include "yac_serializer.h"
31
32 int yac_serializer_php_pack(zval *pzval, smart_str *buf, char **msg TSRMLS_DC) /* {{{ */ {
33 php_serialize_data_t var_hash;
34
35 PHP_VAR_SERIALIZE_INIT(var_hash);
36 php_var_serialize(buf, &pzval, &var_hash TSRMLS_CC);
37 PHP_VAR_SERIALIZE_DESTROY(var_hash);
38
39 return 1;
40 } /* }}} */
41
42 zval * yac_serializer_php_unpack(char *content, size_t len, char **msg TSRMLS_DC) /* {{{ */ {
43 zval *return_value;
44 const unsigned char *p;
45 php_unserialize_data_t var_hash;
46 p = (const unsigned char*)content;
47
48 MAKE_STD_ZVAL(return_value);
49 ZVAL_FALSE(return_value);
50 PHP_VAR_UNSERIALIZE_INIT(var_hash);
51 if (!php_var_unserialize(&return_value, &p, p + len, &var_hash TSRMLS_CC)) {
52 zval_ptr_dtor(&return_value);
53 PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
54 spprintf(msg, 0, "unpack error at offset %ld of %ld bytes", (long)((char*)p - content), len);
55 return NULL;
56 }
57 PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
58
59 return return_value;
60 } /* }}} */
61
62 #endif
63
64 /*
65 * Local variables:
66 * tab-width: 4
67 * c-basic-offset: 4
68 * End:
69 * vim600: noet sw=4 ts=4 fdm=marker
70 * vim<600: noet sw=4 ts=4
71 */
+0
-41
yac-0.9.2/serializer/yac_serializer.h less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #ifndef YAC_SERIALIZER_H
21 #define YAC_SERIALIZER_H
22
23 #if ENABLE_MSGPACK
24 int yac_serializer_msgpack_pack(zval *pzval, smart_str *buf, char **msg TSRMLS_DC);
25 zval * yac_serializer_msgpack_unpack(char *content, size_t len, char **msg TSRMLS_DC);
26 #else
27 int yac_serializer_php_pack(zval *pzval, smart_str *buf, char **msg TSRMLS_DC);
28 zval * yac_serializer_php_unpack(char *content, size_t len, char **msg TSRMLS_DC);
29 #endif
30
31 #endif /* YAC_SERIALIZER_H */
32
33 /*
34 * Local variables:
35 * tab-width: 4
36 * c-basic-offset: 4
37 * End:
38 * vim600: noet sw=4 ts=4 fdm=marker
39 * vim<600: noet sw=4 ts=4
40 */
+0
-302
yac-0.9.2/storage/allocator/allocators/createfilemapping.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 | Dmitry Stogov <dmitry@zend.com> |
16 | Wei Dai <zxcvdavid@gmail.com> |
17 +----------------------------------------------------------------------+
18 */
19
20 #include "php.h"
21
22 #include "php_yac.h"
23 #include "storage/yac_storage.h"
24 #include "storage/allocator/yac_allocator.h"
25
26 #include <stdio.h>
27 #include <windows.h>
28 #include <Lmcons.h>
29
30 #define ACCEL_FILEMAP_NAME "Yac.SharedMemoryArea"
31 #define ACCEL_FILEMAP_BASE "Yac.MemoryBase"
32 #define MAX_MAP_RETRIES 25
33
34 static HANDLE memfile = NULL;
35 static void *mapping_base;
36
37 typedef struct {
38 yac_shared_segment common;
39 unsigned long size;
40 } yac_shared_segment_create_file;
41
42 #ifdef USE_FILE_MAPPING
43 static char *create_name_with_username(char *name)
44 {
45 static char newname[MAXPATHLEN + UNLEN + 4];
46 char uname[UNLEN + 1];
47 DWORD unsize = UNLEN;
48
49 GetUserName(uname, &unsize);
50 snprintf(newname, sizeof(newname) - 1, "%s@%s", name, uname);
51 return newname;
52 }
53
54 static char *get_mmap_base_file(void) {
55 static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")];
56 char uname[UNLEN + 1];
57 DWORD unsize = UNLEN;
58 int l;
59
60 GetTempPath(MAXPATHLEN, windir);
61 GetUserName(uname, &unsize);
62 l = strlen(windir);
63 snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s", ACCEL_FILEMAP_BASE, uname);
64 return windir;
65 }
66
67 static int yac_shared_alloc_reattach(size_t requested_size, char **error_in)
68 {
69 void *wanted_mapping_base;
70 char *mmap_base_file = get_mmap_base_file();
71 FILE *fp = fopen(mmap_base_file, "r");
72 MEMORY_BASIC_INFORMATION info;
73
74 if (!fp) {
75 *error_in="fopen";
76 return ALLOC_FAILURE;
77 }
78
79 if (!fscanf(fp, "%p", &wanted_mapping_base)) {
80 *error_in="read mapping base";
81 fclose(fp);
82 return ALLOC_FAILURE;
83 }
84 fclose(fp);
85
86 /* Check if the requested address space is free */
87 if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0) {
88 *error_in="VirtualQuery";
89 return ALLOC_FAILURE;
90 }
91
92 if (info.State != MEM_FREE) {
93 *error_in="info.State";
94 return ALLOC_FAILURE;
95 }
96
97 if (info.RegionSize < requested_size) {
98 *error_in="info.RegionSize";
99 return ALLOC_FAILURE;
100 }
101
102 mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, wanted_mapping_base);
103
104 if (mapping_base == NULL) {
105 return ALLOC_FAIL_MAPPING;
106 }
107
108 return SUCCESSFULLY_REATTACHED;
109 }
110
111 static int create_segments(unsigned long k_size, unsigned long v_size, yac_shared_segment_create_file **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
112 int ret;
113 unsigned long allocate_size, occupied_size = 0;
114 unsigned int i, segment_size, segments_num = 1024, is_reattach = 0;
115 int map_retries = 0;
116 yac_shared_segment_create_file first_segment;
117 void *default_mapping_base_set[] = {0, 0};
118 /* TODO:
119 improve fixed addresses on x64. It still makes no sense to do it as Windows addresses are virtual per se and can or should be randomized anyway
120 through Address Space Layout Radomization (ASLR). We can still let the OS do its job and be sure that each process gets the same address if
121 desired. Not done yet, @zend refused but did not remember the exact reason, pls add info here if one of you know why :)
122 */
123 #if defined(_WIN64)
124 void *vista_mapping_base_set[] = { (void *) 0x0000100000000000, (void *) 0x0000200000000000, (void *) 0x0000300000000000, (void *) 0x0000700000000000, 0 };
125 #else
126 void *vista_mapping_base_set[] = { (void *) 0x20000000, (void *) 0x21000000, (void *) 0x30000000, (void *) 0x31000000, (void *) 0x50000000, 0 };
127 #endif
128 void **wanted_mapping_base = default_mapping_base_set;
129 TSRMLS_FETCH();
130
131 k_size = YAC_SMM_ALIGNED_SIZE(k_size);
132 v_size = YAC_SMM_ALIGNED_SIZE(v_size);
133 while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
134 segments_num >>= 1;
135 }
136
137 segment_size = v_size / segments_num;
138 ++segments_num;
139
140 allocate_size = k_size + v_size;
141
142 /* Mapping retries: When Apache2 restarts, the parent process startup routine
143 can be called before the child process is killed. In this case, the map will fail
144 and we have to sleep some time (until the child releases the mapping object) and retry.*/
145 do {
146 memfile = OpenFileMapping(FILE_MAP_WRITE, 0, create_name_with_username(ACCEL_FILEMAP_NAME));
147 if (memfile == NULL) {
148 break;
149 }
150
151 ret = yac_shared_alloc_reattach((size_t)k_size, error_in);
152 if (ret == ALLOC_FAIL_MAPPING) {
153 /* Mapping failed, wait for mapping object to get freed and retry */
154 CloseHandle(memfile);
155 memfile = NULL;
156 Sleep(1000 * (map_retries + 1));
157 } else if (ret == SUCCESSFULLY_REATTACHED) {
158 is_reattach = 1;
159 break;
160 } else {
161 return ret;
162 }
163 } while (++map_retries < MAX_MAP_RETRIES);
164
165 if (map_retries == MAX_MAP_RETRIES) {
166 *error_in = "OpenFileMapping";
167 return 0;
168 }
169
170 *shared_segments_p = (yac_shared_segment_create_file *)calloc(1, segments_num * sizeof(yac_shared_segment_create_file));
171 if(!*shared_segments_p) {
172 *error_in = "calloc";
173 return 0;
174 }
175 *shared_segments_count = segments_num;
176
177 /* Starting from windows Vista, heap randomization occurs which might cause our mapping base to
178 be taken (fail to map). So under Vista, we try to map into a hard coded predefined addresses
179 in high memory. */
180 if (!YAC_G(mmap_base) || !*YAC_G(mmap_base)) {
181 do {
182 OSVERSIONINFOEX osvi;
183 SYSTEM_INFO si;
184
185 ZeroMemory(&si, sizeof(SYSTEM_INFO));
186 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
187
188 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
189
190 if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) {
191 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
192 if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
193 break;
194 }
195 }
196
197 GetSystemInfo(&si);
198
199 /* Are we running Vista ? */
200 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 6) {
201 wanted_mapping_base = vista_mapping_base_set;
202 }
203 } while (0);
204 } else {
205 char *s = YAC_G(mmap_base);
206
207 /* skip leading 0x, %p assumes hexdeciaml format anyway */
208 if (*s == '0' && *(s + 1) == 'x') {
209 s += 2;
210 }
211 if (sscanf(s, "%p", &default_mapping_base_set[0]) != 1) {
212 *error_in = "mapping";
213 return 0;
214 }
215 }
216
217 if (is_reattach == 0) {
218 memfile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, allocate_size, create_name_with_username(ACCEL_FILEMAP_NAME));
219 if (memfile == NULL) {
220 *error_in = "CreateFileMapping";
221 return 0;
222 }
223
224 do {
225 first_segment.common.p = mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, *wanted_mapping_base);
226 if (wanted_mapping_base == NULL) {
227 break;
228 }
229 *wanted_mapping_base++;
230 } while (!mapping_base);
231 }
232
233 if(mapping_base == NULL) {
234 *error_in = "MapViewOfFileEx";
235 return 0;
236 } else {
237 char *mmap_base_file = get_mmap_base_file();
238 FILE *fp = fopen(mmap_base_file, "w");
239 if (!fp) {
240 *error_in = "get_mmap_base_file";
241 return 0;
242 }
243 fprintf(fp, "%p", mapping_base);
244 fclose(fp);
245 }
246
247 first_segment.common.p = mapping_base;
248 first_segment.size = allocate_size;
249 first_segment.common.size = k_size;
250 first_segment.common.pos = 0;
251
252 (*shared_segments_p)[0] = first_segment;
253
254 occupied_size = k_size;
255 for (i = 1; i < segments_num; i++) {
256 (*shared_segments_p)[i].size = 0;
257 (*shared_segments_p)[i].common.pos = 0;
258 (*shared_segments_p)[i].common.p = (void *)((char *)first_segment.common.p + occupied_size);
259 if ((allocate_size - occupied_size) >= YAC_SMM_ALIGNED_SIZE(segment_size)) {
260 (*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
261 occupied_size += YAC_SMM_ALIGNED_SIZE(segment_size);
262 } else {
263 (*shared_segments_p)[i].common.size = (allocate_size - occupied_size);
264 break;
265 }
266 }
267
268 return 1;
269 }
270 /* }}} */
271
272 static int detach_segment(yac_shared_segment *shared_segment) /* {{{ */ {
273 if (!shared_segment->size && mapping_base) {
274 UnmapViewOfFile(mapping_base);
275 CloseHandle(memfile);
276 }
277 return 0;
278 }
279 /* }}} */
280
281 static unsigned long segment_type_size(void) /* {{{ */ {
282 return sizeof(yac_shared_segment_create_file);
283 }
284 /* }}} */
285
286 yac_shared_memory_handlers yac_alloc_create_file_handlers = /* {{{ */ {
287 create_segments,
288 detach_segment,
289 segment_type_size
290 };
291 /* }}} */
292 #endif /* USE_CREATE_FILE */
293
294 /*
295 * Local variables:
296 * tab-width: 4
297 * c-basic-offset: 4
298 * End:
299 * vim600: noet sw=4 ts=4 fdm=marker
300 * vim<600: noet sw=4 ts=4
301 */
+0
-126
yac-0.9.2/storage/allocator/allocators/mmap.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #include "storage/yac_storage.h"
19 #include "storage/allocator/yac_allocator.h"
20
21 #ifdef USE_MMAP
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <sys/mman.h>
28
29 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
30 # define MAP_ANONYMOUS MAP_ANON
31 #endif
32
33 #ifndef MAP_FAILED
34 #define MAP_FAILED (void *)-1
35 #endif
36
37 typedef struct {
38 yac_shared_segment common;
39 unsigned long size;
40 } yac_shared_segment_mmap;
41
42 static int create_segments(unsigned long k_size, unsigned long v_size, yac_shared_segment_mmap **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
43 yac_shared_segment *shared_segment;
44 unsigned long allocate_size, occupied_size = 0;
45 unsigned int i, segment_size, segments_num = 1024;
46 yac_shared_segment_mmap first_segment;
47
48 k_size = YAC_SMM_ALIGNED_SIZE(k_size);
49 v_size = YAC_SMM_ALIGNED_SIZE(v_size);
50 while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
51 segments_num >>= 1;
52 }
53
54 segment_size = v_size / segments_num;
55 ++segments_num;
56
57 allocate_size = k_size + v_size;
58
59 first_segment.common.p = mmap(0, allocate_size, PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
60 if (first_segment.common.p == MAP_FAILED) {
61 *error_in = "mmap";
62 return 0;
63 }
64 first_segment.size = allocate_size;
65 first_segment.common.size = k_size;
66 first_segment.common.pos = 0;
67
68 *shared_segments_p = (yac_shared_segment_mmap *)calloc(1, segments_num * sizeof(yac_shared_segment_mmap));
69 if (!*shared_segments_p) {
70 munmap(first_segment.common.p, first_segment.size);
71 *error_in = "calloc";
72 return 0;
73 } else {
74 *shared_segments_p[0] = first_segment;
75 }
76 *shared_segments_count = segments_num;
77
78 occupied_size = k_size;
79 for (i = 1; i < segments_num; i++) {
80 (*shared_segments_p)[i].size = 0;
81 (*shared_segments_p)[i].common.pos = 0;
82 (*shared_segments_p)[i].common.p = first_segment.common.p + occupied_size;
83 if ((allocate_size - occupied_size) >= YAC_SMM_ALIGNED_SIZE(segment_size)) {
84 (*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
85 occupied_size += YAC_SMM_ALIGNED_SIZE(segment_size);
86 } else {
87 (*shared_segments_p)[i].common.size = (allocate_size - occupied_size);
88 break;
89 }
90 }
91
92 return 1;
93 }
94 /* }}} */
95
96 static int detach_segment(yac_shared_segment *shared_segment) /* {{{ */ {
97 if (shared_segment->size) {
98 munmap(shared_segment->p, shared_segment->size);
99 }
100 return 0;
101 }
102 /* }}} */
103
104 static unsigned long segment_type_size(void) /* {{{ */ {
105 return sizeof(yac_shared_segment_mmap);
106 }
107 /* }}} */
108
109 yac_shared_memory_handlers yac_alloc_mmap_handlers = /* {{{ */ {
110 create_segments,
111 detach_segment,
112 segment_type_size
113 };
114 /* }}} */
115
116 #endif /* USE_MMAP */
117
118 /*
119 * Local variables:
120 * tab-width: 4
121 * c-basic-offset: 4
122 * End:
123 * vim600: noet sw=4 ts=4 fdm=marker
124 * vim<600: noet sw=4 ts=4
125 */
+0
-98
yac-0.9.2/storage/allocator/allocators/posix.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Zend Optimizer+ |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 1998-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Andi Gutmans <andi@zend.com> |
15 | Zeev Suraski <zeev@zend.com> |
16 | Stanislav Malyshev <stas@zend.com> |
17 | Dmitry Stogov <dmitry@zend.com> |
18 +----------------------------------------------------------------------+
19 */
20
21 #include "zend_shared_alloc.h"
22
23 #ifdef USE_SHM_OPEN
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <fcntl.h>
29 #include <sys/mman.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32
33 typedef struct {
34 zend_shared_segment common;
35 int shm_fd;
36 } zend_shared_segment_posix;
37
38 static int create_segments(size_t requested_size, zend_shared_segment_posix ***shared_segments_p, int *shared_segments_count, char **error_in)
39 {
40 zend_shared_segment_posix *shared_segment;
41 char shared_segment_name[sizeof("/ZendAccelerator.") + 20];
42
43 *shared_segments_count = 1;
44 *shared_segments_p = (zend_shared_segment_posix **) calloc(1, sizeof(zend_shared_segment_posix) + sizeof(void *));
45 if (!*shared_segments_p) {
46 *error_in = "calloc";
47 return ALLOC_FAILURE;
48 }
49 shared_segment = (zend_shared_segment_posix *)((char *)(*shared_segments_p) + sizeof(void *));
50 (*shared_segments_p)[0] = shared_segment;
51
52 sprintf(shared_segment_name, "/ZendAccelerator.%d", getpid());
53 shared_segment->shm_fd = shm_open(shared_segment_name, O_RDWR|O_CREAT|O_TRUNC, 0600);
54 if (shared_segment->shm_fd == -1) {
55 *error_in = "shm_open";
56 return ALLOC_FAILURE;
57 }
58
59 if (ftruncate(shared_segment->shm_fd, requested_size) != 0) {
60 *error_in = "ftruncate";
61 shm_unlink(shared_segment_name);
62 return ALLOC_FAILURE;
63 }
64
65 shared_segment->common.p = mmap(0, requested_size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_segment->shm_fd, 0);
66 if (shared_segment->common.p == MAP_FAILED) {
67 *error_in = "mmap";
68 shm_unlink(shared_segment_name);
69 return ALLOC_FAILURE;
70 }
71 shm_unlink(shared_segment_name);
72
73 shared_segment->common.pos = 0;
74 shared_segment->common.size = requested_size;
75
76 return ALLOC_SUCCESS;
77 }
78
79 static int detach_segment(zend_shared_segment_posix *shared_segment)
80 {
81 munmap(shared_segment->common.p, shared_segment->common.size);
82 close(shared_segment->shm_fd);
83 return 0;
84 }
85
86 static size_t segment_type_size(void)
87 {
88 return sizeof(zend_shared_segment_posix);
89 }
90
91 zend_shared_memory_handlers zend_alloc_posix_handlers = {
92 (create_segments_t)create_segments,
93 (detach_segment_t)detach_segment,
94 segment_type_size
95 };
96
97 #endif /* USE_SHM_OPEN */
+0
-188
yac-0.9.2/storage/allocator/allocators/shm.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #include "storage/yac_storage.h"
19 #include "storage/allocator/yac_allocator.h"
20
21 #ifdef USE_SHM
22
23 #if defined(__FreeBSD__)
24 # include <machine/param.h>
25 #endif
26 #include <sys/types.h>
27 #include <sys/shm.h>
28 #include <sys/ipc.h>
29 #include <dirent.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <errno.h>
35
36 #include <sys/stat.h>
37 #include <fcntl.h>
38
39 typedef struct {
40 yac_shared_segment common;
41 int shm_id;
42 } yac_shared_segment_shm;
43
44 static int create_segments(size_t k_size, size_t v_size, yac_shared_segment_shm **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
45 struct shmid_ds sds;
46 int shm_id, shmget_flags;
47 yac_shared_segment_shm *shared_segments, first_segment;
48 unsigned int i, j, allocate_size, allocated_num, segments_num, segment_size;
49
50 shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
51 segments_num = 1024;
52 while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
53 segments_num >>= 1;
54 }
55 segment_size = v_size / segments_num;
56 allocate_size = YAC_SMM_SEGMENT_MAX_SIZE;
57
58 while ((shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags)) < 0) {
59 allocate_size >>= 1;
60 }
61
62 if (shm_id < 0) {
63 /* this should never happen */
64 *error_in = "shmget";
65 return 0;
66 }
67
68 if (allocate_size < YAC_SMM_SEGMENT_MIN_SIZE) {
69 /* this should never happen */
70 *error_in = "shmget";
71 return 0;
72 }
73
74 if (k_size <= allocate_size) {
75 first_segment.shm_id = shm_id;
76 first_segment.common.pos = 0;
77 first_segment.common.size = allocate_size;
78 first_segment.common.p = shmat(shm_id, NULL, 0);
79 shmctl(shm_id, IPC_RMID, &sds);
80 if (first_segment.common.p == (void *)-1) {
81 *error_in = "shmat";
82 return 0;
83 }
84 } else {
85 shmctl(shm_id, IPC_RMID, &sds);
86 *error_in = "shmget";
87 return 0;
88 }
89
90 allocated_num = (v_size % allocate_size)? (v_size / allocate_size) + 1 : (v_size / allocate_size);
91 shared_segments = (yac_shared_segment_shm *)calloc(1, (allocated_num) * sizeof(yac_shared_segment_shm));
92 if (!shared_segments) {
93 *error_in = "calloc";
94 return 0;
95 }
96
97 for (i = 0; i < allocated_num; i ++) {
98 shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
99 if (shm_id == -1) {
100 *error_in = "shmget";
101 for (j = 0; j < i; j++) {
102 shmdt(shared_segments[j].common.p);
103 }
104 free(shared_segments);
105 return 0;
106 }
107 shared_segments[i].shm_id = shm_id;
108 shared_segments[i].common.pos = 0;
109 shared_segments[i].common.size = allocate_size;
110 shared_segments[i].common.p = shmat(shm_id, NULL, 0);
111 shmctl(shm_id, IPC_RMID, &sds);
112 if (shared_segments[i].common.p == (void *)-1) {
113 *error_in = "shmat";
114 for (j = 0; j < i; j++) {
115 shmdt(shared_segments[j].common.p);
116 }
117 free(shared_segments);
118 return 0;
119 }
120 }
121
122 ++segments_num;
123 *shared_segments_p = (yac_shared_segment_shm *)calloc(1, segments_num * sizeof(yac_shared_segment_shm));
124 if (!*shared_segments_p) {
125 free(shared_segments);
126 *error_in = "calloc";
127 return 0;
128 } else {
129 *shared_segments_p[0] = first_segment;
130 }
131 *shared_segments_count = segments_num;
132
133 j = 0;
134 for (i = 1; i < segments_num; i++) {
135 if (shared_segments[j].common.pos == 0) {
136 (*shared_segments_p)[i].shm_id = shared_segments[j].shm_id;
137 }
138
139 if ((shared_segments[j].common.size - shared_segments[j].common.pos) >= (2 * YAC_SMM_ALIGNED_SIZE(segment_size))) {
140 (*shared_segments_p)[i].common.pos = 0;
141 (*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
142 (*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
143 shared_segments[j].common.pos += YAC_SMM_ALIGNED_SIZE(segment_size);
144 } else {
145 (*shared_segments_p)[i].common.pos = 0;
146 (*shared_segments_p)[i].common.size = shared_segments[j].common.size - shared_segments[j].common.pos;
147 (*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
148 j++;
149 }
150 }
151
152 free(shared_segments);
153
154 return 1;
155 }
156 /* }}} */
157
158 static int detach_segment(yac_shared_segment_shm *shared_segment) /* {{{ */ {
159 if (shared_segment->shm_id) {
160 shmdt(shared_segment->common.p);
161 }
162 return 1;
163 }
164 /* }}} */
165
166 static size_t segment_type_size(void) /* {{{ */ {
167 return sizeof(yac_shared_segment_shm);
168 }
169 /* }}} */
170
171 yac_shared_memory_handlers yac_alloc_shm_handlers = /* {{{ */ {
172 (create_segments_t)create_segments,
173 (detach_segment_t)detach_segment,
174 segment_type_size
175 };
176 /* }}} */
177
178 #endif /* USE_SHM */
179
180 /*
181 * Local variables:
182 * tab-width: 4
183 * c-basic-offset: 4
184 * End:
185 * vim600: noet sw=4 ts=4 fdm=marker
186 * vim<600: noet sw=4 ts=4
187 */
+0
-337
yac-0.9.2/storage/allocator/allocators/win32.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #include "ZendAccelerator.h"
19 #include "zend_shared_alloc.h"
20 #include "zend_accelerator_util_funcs.h"
21 #include <winbase.h>
22 #include <process.h>
23 #include <LMCONS.H>
24
25 #define ACCEL_FILEMAP_NAME "ZendOptimizer+.SharedMemoryArea"
26 #define ACCEL_MUTEX_NAME "ZendOptimizer+.SharedMemoryMutex"
27 #define ACCEL_FILEMAP_BASE_DEFAULT 0x01000000
28 #define ACCEL_FILEMAP_BASE "ZendOptimizer+.MemoryBase"
29 #define ACCEL_EVENT_SOURCE "Zend Optimizer+"
30
31 static HANDLE memfile = NULL, memory_mutex = NULL;
32 static void *mapping_base;
33
34 #define MAX_MAP_RETRIES 25
35
36 static void zend_win_error_message(int type, char *msg, int err)
37 {
38 LPVOID lpMsgBuf;
39 HANDLE h;
40 char *ev_msgs[2];
41
42 FormatMessage(
43 FORMAT_MESSAGE_ALLOCATE_BUFFER |
44 FORMAT_MESSAGE_FROM_SYSTEM |
45 FORMAT_MESSAGE_IGNORE_INSERTS,
46 NULL,
47 err,
48 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
49 (LPTSTR) &lpMsgBuf,
50 0,
51 NULL
52 );
53
54 h = RegisterEventSource(NULL, TEXT(ACCEL_EVENT_SOURCE));
55 ev_msgs[0] = msg;
56 ev_msgs[1] = lpMsgBuf;
57 ReportEvent(h, // event log handle
58 EVENTLOG_ERROR_TYPE, // event type
59 0, // category zero
60 err, // event identifier
61 NULL, // no user security identifier
62 2, // one substitution string
63 0, // no data
64 ev_msgs, // pointer to string array
65 NULL); // pointer to data
66 DeregisterEventSource(h);
67
68 LocalFree( lpMsgBuf );
69
70 zend_accel_error(type, msg);
71 }
72
73 static char *create_name_with_username(char *name)
74 {
75 static char newname[MAXPATHLEN + UNLEN + 4];
76 char uname[UNLEN + 1];
77 DWORD unsize = UNLEN;
78
79 GetUserName(uname, &unsize);
80 snprintf(newname, sizeof(newname) - 1, "%s@%s", name, uname);
81 return newname;
82 }
83
84 static char *get_mmap_base_file(void)
85 {
86 static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")];
87 char uname[UNLEN + 1];
88 DWORD unsize = UNLEN;
89 int l;
90
91 GetTempPath(MAXPATHLEN, windir);
92 GetUserName(uname, &unsize);
93 l = strlen(windir);
94 snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s", ACCEL_FILEMAP_BASE, uname);
95 return windir;
96 }
97
98 void zend_shared_alloc_create_lock(void)
99 {
100 memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME));
101 if (!memory_mutex) {
102 zend_accel_error(ACCEL_LOG_FATAL, "Cannot create mutex");
103 return;
104 }
105 ReleaseMutex(memory_mutex);
106 }
107
108 void zend_shared_alloc_lock_win32(void)
109 {
110 DWORD waitRes = WaitForSingleObject(memory_mutex, INFINITE);
111
112 if (waitRes == WAIT_FAILED) {
113 zend_accel_error(ACCEL_LOG_ERROR, "Cannot lock mutex");
114 }
115 }
116
117 void zend_shared_alloc_unlock_win32(void)
118 {
119 ReleaseMutex(memory_mutex);
120 }
121
122 static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
123 {
124 int err;
125 void *wanted_mapping_base;
126 char *mmap_base_file = get_mmap_base_file();
127 FILE *fp = fopen(mmap_base_file, "r");
128 MEMORY_BASIC_INFORMATION info;
129
130 err = GetLastError();
131 if (!fp) {
132 zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err);
133 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open base address file", err);
134 *error_in="fopen";
135 return ALLOC_FAILURE;
136 }
137 if (!fscanf(fp, "%p", &wanted_mapping_base)) {
138 err = GetLastError();
139 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read base address", err);
140 *error_in="read mapping base";
141 fclose(fp);
142 return ALLOC_FAILURE;
143 }
144 fclose(fp);
145
146 /* Check if the requested address space is free */
147 if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 ||
148 info.State != MEM_FREE ||
149 info.RegionSize < requested_size) {
150 err = ERROR_INVALID_ADDRESS;
151 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err);
152 return ALLOC_FAILURE;
153 }
154
155 mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, wanted_mapping_base);
156 err = GetLastError();
157
158 if (mapping_base == NULL) {
159 if (err == ERROR_INVALID_ADDRESS) {
160 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err);
161 return ALLOC_FAILURE;
162 }
163 return ALLOC_FAIL_MAPPING;
164 }
165 smm_shared_globals = (zend_smm_shared_globals *) (((char *) mapping_base) + sizeof(zend_shared_memory_block_header));
166
167 return SUCCESSFULLY_REATTACHED;
168 }
169
170 static int create_segments(size_t requested_size, zend_shared_segment ***shared_segments_p, int *shared_segments_count, char **error_in)
171 {
172 int err, ret;
173 zend_shared_segment *shared_segment;
174 int map_retries = 0;
175 void *default_mapping_base_set[] = { 0, 0 };
176 void *vista_mapping_base_set[] = { (void *)0x20000000, (void *)0x21000000, (void *)0x30000000, (void *)0x31000000, (void *)0x50000000, 0 };
177 void **wanted_mapping_base = default_mapping_base_set;
178 TSRMLS_FETCH();
179
180 zend_shared_alloc_lock_win32();
181 /* Mapping retries: When Apache2 restarts, the parent process startup routine
182 can be called before the child process is killed. In this case, the map will fail
183 and we have to sleep some time (until the child releases the mapping object) and retry.*/
184 do {
185 memfile = OpenFileMapping(FILE_MAP_WRITE, 0, create_name_with_username(ACCEL_FILEMAP_NAME));
186 err = GetLastError();
187 if (memfile == NULL) {
188 break;
189 }
190
191 ret = zend_shared_alloc_reattach(requested_size, error_in);
192 err = GetLastError();
193 if (ret == ALLOC_FAIL_MAPPING) {
194 /* Mapping failed, wait for mapping object to get freed and retry */
195 CloseHandle(memfile);
196 memfile = NULL;
197 Sleep(1000 * (map_retries + 1));
198 } else {
199 zend_shared_alloc_unlock_win32();
200 return ret;
201 }
202 } while (++map_retries < MAX_MAP_RETRIES);
203
204 if (map_retries == MAX_MAP_RETRIES) {
205 zend_shared_alloc_unlock_win32();
206 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open file mapping", err);
207 *error_in = "OpenFileMapping";
208 return ALLOC_FAILURE;
209 }
210
211 /* creating segment here */
212 *shared_segments_count = 1;
213 *shared_segments_p = (zend_shared_segment **) calloc(1, sizeof(zend_shared_segment)+sizeof(void *));
214 if (!*shared_segments_p) {
215 zend_shared_alloc_unlock_win32();
216 zend_win_error_message(ACCEL_LOG_FATAL, "calloc() failed", GetLastError());
217 *error_in = "calloc";
218 return ALLOC_FAILURE;
219 }
220 shared_segment = (zend_shared_segment *)((char *)(*shared_segments_p) + sizeof(void *));
221 (*shared_segments_p)[0] = shared_segment;
222
223 memfile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, requested_size,
224 create_name_with_username(ACCEL_FILEMAP_NAME));
225 err = GetLastError();
226 if (memfile == NULL) {
227 zend_shared_alloc_unlock_win32();
228 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to create file mapping", err);
229 *error_in = "CreateFileMapping";
230 return ALLOC_FAILURE;
231 }
232
233 /* Starting from windows Vista, heap randomization occurs which might cause our mapping base to
234 be taken (fail to map). So under Vista, we try to map into a hard coded predefined addresses
235 in high memory. */
236 if (!ZCG(accel_directives).mmap_base || !*ZCG(accel_directives).mmap_base) {
237 do {
238 OSVERSIONINFOEX osvi;
239 SYSTEM_INFO si;
240
241 ZeroMemory(&si, sizeof(SYSTEM_INFO));
242 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
243
244 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
245
246 if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) {
247 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
248 if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
249 break;
250 }
251 }
252
253 GetSystemInfo(&si);
254
255 /* Are we running Vista ? */
256 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 6) {
257 /* Assert that platform is 32 bit (for 64 bit we need to test a different set */
258 if (si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL) {
259 DebugBreak();
260 }
261
262 wanted_mapping_base = vista_mapping_base_set;
263 }
264 } while (0);
265 } else {
266 char *s = ZCG(accel_directives).mmap_base;
267
268 /* skip leading 0x, %p assumes hexdeciaml format anyway */
269 if (*s == '0' && *(s + 1) == 'x') {
270 s += 2;
271 }
272 if (sscanf(s, "%p", &default_mapping_base_set[0]) != 1) {
273 zend_shared_alloc_unlock_win32();
274 zend_win_error_message(ACCEL_LOG_FATAL, "Bad mapping address specified in zend_optimizerplus.mmap_base", err);
275 return ALLOC_FAILURE;
276 }
277 }
278
279 do {
280 shared_segment->p = mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, *wanted_mapping_base);
281 if (*wanted_mapping_base == NULL) { /* Auto address (NULL) is the last option on the array */
282 break;
283 }
284 wanted_mapping_base++;
285 } while (!mapping_base);
286
287 err = GetLastError();
288 if (mapping_base == NULL) {
289 zend_shared_alloc_unlock_win32();
290 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to create view for file mapping", err);
291 *error_in = "MapViewOfFile";
292 return ALLOC_FAILURE;
293 } else {
294 char *mmap_base_file = get_mmap_base_file();
295 FILE *fp = fopen(mmap_base_file, "w");
296 err = GetLastError();
297 if (!fp) {
298 zend_shared_alloc_unlock_win32();
299 zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err);
300 zend_win_error_message(ACCEL_LOG_FATAL, "Unable to write base address", err);
301 return ALLOC_FAILURE;
302 }
303 fprintf(fp, "%p\n", mapping_base);
304 fclose(fp);
305 }
306
307 shared_segment->pos = 0;
308 shared_segment->size = requested_size;
309
310 zend_shared_alloc_unlock_win32();
311
312 return ALLOC_SUCCESS;
313 }
314
315 static int detach_segment(zend_shared_segment *shared_segment)
316 {
317 zend_shared_alloc_lock_win32();
318 if (mapping_base) {
319 UnmapViewOfFile(mapping_base);
320 }
321 CloseHandle(memfile);
322 zend_shared_alloc_unlock_win32();
323 CloseHandle(memory_mutex);
324 return 0;
325 }
326
327 static size_t segment_type_size(void)
328 {
329 return sizeof(zend_shared_segment);
330 }
331
332 zend_shared_memory_handlers zend_alloc_win32_handlers = {
333 create_segments,
334 detach_segment,
335 segment_type_size
336 };
+0
-207
yac-0.9.2/storage/allocator/yac_allocator.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #include <errno.h>
19 #include <time.h>
20 #include <sys/types.h>
21
22 #include "php.h"
23 #include "storage/yac_storage.h"
24 #include "yac_allocator.h"
25
26 static const yac_shared_memory_handlers *shared_memory_handler = NULL;
27 static const char *shared_model;
28
29 int yac_allocator_startup(unsigned long k_size, unsigned long size, char **msg) /* {{{ */ {
30 char *p;
31 yac_shared_segment *segments = NULL;
32 int i, segments_num, segments_array_size, segment_size;
33 const yac_shared_memory_handlers *he;
34
35 if ((he = &yac_shared_memory_handler)) {
36 int ret = he->create_segments(k_size, size, &segments, &segments_num, msg);
37
38 if (!ret) {
39 if (segments) {
40 int i;
41 for (i = 0; i < segments_num; i++) {
42 if (segments[i].p && segments[i].p != (void *)-1) {
43 he->detach_segment(&segments[i]);
44 }
45 }
46 free(segments);
47 }
48 return 0;
49 }
50 } else {
51 return 0;
52 }
53
54 segment_size = he->segment_type_size();
55 segments_array_size = (segments_num - 1) * segment_size;
56
57 yac_storage = segments[0].p;
58 memcpy(&YAC_SG(first_seg), (char *)(&segments[0]), segment_size);
59
60 YAC_SG(segments_num) = segments_num - 1;
61 YAC_SG(segments_num_mask) = YAC_SG(segments_num) - 1;
62 YAC_SG(segments) = (yac_shared_segment **)((char *)yac_storage + YAC_SMM_ALIGNED_SIZE(sizeof(yac_storage_globals) + segment_size - sizeof(yac_shared_segment)));
63
64 p = (char *)YAC_SG(segments) + (sizeof(void *) * YAC_SG(segments_num));
65 memcpy(p, (char *)segments + segment_size, segments_array_size);
66 for (i = 0; i < YAC_SG(segments_num); i++) {
67 YAC_SG(segments)[i] = (yac_shared_segment *)p;
68 p += segment_size;
69 }
70 YAC_SG(slots) = (yac_kv_key *)((char *)YAC_SG(segments)
71 + (YAC_SG(segments_num) * sizeof(void *)) + YAC_SMM_ALIGNED_SIZE(segments_array_size));
72
73 free(segments);
74
75 return 1;
76 }
77 /* }}} */
78
79 void yac_allocator_shutdown(void) /* {{{ */ {
80 yac_shared_segment **segments;
81 const yac_shared_memory_handlers *he;
82
83 segments = YAC_SG(segments);
84 if (segments) {
85 if ((he = &yac_shared_memory_handler)) {
86 int i = 0;
87 for (i = 0; i < YAC_SG(segments_num); i++) {
88 he->detach_segment(segments[i]);
89 }
90 he->detach_segment(&YAC_SG(first_seg));
91 }
92 }
93 }
94 /* }}} */
95
96 static inline void *yac_allocator_alloc_algo2(unsigned long size, int hash) /* {{{ */ {
97 yac_shared_segment *segment;
98 unsigned int seg_size, retry, pos, current;
99
100 current = hash & YAC_SG(segments_num_mask);
101 /* do we really need lock here? it depends the real life exam */
102 retry = 3;
103 do_retry:
104 segment = YAC_SG(segments)[current];
105 seg_size = segment->size;
106 pos = segment->pos;
107 if ((seg_size - pos) >= size) {
108 do_alloc:
109 pos += size;
110 segment->pos = pos;
111 if (segment->pos == pos) {
112 return (void *)((char *)segment->p + (pos - size));
113 } else if (retry--) {
114 goto do_retry;
115 }
116 return NULL;
117 } else {
118 int i, max;
119 max = (YAC_SG(segments_num) > 4)? 4 : YAC_SG(segments_num);
120 for (i = 1; i < max; i++) {
121 segment = YAC_SG(segments)[(current + i) & YAC_SG(segments_num_mask)];
122 seg_size = segment->size;
123 pos = segment->pos;
124 if ((seg_size - pos) >= size) {
125 current = (current + i) & YAC_SG(segments_num_mask);
126 goto do_alloc;
127 }
128 }
129 segment->pos = 0;
130 pos = 0;
131 ++YAC_SG(recycles);
132 goto do_alloc;
133 }
134 }
135 /* }}} */
136
137 #if 0
138 static inline void *yac_allocator_alloc_algo1(unsigned long size) /* {{{ */ {
139 int i, j, picked_seg, atime;
140 picked_seg = (YAC_SG(current_seg) + 1) & YAC_SG(segments_num_mask);
141
142 atime = YAC_SG(segments)[picked_seg]->atime;
143 for (i = 0; i < 10; i++) {
144 j = (picked_seg + 1) & YAC_SG(segments_num_mask);
145 if (YAC_SG(segments)[j]->atime < atime) {
146 picked_seg = j;
147 atime = YAC_SG(segments)[j]->atime;
148 }
149 }
150
151 YAC_SG(current_seg) = picked_seg;
152 YAC_SG(segments)[picked_seg]->pos = 0;
153 return yac_allocator_alloc_algo2(size);
154 }
155 /* }}} */
156 #endif
157
158 unsigned long yac_allocator_real_size(unsigned long size) /* {{{ */ {
159 unsigned long real_size = YAC_SMM_TRUE_SIZE(size);
160
161 if (real_size > YAC_SG(segments)[0]->size) {
162 return 0;
163 }
164
165 return real_size;
166 }
167 /* }}} */
168
169 void * yac_allocator_raw_alloc(unsigned long real_size, int hash) /* {{{ */ {
170
171 return yac_allocator_alloc_algo2(real_size, hash);
172 /*
173 if (YAC_SG(exhausted)) {
174 return yac_allocator_alloc_algo1(real_size);
175 } else {
176 void *p;
177 if ((p = yac_allocator_alloc_algo2(real_size))) {
178 return p;
179 }
180 return yac_allocator_alloc_algo1(real_size);
181 }
182 */
183 }
184 /* }}} */
185
186 #if 0
187 void yac_allocator_touch(void *p, unsigned long atime) /* {{{ */ {
188 yac_shared_block_header h = *(yac_shared_block_header *)(p - sizeof(yac_shared_block_header));
189
190 if (h.seg >= YAC_SG(segments_num)) {
191 return;
192 }
193
194 YAC_SG(segments)[h.seg]->atime = atime;
195 }
196 /* }}} */
197 #endif
198
199 /*
200 * Local variables:
201 * tab-width: 4
202 * c-basic-offset: 4
203 * End:
204 * vim600: noet sw=4 ts=4 fdm=marker
205 * vim<600: noet sw=4 ts=4
206 */
+0
-97
yac-0.9.2/storage/allocator/yac_allocator.h less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Authors: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 #ifndef YAC_ALLOCATOR_H
19 #define YAC_ALLOCATOR_H
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #define YAC_SMM_ALIGNMENT 8
26 #define YAC_SMM_ALIGNMENT_LOG2 3
27 #define YAC_SMM_ALIGNMENT_MASK ~(YAC_SMM_ALIGNMENT - 1)
28 #define YAC_SMM_BLOCK_HEADER_SIZE YAC_SMM_ALIGNED_SIZE(sizeof(yac_shared_block_header))
29
30 #define YAC_SMM_MAIN_SEG_SIZE (4*1024*1024)
31 #define YAC_SMM_SEGMENT_MAX_SIZE (32*1024*1024)
32 #define YAC_SMM_SEGMENT_MIN_SIZE (4*1024*1024)
33 #define YAC_SMM_MIN_BLOCK_SIZE 128
34 #define YAC_SMM_ALIGNED_SIZE(x) (((x) + YAC_SMM_ALIGNMENT - 1) & YAC_SMM_ALIGNMENT_MASK)
35 #define YAC_SMM_TRUE_SIZE(x) ((x < YAC_SMM_MIN_BLOCK_SIZE)? (YAC_SMM_MIN_BLOCK_SIZE) : (YAC_SMM_ALIGNED_SIZE(x)))
36
37 #ifdef PHP_WIN32
38 # define USE_FILE_MAPPING 1
39 # define inline __inline
40 #elif defined(HAVE_SHM_MMAP_ANON)
41 # define USE_MMAP 1
42 #elif defined(HAVE_SHM_IPC)
43 # define USE_SHM 1
44 #else
45 #error(no builtin shared memory supported)
46 #endif
47
48 #define ALLOC_FAILURE 0
49 #define ALLOC_SUCCESS 1
50 #define FAILED_REATTACHED 2
51 #define SUCCESSFULLY_REATTACHED 4
52 #define ALLOC_FAIL_MAPPING 8
53
54 typedef int (*create_segments_t)(unsigned long k_size, unsigned long v_size, yac_shared_segment **shared_segments, int *shared_segment_count, char **error_in);
55 typedef int (*detach_segment_t)(yac_shared_segment *shared_segment);
56
57 typedef struct {
58 create_segments_t create_segments;
59 detach_segment_t detach_segment;
60 unsigned long (*segment_type_size)(void);
61 } yac_shared_memory_handlers;
62
63 typedef struct {
64 const char *name;
65 yac_shared_memory_handlers *handler;
66 } yac_shared_memory_handler_entry;
67
68 int yac_allocator_startup(unsigned long first_seg_size, unsigned long size, char **err);
69 void yac_allocator_shutdown(void);
70 unsigned long yac_allocator_real_size(unsigned long size);
71 void *yac_allocator_raw_alloc(unsigned long real_size, int seg);
72 int yac_allocator_free(void *p);
73
74 static inline void * yac_allocator_alloc(unsigned long size, int seg) {
75 unsigned long real_size = yac_allocator_real_size(size);
76 if (!real_size) {
77 return (void *)0;
78 }
79 return yac_allocator_raw_alloc(real_size, seg);
80 }
81
82 #if defined(USE_MMAP)
83 extern yac_shared_memory_handlers yac_alloc_mmap_handlers;
84 #define yac_shared_memory_handler yac_alloc_mmap_handlers
85 #define YAC_SHARED_MEMORY_HANDLER_NAME "mmap"
86 #elif defined(USE_SHM)
87 extern yac_shared_memory_handlers yac_alloc_shm_handlers;
88 #define yac_shared_memory_handler yac_alloc_shm_handlers
89 #define YAC_SHARED_MEMORY_HANDLER_NAME "shm"
90 #elif defined(USE_FILE_MAPPING)
91 extern yac_shared_memory_handlers yac_alloc_create_file_handlers;
92 #define yac_shared_memory_handler yac_alloc_create_file_handlers
93 #define YAC_SHARED_MEMORY_HANDLER_NAME "file_mapping"
94 #endif
95
96 #endif /* YAC_ALLOCATOR_H */
+0
-629
yac-0.9.2/storage/yac_storage.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #include "php.h"
21 #include "yac_storage.h"
22 #include "allocator/yac_allocator.h"
23
24 yac_storage_globals *yac_storage;
25
26 static inline unsigned int yac_storage_align_size(unsigned int size) /* {{{ */ {
27 int bits = 0;
28 while ((size = size >> 1)) {
29 ++bits;
30 }
31 return (1 << bits);
32 }
33 /* }}} */
34
35 int yac_storage_startup(unsigned long fsize, unsigned long size, char **msg) /* {{{ */ {
36 unsigned long real_size;
37
38 if (!yac_allocator_startup(fsize, size, msg)) {
39 return 0;
40 }
41
42 size = YAC_SG(first_seg).size - ((char *)YAC_SG(slots) - (char *)yac_storage);
43 real_size = yac_storage_align_size(size / sizeof(yac_kv_key));
44 if (!((size / sizeof(yac_kv_key)) & ~(real_size << 1))) {
45 real_size <<= 1;
46 }
47
48 YAC_SG(slots_size) = real_size;
49 YAC_SG(slots_mask) = real_size - 1;
50 YAC_SG(slots_num) = 0;
51 YAC_SG(fails) = 0;
52 YAC_SG(hits) = 0;
53 YAC_SG(miss) = 0;
54 YAC_SG(kicks) = 0;
55
56 memset((char *)YAC_SG(slots), 0, sizeof(yac_kv_key) * real_size);
57
58 return 1;
59 }
60 /* }}} */
61
62 void yac_storage_shutdown(void) /* {{{ */ {
63 yac_allocator_shutdown();
64 }
65 /* }}} */
66
67 /* {{{ MurmurHash2 (Austin Appleby)
68 */
69 static inline ulong yac_inline_hash_func1(char *data, unsigned int len) {
70 unsigned int h, k;
71
72 h = 0 ^ len;
73
74 while (len >= 4) {
75 k = data[0];
76 k |= data[1] << 8;
77 k |= data[2] << 16;
78 k |= data[3] << 24;
79
80 k *= 0x5bd1e995;
81 k ^= k >> 24;
82 k *= 0x5bd1e995;
83
84 h *= 0x5bd1e995;
85 h ^= k;
86
87 data += 4;
88 len -= 4;
89 }
90
91 switch (len) {
92 case 3:
93 h ^= data[2] << 16;
94 case 2:
95 h ^= data[1] << 8;
96 case 1:
97 h ^= data[0];
98 h *= 0x5bd1e995;
99 }
100
101 h ^= h >> 13;
102 h *= 0x5bd1e995;
103 h ^= h >> 15;
104
105 return h;
106 }
107 /* }}} */
108
109 /* {{{ DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
110 *
111 * This is Daniel J. Bernstein's popular `times 33' hash function as
112 * posted by him years ago on comp->lang.c. It basically uses a function
113 * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
114 * known hash functions for strings. Because it is both computed very
115 * fast and distributes very well.
116 *
117 * The magic of number 33, i.e. why it works better than many other
118 * constants, prime or not, has never been adequately explained by
119 * anyone. So I try an explanation: if one experimentally tests all
120 * multipliers between 1 and 256 (as RSE did now) one detects that even
121 * numbers are not useable at all. The remaining 128 odd numbers
122 * (except for the number 1) work more or less all equally well. They
123 * all distribute in an acceptable way and this way fill a hash table
124 * with an average percent of approx. 86%.
125 *
126 * If one compares the Chi^2 values of the variants, the number 33 not
127 * even has the best value. But the number 33 and a few other equally
128 * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
129 * advantage to the remaining numbers in the large set of possible
130 * multipliers: their multiply operation can be replaced by a faster
131 * operation based on just one shift plus either a single addition
132 * or subtraction operation. And because a hash function has to both
133 * distribute good _and_ has to be very fast to compute, those few
134 * numbers should be preferred and seems to be the reason why Daniel J.
135 * Bernstein also preferred it.
136 *
137 *
138 * -- Ralf S. Engelschall <rse@engelschall.com>
139 */
140
141 static inline ulong yac_inline_hash_func2(char *key, uint len) {
142 register ulong hash = 5381;
143
144 /* variant with the hash unrolled eight times */
145 for (; len >= 8; len -= 8) {
146 hash = ((hash << 5) + hash) + *key++;
147 hash = ((hash << 5) + hash) + *key++;
148 hash = ((hash << 5) + hash) + *key++;
149 hash = ((hash << 5) + hash) + *key++;
150 hash = ((hash << 5) + hash) + *key++;
151 hash = ((hash << 5) + hash) + *key++;
152 hash = ((hash << 5) + hash) + *key++;
153 hash = ((hash << 5) + hash) + *key++;
154 }
155 switch (len) {
156 case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
157 case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
158 case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
159 case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
160 case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
161 case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
162 case 1: hash = ((hash << 5) + hash) + *key++; break;
163 case 0: break;
164 default: break;
165 }
166 return hash;
167 }
168 /* }}} */
169
170 /* {{{ COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
171 * code or tables extracted from it, as desired without restriction.
172 *
173 * First, the polynomial itself and its table of feedback terms. The
174 * polynomial is
175 * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
176 *
177 * Note that we take it "backwards" and put the highest-order term in
178 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
179 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
180 * the MSB being 1
181 *
182 * Note that the usual hardware shift register implementation, which
183 * is what we're using (we're merely optimizing it by doing eight-bit
184 * chunks at a time) shifts bits into the lowest-order term. In our
185 * implementation, that means shifting towards the right. Why do we
186 * do it this way? Because the calculated CRC must be transmitted in
187 * order from highest-order term to lowest-order term. UARTs transmit
188 * characters in order from LSB to MSB. By storing the CRC this way
189 * we hand it to the UART in the order low-byte to high-byte; the UART
190 * sends each low-bit to hight-bit; and the result is transmission bit
191 * by bit from highest- to lowest-order term without requiring any bit
192 * shuffling on our part. Reception works similarly
193 *
194 * The feedback terms table consists of 256, 32-bit entries. Notes
195 *
196 * The table can be generated at runtime if desired; code to do so
197 * is shown later. It might not be obvious, but the feedback
198 * terms simply represent the results of eight shift/xor opera
199 * tions for all combinations of data and CRC register values
200 *
201 * The values must be right-shifted by eight bits by the "updcrc
202 * logic; the shift must be unsigned (bring in zeroes). On some
203 * hardware you could probably optimize the shift in assembler by
204 * using byte-swap instructions
205 * polynomial $edb88320
206 *
207 *
208 * CRC32 code derived from work by Gary S. Brown.
209 */
210
211 static unsigned int crc32_tab[] = {
212 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
213 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
214 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
215 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
216 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
217 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
218 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
219 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
220 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
221 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
222 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
223 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
224 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
225 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
226 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
227 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
228 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
229 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
230 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
231 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
232 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
233 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
234 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
235 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
236 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
237 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
238 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
239 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
240 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
241 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
242 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
243 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
244 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
245 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
246 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
247 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
248 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
249 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
250 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
251 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
252 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
253 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
254 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
255 };
256
257 static inline unsigned int crc32(char *buf, unsigned int size) {
258 const char *p;
259 register int crc = 0;
260
261 p = buf;
262 while (size--) {
263 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
264 }
265
266 return crc ^ ~0U;
267 }
268 /* }}} */
269
270 static inline unsigned int yac_crc32(char *data, unsigned int size) /* {{{ */ {
271 if (size < YAC_FULL_CRC_THRESHOLD) {
272 return crc32(data, size);
273 } else {
274 int i = 0;
275 char crc_contents[YAC_FULL_CRC_THRESHOLD];
276 int head = YAC_FULL_CRC_THRESHOLD >> 2;
277 int tail = YAC_FULL_CRC_THRESHOLD >> 4;
278 int body = YAC_FULL_CRC_THRESHOLD - head - tail;
279 char *p = data + head;
280 char *q = crc_contents + head;
281 int step = (size - tail - head) / body;
282
283 memcpy(crc_contents, data, head);
284 for (; i < body; i++, q++, p+= step) {
285 *q = *p;
286 }
287 memcpy(q, p, tail);
288
289 return crc32(crc_contents, YAC_FULL_CRC_THRESHOLD);
290 }
291 }
292 /* }}} */
293
294 int yac_storage_find(char *key, unsigned int len, char **data, unsigned int *size, unsigned int *flag, int *cas, unsigned long tv) /* {{{ */ {
295 ulong h, hash, seed;
296 yac_kv_key k, *p;
297 yac_kv_val v;
298
299 hash = h = yac_inline_hash_func1(key, len);
300 p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
301 k = *p;
302 if (k.val) {
303 char *s;
304 uint i;
305 if (k.h == hash && YAC_KEY_KLEN(k) == len) {
306 v = *(k.val);
307 if (!memcmp(k.key, key, len)) {
308 s = USER_ALLOC(YAC_KEY_VLEN(k) + 1);
309 memcpy(s, (char *)k.val->data, YAC_KEY_VLEN(k));
310 do_verify:
311 if (k.len != v.len) {
312 USER_FREE(s);
313 ++YAC_SG(miss);
314 return 0;
315 }
316
317 if (k.ttl) {
318 if (k.ttl <= tv) {
319 ++YAC_SG(miss);
320 USER_FREE(s);
321 return 0;
322 }
323 }
324
325 if (k.crc != yac_crc32(s, YAC_KEY_VLEN(k))) {
326 USER_FREE(s);
327 ++YAC_SG(miss);
328 return 0;
329 }
330 s[YAC_KEY_VLEN(k)] = '\0';
331 k.val->atime = tv;
332 *data = s;
333 *size = YAC_KEY_VLEN(k);
334 *flag = k.flag;
335 ++YAC_SG(hits);
336 return 1;
337 }
338 }
339
340 seed = yac_inline_hash_func2(key, len);
341 for (i = 0; i < 3; i++) {
342 h += seed & YAC_SG(slots_mask);
343 p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
344 k = *p;
345 if (k.h == hash && YAC_KEY_KLEN(k) == len) {
346 v = *(k.val);
347 if (!memcmp(k.key, key, len)) {
348 s = USER_ALLOC(YAC_KEY_VLEN(k) + 1);
349 memcpy(s, (char *)k.val->data, YAC_KEY_VLEN(k));
350 goto do_verify;
351 }
352 }
353 }
354 }
355
356 ++YAC_SG(miss);
357
358 return 0;
359 }
360 /* }}} */
361
362 void yac_storage_delete(char *key, unsigned int len, int ttl, unsigned long tv) /* {{{ */ {
363 ulong hash, h, seed;
364 yac_kv_key k, *p;
365
366 hash = h = yac_inline_hash_func1(key, len);
367 p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
368 k = *p;
369 if (k.val) {
370 uint i;
371 if (k.h == hash && YAC_KEY_KLEN(k) == len) {
372 if (!memcmp((char *)k.key, key, len)) {
373 if (ttl == 0) {
374 p->ttl = 1;
375 } else {
376 p->ttl = ttl + tv;
377 }
378 return;
379 }
380 }
381
382 seed = yac_inline_hash_func2(key, len);
383 for (i = 0; i < 3; i++) {
384 h += seed & YAC_SG(slots_mask);
385 p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
386 k = *p;
387 if (k.val == NULL) {
388 return;
389 } else if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
390 p->ttl = 1;
391 return;
392 }
393 }
394 }
395 }
396 /* }}} */
397
398 int yac_storage_update(char *key, unsigned int len, char *data, unsigned int size, unsigned int flag, int ttl, int add, unsigned long tv) /* {{{ */ {
399 ulong hash, h;
400 int idx = 0, is_valid;
401 yac_kv_key *p, k, *paths[4];
402 yac_kv_val *val, *s;
403 unsigned long real_size;
404
405 hash = h = yac_inline_hash_func1(key, len);
406 paths[idx++] = p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
407 k = *p;
408 if (k.val) {
409 /* Found the exact match */
410 if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
411 do_update:
412 is_valid = 0;
413 if (k.crc == yac_crc32(k.val->data, YAC_KEY_VLEN(k))) {
414 is_valid = 1;
415 }
416 if (add && (!k.ttl || k.ttl > tv) && is_valid) {
417 return 0;
418 }
419 if (k.size >= size && is_valid) {
420 s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
421 memcpy(s->data, data, size);
422 if (ttl) {
423 k.ttl = (ulong)tv + ttl;
424 } else {
425 k.ttl = 0;
426 }
427 s->atime = tv;
428 YAC_KEY_SET_LEN(*s, len, size);
429 memcpy((char *)k.val, (char *)s, sizeof(yac_kv_val) + size - 1);
430 k.crc = yac_crc32(s->data, size);
431 k.flag = flag;
432 memcpy(k.key, key, len);
433 YAC_KEY_SET_LEN(k, len, size);
434 *p = k;
435 USER_FREE(s);
436 return 1;
437 } else {
438 uint msize;
439 real_size = yac_allocator_real_size(sizeof(yac_kv_val) + (size * YAC_STORAGE_FACTOR) - 1);
440 if (!real_size) {
441 ++YAC_SG(fails);
442 return 0;
443 }
444 msize = sizeof(yac_kv_val) + size - 1;
445 s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
446 memcpy(s->data, data, size);
447 s->atime = tv;
448 YAC_KEY_SET_LEN(*s, len, size);
449 val = yac_allocator_raw_alloc(real_size, (int)hash);
450 if (val) {
451 memcpy((char *)val, (char *)s, msize);
452 if (ttl) {
453 k.ttl = tv + ttl;
454 } else {
455 k.ttl = 0;
456 }
457 k.crc = yac_crc32(s->data, size);
458 k.val = val;
459 k.flag = flag;
460 k.size = real_size;
461 memcpy(k.key, key, len);
462 YAC_KEY_SET_LEN(k, len, size);
463 *p = k;
464 USER_FREE(s);
465 return 1;
466 }
467 ++YAC_SG(fails);
468 USER_FREE(s);
469 return 0;
470 }
471 } else {
472 uint i;
473 ulong seed, max_atime;
474
475 seed = yac_inline_hash_func2(key, len);
476 for (i = 0; i < 3; i++) {
477 h += seed & YAC_SG(slots_mask);
478 paths[idx++] = p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
479 k = *p;
480 if (k.val == NULL) {
481 goto do_add;
482 } else if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
483 /* Found the exact match */
484 goto do_update;
485 }
486 }
487
488 --idx;
489 max_atime = paths[idx]->val->atime;
490 for (i = 0; i < idx; i++) {
491 if ((paths[i]->ttl && paths[i]->ttl <= tv) || paths[i]->len != paths[i]->val->len) {
492 p = paths[i];
493 goto do_add;
494 } else if (paths[i]->val->atime < max_atime) {
495 max_atime = paths[i]->val->atime;
496 p = paths[i];
497 }
498 }
499 ++YAC_SG(kicks);
500 k = *p;
501 k.h = hash;
502
503 goto do_update;
504 }
505 } else {
506 do_add:
507 real_size = yac_allocator_real_size(sizeof(yac_kv_val) + (size * YAC_STORAGE_FACTOR) - 1);
508 if (!real_size) {
509 ++YAC_SG(fails);
510 return 0;
511 }
512 s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
513 memcpy(s->data, data, size);
514 s->atime = tv;
515 YAC_KEY_SET_LEN(*s, len, size);
516 val = yac_allocator_raw_alloc(real_size, (int)hash);
517 if (val) {
518 memcpy((char *)val, (char *)s, sizeof(yac_kv_val) + size - 1);
519 if (p->val == NULL) {
520 ++YAC_SG(slots_num);
521 }
522 k.h = hash;
523 k.val = val;
524 k.flag = flag;
525 k.size = real_size;
526 k.crc = yac_crc32(s->data, size);
527 memcpy(k.key, key, len);
528 YAC_KEY_SET_LEN(k, len, size);
529 if (ttl) {
530 k.ttl = tv + ttl;
531 } else {
532 k.ttl = 0;
533 }
534 *p = k;
535 USER_FREE(s);
536 return 1;
537 }
538 ++YAC_SG(fails);
539 USER_FREE(s);
540 }
541
542 return 0;
543 }
544 /* }}} */
545
546 void yac_storage_flush(void) /* {{{ */ {
547 YAC_SG(slots_num) = 0;
548 memset((char *)YAC_SG(slots), 0, sizeof(yac_kv_key) * YAC_SG(slots_size));
549 }
550 /* }}} */
551
552 yac_storage_info * yac_storage_get_info(void) /* {{{ */ {
553 yac_storage_info *info = USER_ALLOC(sizeof(yac_storage_info));
554
555 info->k_msize = (unsigned long)YAC_SG(first_seg).size;
556 info->v_msize = (unsigned long)YAC_SG(segments)[0]->size * (unsigned long)YAC_SG(segments_num);
557 info->segment_size = YAC_SG(segments)[0]->size;
558 info->segments_num = YAC_SG(segments_num);
559 info->hits = YAC_SG(hits);
560 info->miss = YAC_SG(miss);
561 info->fails = YAC_SG(fails);
562 info->kicks = YAC_SG(kicks);
563 info->recycles = YAC_SG(recycles);
564 info->slots_size = YAC_SG(slots_size);
565 info->slots_num = YAC_SG(slots_num);
566
567 return info;
568 }
569 /* }}} */
570
571 void yac_storage_free_info(yac_storage_info *info) /* {{{ */ {
572 USER_FREE(info);
573 }
574 /* }}} */
575
576 yac_item_list * yac_storage_dump(unsigned int limit) /* {{{ */ {
577 yac_kv_key k;
578 yac_item_list *item, *list = NULL;
579
580 if (YAC_SG(slots_num)) {
581 unsigned int i = 0, n = 0;
582 for (; i<YAC_SG(slots_size) && n < YAC_SG(slots_num) && n < limit; i++) {
583 k = YAC_SG(slots)[i];
584 if (k.val) {
585 item = USER_ALLOC(sizeof(yac_item_list));
586 item->index = i;
587 item->h = k.h;
588 item->crc = k.crc;
589 item->ttl = k.ttl;
590 item->k_len = YAC_KEY_KLEN(k);
591 item->v_len = YAC_KEY_VLEN(k);
592 item->flag = k.flag;
593 item->size = k.size;
594 memcpy(item->key, k.key, YAC_STORAGE_MAX_KEY_LEN);
595 item->next = list;
596 list = item;
597 ++n;
598 }
599 }
600 }
601
602 return list;
603 }
604 /* }}} */
605
606 void yac_storage_free_list(yac_item_list *list) /* {{{ */ {
607 yac_item_list *l;
608 while (list) {
609 l = list;
610 list = list->next;
611 USER_FREE(l);
612 }
613 }
614 /* }}} */
615
616 const char * yac_storage_shared_memory_name(void) /* {{{ */ {
617 return YAC_SHARED_MEMORY_HANDLER_NAME;
618 }
619 /* }}} */
620
621 /*
622 * Local variables:
623 * tab-width: 4
624 * c-basic-offset: 4
625 * End:
626 * vim600: noet sw=4 ts=4 fdm=marker
627 * vim<600: noet sw=4 ts=4
628 */
+0
-129
yac-0.9.2/storage/yac_storage.h less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #ifndef YAC_STORAGE_H
21 #define YAC_STORAGE_H
22
23 #define YAC_STORAGE_MAX_ENTRY_LEN (1 << 20)
24 #define YAC_STORAGE_MAX_KEY_LEN (48)
25 #define YAC_STORAGE_FACTOR (1.25)
26 #define YAC_KEY_KLEN_MASK (255)
27 #define YAC_KEY_VLEN_BITS (8)
28 #define YAC_KEY_KLEN(k) ((k).len & YAC_KEY_KLEN_MASK)
29 #define YAC_KEY_VLEN(k) ((k).len >> YAC_KEY_VLEN_BITS)
30 #define YAC_KEY_SET_LEN(k, kl, vl) ((k).len = (vl << YAC_KEY_VLEN_BITS) | (kl & YAC_KEY_KLEN_MASK))
31 #define YAC_FULL_CRC_THRESHOLD 256
32
33 #define USER_ALLOC emalloc
34 #define USER_FREE efree
35
36 typedef struct {
37 unsigned long atime;
38 unsigned int len;
39 char data[1];
40 } yac_kv_val;
41
42 typedef struct {
43 unsigned long h;
44 unsigned long crc;
45 unsigned int ttl;
46 unsigned int len;
47 unsigned int flag;
48 unsigned int size;
49 yac_kv_val *val;
50 unsigned char key[YAC_STORAGE_MAX_KEY_LEN];
51 } yac_kv_key;
52
53 typedef struct _yac_item_list {
54 unsigned int index;
55 unsigned long h;
56 unsigned long crc;
57 unsigned int ttl;
58 unsigned int k_len;
59 unsigned int v_len;
60 unsigned int flag;
61 unsigned int size;
62 unsigned char key[YAC_STORAGE_MAX_KEY_LEN];
63 struct _yac_item_list *next;
64 } yac_item_list;
65
66 typedef struct {
67 volatile unsigned int pos;
68 unsigned int size;
69 void *p;
70 } yac_shared_segment;
71
72 typedef struct {
73 unsigned long k_msize;
74 unsigned long v_msize;
75 unsigned int segments_num;
76 unsigned int segment_size;
77 unsigned int slots_num;
78 unsigned int slots_size;
79 unsigned int miss;
80 unsigned int fails;
81 unsigned int kicks;
82 unsigned int recycles;
83 unsigned long hits;
84 } yac_storage_info;
85
86 typedef struct {
87 yac_kv_key *slots;
88 unsigned int slots_mask;
89 unsigned int slots_num;
90 unsigned int slots_size;
91 unsigned int miss;
92 unsigned int fails;
93 unsigned int kicks;
94 unsigned int recycles;
95 unsigned long hits;
96 yac_shared_segment **segments;
97 unsigned int segments_num;
98 unsigned int segments_num_mask;
99 yac_shared_segment first_seg;
100 } yac_storage_globals;
101
102 extern yac_storage_globals *yac_storage;
103
104 #define YAC_SG(element) (yac_storage->element)
105
106 int yac_storage_startup(unsigned long first_size, unsigned long size, char **err);
107 void yac_storage_shutdown(void);
108 int yac_storage_find(char *key, unsigned int len, char **data, unsigned int *size, unsigned int *flag, int *cas, unsigned long tv);
109 int yac_storage_update(char *key, unsigned int len, char *data, unsigned int size, unsigned int falg, int ttl, int add, unsigned long tv);
110 void yac_storage_delete(char *key, unsigned int len, int ttl, unsigned long tv);
111 void yac_storage_flush(void);
112 const char * yac_storage_shared_memory_name(void);
113 yac_storage_info * yac_storage_get_info(void);
114 void yac_storage_free_info(yac_storage_info *info);
115 yac_item_list * yac_storage_dump(unsigned int limit);
116 void yac_storage_free_list(yac_item_list *list);
117 #define yac_storage_exists(ht, key, len) yac_storage_find(ht, key, len, NULL)
118
119 #endif /* YAC_STORAGE_H */
120
121 /*
122 * Local variables:
123 * tab-width: 4
124 * c-basic-offset: 4
125 * End:
126 * vim600: noet sw=4 ts=4 fdm=marker
127 * vim<600: noet sw=4 ts=4
128 */
+0
-21
yac-0.9.2/tests/001.phpt less more
0 --TEST--
1 Check for yac presence
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --FILE--
5 <?php
6 echo "yac extension is available";
7 /*
8 you can add regression tests for your extension here
9
10 the output of your test code has to be equal to the
11 text in the --EXPECT-- section below for the tests
12 to pass, differences between the output and the
13 expected text are interpreted as failure
14
15 see php5/README.TESTING for further information on
16 writing regression tests
17 */
18 ?>
19 --EXPECT--
20 yac extension is available
+0
-92
yac-0.9.2/tests/002.phpt less more
0 --TEST--
1 Check for yac basic functions
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 <?php if (YAC_SERIALIZER != "PHP") print "skip"; ?>
5 --INI--
6 yac.enable=1
7 yac.enable_cli=1
8 yac.keys_memory_size=4M
9 yac.values_memory_size=32M
10 --FILE--
11 <?php
12 $yac = new Yac();
13
14 $key = "foo";
15 $value = "dummy";
16
17 var_dump($yac->set($key, $value));
18 var_dump($yac->get($key));
19
20 $value = NULL;
21 var_dump($yac->set($key, $value));
22 var_dump($yac->get($key));
23
24 $value = TRUE;
25 var_dump($yac->set($key, $value));
26 var_dump($yac->get($key));
27
28 $value = FALSE;
29 var_dump($yac->set($key, $value));
30 var_dump($yac->get($key));
31
32 $value = range(1, 5);
33 var_dump($yac->set($key, $value));
34 var_dump($yac->get($key));
35
36 $value = 9234324;
37 var_dump($yac->set($key, $value));
38 var_dump($yac->get($key));
39
40 $value = 9234324.123456;
41 var_dump($yac->set($key, $value));
42 var_dump($yac->get($key));
43
44 $value = new StdClass();;
45 var_dump($yac->set($key, $value));
46 var_dump($yac->get($key));
47
48 $value = fopen("php://input", "r");
49 var_dump($yac->set($key, $value));
50
51 $value = range(1, 5);
52 var_dump($yac->set($key, $value));
53 var_dump($yac->delete($key));
54 var_dump($yac->get($key));
55
56 ?>
57 --EXPECTF--
58 bool(true)
59 string(5) "dummy"
60 bool(true)
61 NULL
62 bool(true)
63 bool(true)
64 bool(true)
65 bool(false)
66 bool(true)
67 array(5) {
68 [0]=>
69 int(1)
70 [1]=>
71 int(2)
72 [2]=>
73 int(3)
74 [3]=>
75 int(4)
76 [4]=>
77 int(5)
78 }
79 bool(true)
80 int(9234324)
81 bool(true)
82 float(9234324.123456)
83 bool(true)
84 object(stdClass)#3 (0) {
85 }
86
87 Warning: Yac::set(): Type 'IS_RESOURCE' cannot be stored in %s002.php on line %d
88 bool(false)
89 bool(true)
90 bool(true)
91 bool(false)
+0
-48
yac-0.9.2/tests/003.phpt less more
0 --TEST--
1 Check for yac errors
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $key = str_repeat("k", YAC_MAX_KEY_LEN - 1);
14 $value = NULL;
15
16 var_dump($yac->set($key, $value));
17 var_dump($yac->get($key));
18
19 $key = str_repeat("k", YAC_MAX_KEY_LEN);
20 var_dump($yac->set($key, $value));
21 var_dump($yac->get($key));
22
23 $key = str_repeat("k", YAC_MAX_KEY_LEN + 1);
24 var_dump($yac->set($key, $value));
25 var_dump($yac->get($key));
26
27 $yac = new Yac("dummy");
28 var_dump($yac->set($key, $value));
29 var_dump($yac->get($key));
30 ?>
31 --EXPECTF--
32 bool(true)
33 NULL
34 bool(true)
35 NULL
36
37 Warning: Yac::set(): Key can not be longer than 48 bytes in %s003.php on line %d
38 bool(false)
39
40 Warning: Yac::get(): Key can not be longer than 48 bytes in %s003.php on line %d
41 bool(false)
42
43 Warning: Yac::set(): Key(include prefix) can not be longer than 48 bytes in %s003.php on line %d
44 bool(false)
45
46 Warning: Yac::get(): Key(include prefix) can not be longer than 48 bytes in %s003.php on line %d
47 bool(false)
+0
-38
yac-0.9.2/tests/004.phpt less more
0 --TEST--
1 Check for yac ttl
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $key = "foo";
14 $value = "dummy";
15
16 var_dump($yac->set($key, $value, 1));
17 var_dump($yac->get($key));
18 sleep(1);
19 var_dump($yac->get($key));
20
21 var_dump($yac->set($key, $value));
22 var_dump($yac->get($key));
23 var_dump($yac->delete($key, 1));
24 var_dump($yac->get($key));
25 sleep(1);
26 var_dump($yac->get($key));
27
28 ?>
29 --EXPECTF--
30 bool(true)
31 string(5) "dummy"
32 bool(false)
33 bool(true)
34 string(5) "dummy"
35 bool(true)
36 string(5) "dummy"
37 bool(false)
+0
-45
yac-0.9.2/tests/005.phpt less more
0 --TEST--
1 Check for yac non-string key
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $key = md5(12345);
14 $value = "dummy";
15
16 var_dump($yac->set($key, $value, 1));
17 var_dump($yac->get($key));
18
19 $key = 12345.12345;
20 var_dump($yac->set($key, $value, 1));
21 var_dump($yac->get($key));
22
23 $key = range(1, 2);
24 var_dump($yac->set($key, $value, 1));
25 var_dump($yac->get($key));
26
27 $key = new StdClass();
28 var_dump($yac->set($key, $value, 1));
29 var_dump($yac->get($key));
30 ?>
31 --EXPECTF--
32 bool(true)
33 string(5) "dummy"
34 bool(true)
35 string(5) "dummy"
36 bool(true)
37 array(2) {
38 [1]=>
39 int(2)
40 [2]=>
41 bool(false)
42 }
43
44 Catchable fatal error: Object of class stdClass could not be converted to string in %s005.php on line %d
+0
-32
yac-0.9.2/tests/006.phpt less more
0 --TEST--
1 Check for yac multi set/get
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11
12 $yac = new Yac();
13
14 for ($i = 0; $i<1000; $i++) {
15 $key = "xxx" . rand(1, 100000);
16 $value = str_repeat("a", rand(1, 100000));
17
18 if (!$yac->set($key, $value)) {
19 var_dump($key, $value);
20 var_dump("write " . $i);
21 }
22
23 if ($value != ($new = $yac->get($key))) {
24 var_dump($new);
25 var_dump("read " . $i);
26 }
27 }
28
29 var_dump($i);
30 --EXPECTF--
31 int(1000)
+0
-41
yac-0.9.2/tests/007.phpt less more
0 --TEST--
1 Check for yac info
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11
12 $yac = new Yac();
13
14 for ($i = 0; $i<1000; $i++) {
15 $key = "xxx" . rand(1, 1000);
16 $value = str_repeat("a", rand(1, 100000));
17
18 if (!$yac->set($key, $value)) {
19 var_dump($key, $value);
20 var_dump("write " . $i);
21 }
22
23 if ($value != ($new = $yac->get($key))) {
24 var_dump($new);
25 var_dump("read " . $i);
26 }
27 }
28
29 $info = $yac->info();
30 var_dump($info['slots_used'] <= 1000);
31 var_dump($info['hits']);
32 var_dump($info['miss']);
33 var_dump($info['fails']);
34 var_dump($info['kicks']);
35 --EXPECTF--
36 bool(true)
37 int(1000)
38 int(0)
39 int(0)
40 int(0)
+0
-39
yac-0.9.2/tests/008.phpt less more
0 --TEST--
1 Check for yac prefix
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac("dummy_");
12 $yac2 = new Yac();
13
14 $key = "bar";
15 $value = true;
16
17 $yac->set($key, $value);
18 var_dump($yac->get($key)); //true
19 var_dump($yac2->get($key)); //false
20 var_dump($yac2->get("dummy_" . $key)); //true
21
22 $yac2->delete($key); //fail
23 var_dump($yac->get($key)); //true
24
25 $yac->delete($key); //okey
26 var_dump($yac->get($key)); //false
27
28 $yac->set($key, $value);
29 $yac2->delete("dummy_" . $key); //okey
30 var_dump($yac->get($key)); //false
31 ?>
32 --EXPECTF--
33 bool(true)
34 bool(false)
35 bool(true)
36 bool(true)
37 bool(false)
38 bool(false)
+0
-39
yac-0.9.2/tests/009.phpt less more
0 --TEST--
1 Check for yac multi ops
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $values = array();
14 $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
15 for ($i = 0; $i < 100; $i++) {
16 $key = substr(str_shuffle($chars), 0, rand(16, 32));
17 $value = md5($key . rand(1, 10000));
18 $values[$key] = $value;
19 }
20
21 $numbers = count($values);
22
23 var_dump($yac->set($values));
24
25 $keys = array_keys($values);
26 $ret = $yac->get($keys);
27 var_dump(count(array_filter($ret)) == $numbers);
28
29 $disable = array_slice($keys, 0, -10);
30 $yac->delete($disable);
31
32 $ret = $yac->get($keys);
33 var_dump(count(array_filter($ret)) == 10);
34 ?>
35 --EXPECTF--
36 bool(true)
37 bool(true)
38 bool(true)
+0
-35
yac-0.9.2/tests/010.phpt less more
0 --TEST--
1 Check for yac::flush
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $values = array();
14 $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
15 for ($i = 0; $i < 100; $i++) {
16 $key = substr(str_shuffle($chars), 0, rand(16, 32));
17 $value = md5($key . rand(1, 10000));
18 $values[$key] = $value;
19 }
20
21 $numbers = count($values);
22
23 var_dump($yac->set($values));
24
25 $yac->flush();
26
27 var_dump($yac->get($key));
28 $info = $yac->info();
29 var_dump($info['slots_used']);
30 ?>
31 --EXPECTF--
32 bool(true)
33 bool(false)
34 int(0)
+0
-38
yac-0.9.2/tests/011.phpt less more
0 --TEST--
1 Check for yac::add
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=4M
8 yac.values_memory_size=32M
9 --FILE--
10 <?php
11 $yac = new Yac();
12
13 $key = "dummy";
14 $value = "foo";
15 var_dump($yac->add($key, $value)); // true
16 var_dump($yac->add($key, $value)); // false
17 var_dump($yac->set($key, $value)); // true
18 var_dump($yac->get($key)); // foo
19 var_dump($yac->delete($key)); // true
20 $value = "bar";
21 var_dump($yac->add($key, $value, 1)); //true
22 var_dump($yac->add($key, $value, 1)); //false
23 var_dump($yac->get($key)); //bar
24 sleep(1);
25 var_dump($yac->add($key, $value)); //true
26
27 ?>
28 --EXPECTF--
29 bool(true)
30 bool(false)
31 bool(true)
32 string(3) "foo"
33 bool(true)
34 bool(true)
35 bool(false)
36 string(3) "bar"
37 bool(true)
+0
-33
yac-0.9.2/tests/012.phpt less more
0 --TEST--
1 Check for functional apis
2 --SKIPIF--
3 <?php
4 if (!extension_loaded("yac")) print "skip";
5 print "skip Functional style APIs are not enabled";
6 ?>
7 --INI--
8 yac.enable=1
9 yac.enable_cli=1
10 yac.keys_memory_size=4M
11 yac.values_memory_size=32M
12 --FILE--
13 <?php
14 $key = "dummy";
15 $value = "foo";
16 var_dump(yac_set($key, $value)); //true
17 var_dump(yac_add($key, $value)); //false
18 var_dump(yac_get($key)); //foo
19 var_dump(yac_delete($key)); //true
20 var_dump(yac_set($key, $value)); //true
21 var_dump(yac_flush()); //true
22 $info = yac_info();
23 var_dump($info['slots_used']); //0
24 ?>
25 --EXPECTF--
26 bool(true)
27 bool(false)
28 string(3) "foo"
29 bool(true)
30 bool(true)
31 bool(true)
32 int(0)
+0
-16
yac-0.9.2/tests/013.phpt less more
0 --TEST--
1 Check for ttl bug
2 --INI--
3 yac.enable=1
4 yac.enable_cli=1
5 yac.keys_memory_size=4M
6 yac.values_memory_size=32M
7 --FILE--
8 <?php
9 $yac = new Yac();
10 $yac->set('test', 1, 1);
11 sleep(2);
12 var_dump($yac->get('test'));
13 ?>
14 --EXPECTF--
15 bool(false)
+0
-26
yac-0.9.2/tests/014.phpt less more
0 --TEST--
1 Check for ttl bug
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 <?php if (YAC_SERIALIZER != "PHP") print "skip"; ?>
5 --INI--
6 yac.enable=1
7 yac.enable_cli=1
8 yac.keys_memory_size=4M
9 yac.values_memory_size=32M
10 yac.compress_threshold=1024
11 --FILE--
12 <?php
13 error_reporting(E_ALL);
14 $yac = new Yac();
15
16 for($i = 0; $i<100; $i++) {
17 $value[] = ($i + 100000)."sdfsfsfsfs";
18 }
19
20 $yac->set('test', $value);
21
22 echo count($yac->get('test'));
23 ?>
24 --EXPECTF--
25 100
+0
-22
yac-0.9.2/tests/015.phpt less more
0 --TEST--
1 Check for Yac::dump
2 --INI--
3 yac.enable=1
4 yac.enable_cli=1
5 yac.keys_memory_size=4M
6 yac.values_memory_size=32M
7 yac.compress_threshold=1024
8 --FILE--
9 <?php
10 $yac = new Yac();
11
12 for ($i = 0; $i<100; $i++) {
13 $yac->set("key". $i, "kjslkdfkldasjkf");
14 }
15 for ($i = 0; $i<100; $i++) {
16 $yac->set("key". $i, "kjslkdfkldasjkf");
17 }
18
19 var_dump(count($yac->dump(1000)));
20 --EXPECTF--
21 int(100)
+0
-24
yac-0.9.2/tests/issue012.phpt less more
0 --TEST--
1 ISSUE #12 segfault if use mmap&k_size bigger than 4M
2 --SKIPIF--
3 <?php if (!extension_loaded("yac")) print "skip"; ?>
4 --INI--
5 yac.enable=1
6 yac.enable_cli=1
7 yac.keys_memory_size=8M
8 yac.values_memory_size=128M
9 --FILE--
10 <?php
11 $yac = new Yac();
12 $i = 0;
13 while (true) {
14 $yac->set(rand(), strval(rand()), 2);
15 $i++;
16 if ($i > 20000) {
17 break;
18 }
19 }
20 ?>
21 OKEY
22 --EXPECTF--
23 OKEY
+0
-1005
yac-0.9.2/yac.c less more
0 /*
1 +----------------------------------------------------------------------+
2 | Yet Another Cache |
3 +----------------------------------------------------------------------+
4 | Copyright (c) 2013-2013 The PHP Group |
5 +----------------------------------------------------------------------+
6 | This source file is subject to version 3.01 of the PHP license, |
7 | that is bundled with this package in the file LICENSE, and is |
8 | available through the world-wide-web at the following url: |
9 | http://www.php.net/license/3_01.txt |
10 | If you did not receive a copy of the PHP license and are unable to |
11 | obtain it through the world-wide-web, please send a note to |
12 | license@php.net so we can mail you a copy immediately. |
13 +----------------------------------------------------------------------+
14 | Author: Xinchen Hui <laruence@php.net> |
15 +----------------------------------------------------------------------+
16 */
17
18 /* $Id$ */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <time.h>
25
26 #include "php.h"
27 #include "php_ini.h"
28 #include "ext/standard/info.h"
29 #include "ext/standard/php_smart_str.h" /* for smart_str */
30 #include "SAPI.h"
31
32 #include "php_yac.h"
33 #include "storage/yac_storage.h"
34 #include "serializer/yac_serializer.h"
35 #ifdef HAVE_FASTLZ_H
36 #include <fastlz.h>
37 #else
38 #include "compressor/fastlz/fastlz.h"
39 #endif
40
41 zend_class_entry *yac_class_ce;
42
43 ZEND_DECLARE_MODULE_GLOBALS(yac);
44
45 /** {{{ ARG_INFO
46 */
47 ZEND_BEGIN_ARG_INFO_EX(arginfo_yac_constructor, 0, 0, 0)
48 ZEND_ARG_INFO(0, prefix)
49 ZEND_END_ARG_INFO()
50
51 ZEND_BEGIN_ARG_INFO_EX(arginfo_yac_add, 0, 0, 1)
52 ZEND_ARG_INFO(0, keys)
53 ZEND_ARG_INFO(0, value)
54 ZEND_ARG_INFO(0, ttl)
55 ZEND_END_ARG_INFO()
56
57 ZEND_BEGIN_ARG_INFO_EX(arginfo_yac_get, 0, 0, 1)
58 ZEND_ARG_INFO(0, keys)
59 ZEND_END_ARG_INFO()
60
61 ZEND_BEGIN_ARG_INFO_EX(arginfo_yac_delete, 0, 0, 1)
62 ZEND_ARG_INFO(0, keys)
63 ZEND_ARG_INFO(0, ttl)
64 ZEND_END_ARG_INFO()
65
66 ZEND_BEGIN_ARG_INFO_EX(arginfo_yac_void, 0, 0, 0)
67 ZEND_END_ARG_INFO()
68 /* }}} */
69
70 static PHP_INI_MH(OnChangeKeysMemoryLimit) /* {{{ */ {
71 if (new_value) {
72 YAC_G(k_msize) = zend_atol(new_value, new_value_length);
73 }
74 return SUCCESS;
75 }
76 /* }}} */
77
78 static PHP_INI_MH(OnChangeValsMemoryLimit) /* {{{ */ {
79 if (new_value) {
80 YAC_G(v_msize) = zend_atol(new_value, new_value_length);
81 }
82 return SUCCESS;
83 }
84 /* }}} */
85
86 static PHP_INI_MH(OnChangeCompressThreshold) /* {{{ */ {
87 if (new_value) {
88 YAC_G(compress_threshold) = zend_atol(new_value, new_value_length);
89 if (YAC_G(compress_threshold) < YAC_MIN_COMPRESS_THRESHOLD) {
90 YAC_G(compress_threshold) = YAC_MIN_COMPRESS_THRESHOLD;
91 }
92 }
93 return SUCCESS;
94 }
95 /* }}} */
96
97 /* {{{ PHP_INI
98 */
99 PHP_INI_BEGIN()
100 STD_PHP_INI_BOOLEAN("yac.enable", "1", PHP_INI_SYSTEM, OnUpdateBool, enable, zend_yac_globals, yac_globals)
101 STD_PHP_INI_BOOLEAN("yac.debug", "0", PHP_INI_ALL, OnUpdateBool, debug, zend_yac_globals, yac_globals)
102 STD_PHP_INI_ENTRY("yac.keys_memory_size", "4M", PHP_INI_SYSTEM, OnChangeKeysMemoryLimit, k_msize, zend_yac_globals, yac_globals)
103 STD_PHP_INI_ENTRY("yac.values_memory_size", "64M", PHP_INI_SYSTEM, OnChangeValsMemoryLimit, v_msize, zend_yac_globals, yac_globals)
104 STD_PHP_INI_ENTRY("yac.compress_threshold", "-1", PHP_INI_SYSTEM, OnChangeCompressThreshold, compress_threshold, zend_yac_globals, yac_globals)
105 STD_PHP_INI_ENTRY("yac.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_yac_globals, yac_globals)
106 PHP_INI_END()
107 /* }}} */
108
109 static int yac_add_impl(char *prefix, uint prefix_len, char *key, uint len, zval *value, int ttl, int add TSRMLS_DC) /* {{{ */ {
110 int ret = 0, flag = Z_TYPE_P(value);
111 char *msg, buf[YAC_STORAGE_MAX_KEY_LEN];
112 time_t tv;
113
114 if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
115 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes",
116 prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
117 return ret;
118 }
119
120 if (prefix_len) {
121 len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
122 key = (char *)buf;
123 }
124
125
126 tv = time(NULL);
127 switch (Z_TYPE_P(value)) {
128 case IS_NULL:
129 ret = yac_storage_update(key, len, (char *)&flag, sizeof(int), flag, ttl, add, tv);
130 break;
131 case IS_BOOL:
132 case IS_LONG:
133 ret = yac_storage_update(key, len, (char *)&Z_LVAL_P(value), sizeof(long), flag, ttl, add, tv);
134 break;
135 case IS_DOUBLE:
136 ret = yac_storage_update(key, len, (char *)&Z_DVAL_P(value), sizeof(double), flag, ttl, add, tv);
137 break;
138 case IS_STRING:
139 case IS_CONSTANT:
140 {
141 if (Z_STRLEN_P(value) > YAC_G(compress_threshold) || Z_STRLEN_P(value) > YAC_STORAGE_MAX_ENTRY_LEN) {
142 int compressed_len;
143 char *compressed;
144
145 /* if longer than this, then we can not stored the length in flag */
146 if (Z_STRLEN_P(value) > YAC_ENTRY_MAX_ORIG_LEN) {
147 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d bytes) to be stored", Z_STRLEN_P(value));
148 return ret;
149 }
150
151 compressed = emalloc(Z_STRLEN_P(value) * 1.05);
152 compressed_len = fastlz_compress(Z_STRVAL_P(value), Z_STRLEN_P(value), compressed);
153 if (!compressed_len || compressed_len > Z_STRLEN_P(value)) {
154 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed");
155 efree(compressed);
156 return ret;
157 }
158
159 if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
160 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d bytes) to be stored", Z_STRLEN_P(value));
161 efree(compressed);
162 return ret;
163 }
164
165 flag |= YAC_ENTRY_COMPRESSED;
166 flag |= (Z_STRLEN_P(value) << YAC_ENTRY_ORIG_LEN_SHIT);
167 ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add, tv);
168 efree(compressed);
169 } else {
170 ret = yac_storage_update(key, len, Z_STRVAL_P(value), Z_STRLEN_P(value), flag, ttl, add, tv);
171 }
172 }
173 break;
174 case IS_ARRAY:
175 #ifdef IS_CONSTANT_ARRAY
176 case IS_CONSTANT_ARRAY:
177 #endif
178 case IS_OBJECT:
179 {
180 smart_str buf = {0};
181 #if ENABLE_MSGPACK
182 if (yac_serializer_msgpack_pack(value, &buf, &msg TSRMLS_CC)) {
183 #else
184
185 if (yac_serializer_php_pack(value, &buf, &msg TSRMLS_CC)) {
186 #endif
187 if (buf.len > YAC_G(compress_threshold) || buf.len > YAC_STORAGE_MAX_ENTRY_LEN) {
188 int compressed_len;
189 char *compressed;
190
191 if (buf.len > YAC_ENTRY_MAX_ORIG_LEN) {
192 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
193 return ret;
194 }
195
196 compressed = emalloc(buf.len * 1.05);
197 compressed_len = fastlz_compress(buf.c, buf.len, compressed);
198 if (!compressed_len || compressed_len > buf.len) {
199 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed");
200 efree(compressed);
201 return ret;
202 }
203
204 if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
205 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
206 efree(compressed);
207 return ret;
208 }
209
210 flag |= YAC_ENTRY_COMPRESSED;
211 flag |= (buf.len << YAC_ENTRY_ORIG_LEN_SHIT);
212 ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add, tv);
213 efree(compressed);
214 } else {
215 ret = yac_storage_update(key, len, buf.c, buf.len, flag, ttl, add, tv);
216 }
217 smart_str_free(&buf);
218 } else {
219 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serialization failed");
220 smart_str_free(&buf);
221 }
222 }
223 break;
224 case IS_RESOURCE:
225 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type 'IS_RESOURCE' cannot be stored");
226 break;
227 default:
228 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported valued type to be stored '%d'", flag);
229 break;
230 }
231
232 return ret;
233 }
234 /* }}} */
235
236 static int yac_add_multi_impl(char *prefix, uint prefix_len, zval *kvs, int ttl, int add TSRMLS_DC) /* {{{ */ {
237 HashTable *ht = Z_ARRVAL_P(kvs);
238
239 for (zend_hash_internal_pointer_reset(ht);
240 zend_hash_has_more_elements(ht) == SUCCESS;
241 zend_hash_move_forward(ht)) {
242 char *key;
243 ulong idx;
244 zval **value;
245 uint len, should_free = 0;
246
247 if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) {
248 continue;
249 }
250
251 switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
252 case HASH_KEY_IS_LONG:
253 len = spprintf(&key, 0, "%lu", idx) + 1;
254 should_free = 1;
255 case HASH_KEY_IS_STRING:
256 if (yac_add_impl(prefix, prefix_len, key, len - 1, *value, ttl, add TSRMLS_CC)) {
257 if (should_free) {
258 efree(key);
259 }
260 continue;
261 } else {
262 if (should_free) {
263 efree(key);
264 }
265 return 0;
266 }
267 default:
268 continue;
269 }
270 }
271
272 return 1;
273 }
274 /* }}} */
275
276 static zval * yac_get_impl(char * prefix, uint prefix_len, char *key, uint len, uint *cas TSRMLS_DC) /* {{{ */ {
277 zval *ret = NULL;
278 uint flag, size = 0;
279 char *data, *msg, buf[YAC_STORAGE_MAX_KEY_LEN];
280 time_t tv;
281
282 if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
283 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes",
284 prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
285 return ret;
286 }
287
288 if (prefix_len) {
289 len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
290 key = (char *)buf;
291 }
292
293 tv = time(NULL);
294 if (yac_storage_find(key, len, &data, &size, &flag, (int *)cas, tv)) {
295 switch ((flag & YAC_ENTRY_TYPE_MASK)) {
296 case IS_NULL:
297 if (size == sizeof(int)) {
298 MAKE_STD_ZVAL(ret);
299 ZVAL_NULL(ret);
300 }
301 efree(data);
302 break;
303 case IS_BOOL:
304 case IS_LONG:
305 if (size == sizeof(long)) {
306 MAKE_STD_ZVAL(ret);
307 Z_TYPE_P(ret) = flag;
308 Z_LVAL_P(ret) = *(long*)data;
309 }
310 efree(data);
311 break;
312 case IS_DOUBLE:
313 if (size == sizeof(double)) {
314 MAKE_STD_ZVAL(ret);
315 Z_TYPE_P(ret) = flag;
316 Z_DVAL_P(ret) = *(double*)data;
317 }
318 efree(data);
319 break;
320 case IS_STRING:
321 case IS_CONSTANT:
322 {
323 if ((flag & YAC_ENTRY_COMPRESSED)) {
324 size_t orig_len = ((uint)flag >> YAC_ENTRY_ORIG_LEN_SHIT);
325 char *origin = emalloc(orig_len + 1);
326 uint length;
327 length = fastlz_decompress(data, size, origin, orig_len);
328 if (!length) {
329 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompression failed");
330 efree(data);
331 efree(origin);
332 return ret;
333 }
334 MAKE_STD_ZVAL(ret);
335 ZVAL_STRINGL(ret, origin, length, 0);
336 efree(data);
337 } else {
338 MAKE_STD_ZVAL(ret);
339 ZVAL_STRINGL(ret, data, size, 0);
340 Z_TYPE_P(ret) = flag;
341 }
342 }
343 break;
344 case IS_ARRAY:
345 #ifdef IS_CONSTANT_ARRAY
346 case IS_CONSTANT_ARRAY:
347 #endif
348 case IS_OBJECT:
349 {
350 if ((flag & YAC_ENTRY_COMPRESSED)) {
351 size_t length, orig_len = ((uint)flag >> YAC_ENTRY_ORIG_LEN_SHIT);
352 char *origin = emalloc(orig_len + 1);
353 length = fastlz_decompress(data, size, origin, orig_len);
354 if (!length) {
355 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompression failed");
356 efree(data);
357 efree(origin);
358 return ret;
359 }
360 efree(data);
361 data = origin;
362 size = length;
363 }
364 #if ENABLE_MSGPACK
365 ret = yac_serializer_msgpack_unpack(data, size, &msg TSRMLS_CC);
366 #else
367 ret = yac_serializer_php_unpack(data, size, &msg TSRMLS_CC);
368 #endif
369 if (!ret) {
370 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unserialization failed");
371 }
372 efree(data);
373 }
374 break;
375 default:
376 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected valued type '%d'", flag);
377 break;
378 }
379 }
380
381 return ret;
382 }
383 /* }}} */
384
385 static zval * yac_get_multi_impl(char *prefix, uint prefix_len, zval *keys, zval *cas TSRMLS_DC) /* {{{ */ {
386 zval *ret;
387 HashTable *ht = Z_ARRVAL_P(keys);
388
389 MAKE_STD_ZVAL(ret);
390 array_init(ret);
391
392 for (zend_hash_internal_pointer_reset(ht);
393 zend_hash_has_more_elements(ht) == SUCCESS;
394 zend_hash_move_forward(ht)) {
395 uint cas;
396 zval **value, *v;
397
398 if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) {
399 continue;
400 }
401
402 switch (Z_TYPE_PP(value)) {
403 case IS_STRING:
404 if ((v = yac_get_impl(prefix, prefix_len, Z_STRVAL_PP(value), Z_STRLEN_PP(value), &cas TSRMLS_CC))) {
405 add_assoc_zval_ex(ret, Z_STRVAL_PP(value), Z_STRLEN_PP(value) + 1, v);
406 } else {
407 add_assoc_bool_ex(ret, Z_STRVAL_PP(value), Z_STRLEN_PP(value) + 1, 0);
408 }
409 continue;
410 default:
411 {
412 zval copy;
413 int use_copy;
414 zend_make_printable_zval(*value, &copy, &use_copy);
415 if ((v = yac_get_impl(prefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), &cas TSRMLS_CC))) {
416 add_assoc_zval_ex(ret, Z_STRVAL(copy), Z_STRLEN(copy) + 1, v);
417 } else {
418 add_assoc_bool_ex(ret, Z_STRVAL(copy), Z_STRLEN(copy) + 1, 0);
419 }
420 zval_dtor(&copy);
421 }
422 continue;
423 }
424 }
425
426 return ret;
427 }
428 /* }}} */
429
430 void yac_delete_impl(char *prefix, uint prefix_len, char *key, uint len, int ttl TSRMLS_DC) /* {{{ */ {
431 char buf[YAC_STORAGE_MAX_KEY_LEN];
432 time_t tv = 0;
433
434 if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
435 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes",
436 prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
437 return;
438 }
439
440 if (prefix_len) {
441 len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
442 key = (char *)buf;
443 }
444
445 if (ttl) {
446 tv = (ulong)time(NULL);
447 }
448
449 yac_storage_delete(key, len, ttl, tv);
450 }
451 /* }}} */
452
453 static void yac_delete_multi_impl(char *prefix, uint prefix_len, zval *keys, int ttl TSRMLS_DC) /* {{{ */ {
454 HashTable *ht = Z_ARRVAL_P(keys);
455
456 for (zend_hash_internal_pointer_reset(ht);
457 zend_hash_has_more_elements(ht) == SUCCESS;
458 zend_hash_move_forward(ht)) {
459 zval **value;
460
461 if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) {
462 continue;
463 }
464
465 switch (Z_TYPE_PP(value)) {
466 case IS_STRING:
467 yac_delete_impl(prefix, prefix_len, Z_STRVAL_PP(value), Z_STRLEN_PP(value), ttl TSRMLS_CC);
468 continue;
469 default:
470 {
471 zval copy;
472 int use_copy;
473 zend_make_printable_zval(*value, &copy, &use_copy);
474 yac_delete_impl(prefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), ttl TSRMLS_CC);
475 zval_dtor(&copy);
476 }
477 continue;
478 }
479 }
480 }
481 /* }}} */
482
483 /** {{{ proto public Yac::__construct([string $prefix])
484 */
485 PHP_METHOD(yac, __construct) {
486 char *prefix;
487 uint len = 0;
488
489 if (!YAC_G(enable)) {
490 return;
491 }
492
493 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &prefix, &len) == FAILURE) {
494 return;
495 }
496
497 if (len == 0) {
498 return;
499 }
500
501 zend_update_property_stringl(yac_class_ce, getThis(), ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, prefix, len TSRMLS_CC);
502
503 }
504 /* }}} */
505
506 /** {{{ proto public Yac::add(mixed $keys, mixed $value[, int $ttl])
507 */
508 PHP_METHOD(yac, add) {
509 long ttl = 0;
510 zval *keys, *prefix, *value = NULL;
511 char *sprefix = NULL;
512 uint ret, prefix_len = 0;
513
514 if (!YAC_G(enable)) {
515 RETURN_FALSE;
516 }
517
518 switch (ZEND_NUM_ARGS()) {
519 case 1:
520 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &keys) == FAILURE) {
521 return;
522 }
523 break;
524 case 2:
525 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &keys, &value) == FAILURE) {
526 return;
527 }
528 if (Z_TYPE_P(keys) == IS_ARRAY) {
529 if (Z_TYPE_P(value) == IS_LONG) {
530 ttl = Z_LVAL_P(value);
531 value = NULL;
532 } else {
533 php_error_docref(NULL TSRMLS_CC, E_WARNING, "ttl parameter must be an integer");
534 return;
535 }
536 }
537 break;
538 case 3:
539 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzl", &keys, &value, &ttl) == FAILURE) {
540 return;
541 }
542 break;
543 default:
544 WRONG_PARAM_COUNT;
545 }
546
547 prefix = zend_read_property(yac_class_ce, getThis(), ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, 0 TSRMLS_CC);
548 sprefix = Z_STRVAL_P(prefix);
549 prefix_len = Z_STRLEN_P(prefix);
550
551 if (Z_TYPE_P(keys) == IS_ARRAY) {
552 ret = yac_add_multi_impl(sprefix, prefix_len, keys, ttl, 1 TSRMLS_CC);
553 } else if (Z_TYPE_P(keys) == IS_STRING) {
554 ret = yac_add_impl(sprefix, prefix_len, Z_STRVAL_P(keys), Z_STRLEN_P(keys), value, ttl, 1 TSRMLS_CC);
555 } else {
556 zval copy;
557 int use_copy;
558 zend_make_printable_zval(keys, &copy, &use_copy);
559 ret = yac_add_impl(sprefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), value, ttl, 1 TSRMLS_CC);
560 zval_dtor(&copy);
561 }
562
563 RETURN_BOOL(ret? 1 : 0);
564 }
565 /* }}} */
566
567 /** {{{ proto public Yac::set(mixed $keys, mixed $value[, int $ttl])
568 */
569 PHP_METHOD(yac, set) {
570 long ttl = 0;
571 zval *keys, *prefix, *value = NULL;
572 char *sprefix = NULL;
573 uint ret, prefix_len = 0;
574
575 if (!YAC_G(enable)) {
576 RETURN_FALSE;
577 }
578
579 switch (ZEND_NUM_ARGS()) {
580 case 1:
581 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &keys) == FAILURE) {
582 return;
583 }
584 break;
585 case 2:
586 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &keys, &value) == FAILURE) {
587 return;
588 }
589 if (Z_TYPE_P(keys) == IS_ARRAY) {
590 if (Z_TYPE_P(value) == IS_LONG) {
591 ttl = Z_LVAL_P(value);
592 value = NULL;
593 } else {
594 php_error_docref(NULL TSRMLS_CC, E_WARNING, "ttl parameter must be an integer");
595 return;
596 }
597 }
598 break;
599 case 3:
600 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzl", &keys, &value, &ttl) == FAILURE) {
601 return;
602 }
603 break;
604 default:
605 WRONG_PARAM_COUNT;
606 }
607
608 prefix = zend_read_property(yac_class_ce, getThis(), ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, 0 TSRMLS_CC);
609 sprefix = Z_STRVAL_P(prefix);
610 prefix_len = Z_STRLEN_P(prefix);
611
612 if (Z_TYPE_P(keys) == IS_ARRAY) {
613 ret = yac_add_multi_impl(sprefix, prefix_len, keys, ttl, 0 TSRMLS_CC);
614 } else if (Z_TYPE_P(keys) == IS_STRING) {
615 ret = yac_add_impl(sprefix, prefix_len, Z_STRVAL_P(keys), Z_STRLEN_P(keys), value, ttl, 0 TSRMLS_CC);
616 } else {
617 zval copy;
618 int use_copy;
619 zend_make_printable_zval(keys, &copy, &use_copy);
620 ret = yac_add_impl(sprefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), value, ttl, 0 TSRMLS_CC);
621 zval_dtor(&copy);
622 }
623
624 RETURN_BOOL(ret? 1 : 0);
625 }
626 /* }}} */
627
628 /** {{{ proto public Yac::get(mixed $keys[, int &$cas])
629 */
630 PHP_METHOD(yac, get) {
631 char *sprefix = NULL;
632 uint prefix_len = 0, lcas = 0;
633 zval *ret, *keys, *prefix, *cas = NULL;
634
635 if (!YAC_G(enable)) {
636 RETURN_FALSE;
637 }
638
639 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &keys, &cas) == FAILURE) {
640 return;
641 }
642
643 prefix = zend_read_property(yac_class_ce, getThis(), ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, 0 TSRMLS_CC);
644 sprefix = Z_STRVAL_P(prefix);
645 prefix_len = Z_STRLEN_P(prefix);
646
647 if (Z_TYPE_P(keys) == IS_ARRAY) {
648 ret = yac_get_multi_impl(sprefix, prefix_len, keys, cas TSRMLS_CC);
649 } else if (Z_TYPE_P(keys) == IS_STRING) {
650 ret = yac_get_impl(sprefix, prefix_len, Z_STRVAL_P(keys), Z_STRLEN_P(keys), &lcas TSRMLS_CC);
651 } else {
652 zval copy;
653 int use_copy;
654 zend_make_printable_zval(keys, &copy, &use_copy);
655 ret = yac_get_impl(sprefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), &lcas TSRMLS_CC);
656 zval_dtor(&copy);
657 }
658
659 if (ret) {
660 RETURN_ZVAL(ret, 1, 1);
661 } else {
662 RETURN_FALSE;
663 }
664 }
665 /* }}} */
666
667 /** {{{ proto public Yac::delete(mixed $key[, int $delay = 0])
668 */
669 PHP_METHOD(yac, delete) {
670 long time = 0;
671 zval *keys, *prefix;
672 char *sprefix = NULL;
673 uint prefix_len = 0;
674
675 if (!YAC_G(enable)) {
676 RETURN_FALSE;
677 }
678
679 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &keys, &time) == FAILURE) {
680 return;
681 }
682
683 prefix = zend_read_property(yac_class_ce, getThis(), ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, 0 TSRMLS_CC);
684 sprefix = Z_STRVAL_P(prefix);
685 prefix_len = Z_STRLEN_P(prefix);
686
687 if (Z_TYPE_P(keys) == IS_ARRAY) {
688 yac_delete_multi_impl(sprefix, prefix_len, keys, time TSRMLS_CC);
689 } else if (Z_TYPE_P(keys) == IS_STRING) {
690 yac_delete_impl(sprefix, prefix_len, Z_STRVAL_P(keys), Z_STRLEN_P(keys), time TSRMLS_CC);
691 } else {
692 zval copy;
693 int use_copy;
694 zend_make_printable_zval(keys, &copy, &use_copy);
695 yac_delete_impl(sprefix, prefix_len, Z_STRVAL(copy), Z_STRLEN(copy), time TSRMLS_CC);
696 zval_dtor(&copy);
697 }
698
699 RETURN_TRUE;
700 }
701 /* }}} */
702
703 /** {{{ proto public Yac::flush(void)
704 */
705 PHP_METHOD(yac, flush) {
706
707 if (!YAC_G(enable)) {
708 RETURN_FALSE;
709 }
710
711 yac_storage_flush();
712
713 RETURN_TRUE;
714 }
715 /* }}} */
716
717 /** {{{ proto public Yac::info(void)
718 */
719 PHP_METHOD(yac, info) {
720 yac_storage_info *inf;
721
722 if (!YAC_G(enable)) {
723 RETURN_FALSE;
724 }
725
726 inf = yac_storage_get_info();
727
728 array_init(return_value);
729
730 add_assoc_long(return_value, "memory_size", inf->k_msize + inf->v_msize);
731 add_assoc_long(return_value, "slots_memory_size", inf->k_msize);
732 add_assoc_long(return_value, "values_memory_size", inf->v_msize);
733 add_assoc_long(return_value, "segment_size", inf->segment_size);
734 add_assoc_long(return_value, "segment_num", inf->segments_num);
735 add_assoc_long(return_value, "miss", inf->miss);
736 add_assoc_long(return_value, "hits", inf->hits);
737 add_assoc_long(return_value, "fails", inf->fails);
738 add_assoc_long(return_value, "kicks", inf->kicks);
739 add_assoc_long(return_value, "recycles", inf->recycles);
740 add_assoc_long(return_value, "slots_size", inf->slots_size);
741 add_assoc_long(return_value, "slots_used", inf->slots_num);
742
743 yac_storage_free_info(inf);
744 }
745 /* }}} */
746
747 /** {{{ proto public Yac::dump(int $limit)
748 */
749 PHP_METHOD(yac, dump) {
750 long limit = 100;
751 yac_item_list *list, *l;
752
753 if (!YAC_G(enable)) {
754 RETURN_FALSE;
755 }
756
757 array_init(return_value);
758
759 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &limit) == FAILURE) {
760 return;
761 }
762
763 list = l = yac_storage_dump(limit);
764 for (; l; l = l->next) {
765 zval *item;
766 MAKE_STD_ZVAL(item);
767 array_init(item);
768 add_assoc_long(item, "index", l->index);
769 add_assoc_long(item, "hash", l->h);
770 add_assoc_long(item, "crc", l->crc);
771 add_assoc_long(item, "ttl", l->ttl);
772 add_assoc_long(item, "k_len", l->k_len);
773 add_assoc_long(item, "v_len", l->v_len);
774 add_assoc_long(item, "size", l->size);
775 add_assoc_string(item, "key", l->key, 1);
776 add_next_index_zval(return_value, item);
777 }
778
779 yac_storage_free_list(list);
780 return;
781 }
782 /* }}} */
783
784 #if 0
785 only OO-style APIs is supported now
786 /* {{{{ proto bool yac_add(mixed $keys, mixed $value[, int $ttl])
787 */
788 PHP_FUNCTION(yac_add)
789 {
790 PHP_MN(yac_add)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
791 }
792 /* }}} */
793
794 /* {{{ proto bool yac_set(mixed $keys, mixed $value[, int $ttl])
795 */
796 PHP_FUNCTION(yac_set)
797 {
798 PHP_MN(yac_set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
799 }
800 /* }}} */
801
802 /* {{{ proto bool yac_get(mixed $keys[, int &$cas])
803 */
804 PHP_FUNCTION(yac_get)
805 {
806 PHP_MN(yac_get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
807 }
808 /* }}} */
809
810 /* {{{ proto bool yac_delete(mixed $keys[, int $delay = 0])
811 */
812 PHP_FUNCTION(yac_delete)
813 {
814 PHP_MN(yac_delete)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
815 }
816 /* }}} */
817
818 /* {{{ proto bool yac_flush(void)
819 */
820 PHP_FUNCTION(yac_flush)
821 {
822 PHP_MN(yac_flush)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
823 }
824 /* }}} */
825
826 /* {{{ proto bool yac_info(void)
827 */
828 PHP_FUNCTION(yac_info)
829 {
830 PHP_MN(yac_info)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
831 }
832 /* }}} */
833
834 /* {{{ yac_functions[] */
835 zend_function_entry yac_functions[] = {
836 PHP_FE(yac_add, arginfo_yac_add)
837 PHP_FE(yac_set, arginfo_yac_add)
838 PHP_FE(yac_get, arginfo_yac_get)
839 PHP_FE(yac_delete, arginfo_yac_delete)
840 PHP_FE(yac_flush, arginfo_yac_void)
841 PHP_FE(yac_info, arginfo_yac_void)
842 {NULL, NULL}
843 };
844 /* }}} */
845 #endif
846
847 /** {{{ yac_methods
848 */
849 zend_function_entry yac_methods[] = {
850 PHP_ME(yac, __construct, arginfo_yac_constructor, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
851 PHP_ME(yac, add, arginfo_yac_add, ZEND_ACC_PUBLIC)
852 PHP_ME(yac, set, arginfo_yac_add, ZEND_ACC_PUBLIC)
853 PHP_ME(yac, get, arginfo_yac_get, ZEND_ACC_PUBLIC)
854 PHP_ME(yac, delete, arginfo_yac_delete, ZEND_ACC_PUBLIC)
855 PHP_ME(yac, flush, arginfo_yac_void, ZEND_ACC_PUBLIC)
856 PHP_ME(yac, info, arginfo_yac_void, ZEND_ACC_PUBLIC)
857 PHP_ME(yac, dump, arginfo_yac_void, ZEND_ACC_PUBLIC)
858 {NULL, NULL, NULL}
859 };
860 /* }}} */
861
862 /* {{{ PHP_GINIT_FUNCTION
863 */
864 PHP_GINIT_FUNCTION(yac)
865 {
866 yac_globals->enable = 1;
867 yac_globals->k_msize = (4 * 1024 * 1024);
868 yac_globals->v_msize = (64 * 1024 * 1024);
869 yac_globals->debug = 0;
870 yac_globals->compress_threshold = -1;
871 yac_globals->enable_cli = 0;
872 #ifdef PHP_WIN32
873 yac_globals->mmap_base = NULL;
874 #endif
875 }
876 /* }}} */
877
878 /* {{{ PHP_MINIT_FUNCTION
879 */
880 PHP_MINIT_FUNCTION(yac)
881 {
882 char *msg;
883 zend_class_entry ce;
884
885 REGISTER_INI_ENTRIES();
886
887 if(!YAC_G(enable_cli) && !strcmp(sapi_module.name, "cli")) {
888 YAC_G(enable) = 0;
889 }
890
891 if (YAC_G(enable)) {
892 if (!yac_storage_startup(YAC_G(k_msize), YAC_G(v_msize), &msg)) {
893 php_error(E_ERROR, "Shared memory allocator startup failed at '%s': %s", msg, strerror(errno));
894 return FAILURE;
895 }
896 }
897
898 REGISTER_STRINGL_CONSTANT("YAC_VERSION", PHP_YAC_VERSION, sizeof(PHP_YAC_VERSION) - 1, CONST_PERSISTENT | CONST_CS);
899 REGISTER_LONG_CONSTANT("YAC_MAX_KEY_LEN", YAC_STORAGE_MAX_KEY_LEN, CONST_PERSISTENT | CONST_CS);
900 REGISTER_LONG_CONSTANT("YAC_MAX_VALUE_RAW_LEN", YAC_ENTRY_MAX_ORIG_LEN, CONST_PERSISTENT | CONST_CS);
901 REGISTER_LONG_CONSTANT("YAC_MAX_RAW_COMPRESSED_LEN", YAC_STORAGE_MAX_ENTRY_LEN, CONST_PERSISTENT | CONST_CS);
902 #if ENABLE_MSGPACK
903 REGISTER_STRINGL_CONSTANT("YAC_SERIALIZER", "PHP", sizeof("MSGPACK") -1, CONST_PERSISTENT | CONST_CS);
904 #else
905 REGISTER_STRINGL_CONSTANT("YAC_SERIALIZER", "PHP", sizeof("PHP") -1, CONST_PERSISTENT | CONST_CS);
906 #endif
907
908 INIT_CLASS_ENTRY(ce, "Yac", yac_methods);
909 yac_class_ce = zend_register_internal_class(&ce TSRMLS_CC);
910 zend_declare_property_stringl(yac_class_ce, ZEND_STRS(YAC_CLASS_PROPERTY_PREFIX) - 1, "", 0, ZEND_ACC_PROTECTED TSRMLS_CC);
911
912 return SUCCESS;
913 }
914 /* }}} */
915
916 /* {{{ PHP_MSHUTDOWN_FUNCTION
917 */
918 PHP_MSHUTDOWN_FUNCTION(yac)
919 {
920 UNREGISTER_INI_ENTRIES();
921 if (YAC_G(enable)) {
922 yac_storage_shutdown();
923 }
924 return SUCCESS;
925 }
926 /* }}} */
927
928 /* {{{ PHP_MINFO_FUNCTION
929 */
930 PHP_MINFO_FUNCTION(yac)
931 {
932 php_info_print_table_start();
933 php_info_print_table_header(2, "yac support", "enabled");
934 php_info_print_table_row(2, "Version", PHP_YAC_VERSION);
935 php_info_print_table_row(2, "Shared Memory", yac_storage_shared_memory_name());
936 #if ENABLE_MSGPACK
937 php_info_print_table_row(2, "Serializer", "msgpack");
938 #else
939 php_info_print_table_row(2, "Serializer", "php");
940 #endif
941 php_info_print_table_end();
942
943 DISPLAY_INI_ENTRIES();
944
945 if (YAC_G(enable)) {
946 char buf[64];
947 yac_storage_info *inf;
948 inf = yac_storage_get_info();
949
950 php_info_print_table_start();
951 php_info_print_table_colspan_header(2, "Cache info");
952 snprintf(buf, sizeof(buf), "%ld", inf->k_msize + inf->v_msize);
953 php_info_print_table_row(2, "Total Shared Memory Usage(memory_size)", buf);
954 snprintf(buf, sizeof(buf), "%ld", inf->k_msize);
955 php_info_print_table_row(2, "Total Shared Memory Usage for keys(keys_memory_size)", buf);
956 snprintf(buf, sizeof(buf), "%ld", inf->v_msize);
957 php_info_print_table_row(2, "Total Shared Memory Usage for values(values_memory_size)", buf);
958 snprintf(buf, sizeof(buf), "%ld", inf->segment_size);
959 php_info_print_table_row(2, "Size of Shared Memory Segment(segment_size)", buf);
960 snprintf(buf, sizeof(buf), "%ld", inf->segments_num);
961 php_info_print_table_row(2, "Number of Segments (segment_num)", buf);
962 snprintf(buf, sizeof(buf), "%ld", inf->slots_size);
963 php_info_print_table_row(2, "Total Slots Number(slots_size)", buf);
964 snprintf(buf, sizeof(buf), "%ld", inf->slots_num);
965 php_info_print_table_row(2, "Total Used Slots(slots_num)", buf);
966 php_info_print_table_end();
967
968 yac_storage_free_info(inf);
969 }
970 }
971 /* }}} */
972
973 #ifdef COMPILE_DL_YAC
974 ZEND_GET_MODULE(yac)
975 #endif
976
977 /* {{{ yac_module_entry
978 */
979 zend_module_entry yac_module_entry = {
980 STANDARD_MODULE_HEADER,
981 "yac",
982 NULL, /* yac_functions, */
983 PHP_MINIT(yac),
984 PHP_MSHUTDOWN(yac),
985 NULL,
986 NULL,
987 PHP_MINFO(yac),
988 PHP_YAC_VERSION,
989 PHP_MODULE_GLOBALS(yac),
990 PHP_GINIT(yac),
991 NULL,
992 NULL,
993 STANDARD_MODULE_PROPERTIES_EX
994 };
995 /* }}} */
996
997 /*
998 * Local variables:
999 * tab-width: 4
1000 * c-basic-offset: 4
1001 * End:
1002 * vim600: noet sw=4 ts=4 fdm=marker
1003 * vim<600: noet sw=4 ts=4
1004 */