Skip to content

Commit b786888

Browse files
committed
Initial Boost-based implementation.
0 parents  commit b786888

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+17752
-0
lines changed

.clang-format

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
BasedOnStyle: LLVM
2+
AlignConsecutiveAssignments: true
3+
AllowShortFunctionsOnASingleLine: false
4+
AllowShortIfStatementsOnASingleLine: false
5+
AllowShortLoopsOnASingleLine: false
6+
AlwaysBreakAfterDefinitionReturnType: true
7+
AlwaysBreakBeforeMultilineStrings: true
8+
BinPackParameters: false
9+
BreakBeforeBraces: Linux
10+
BreakConstructorInitializersBeforeComma: true
11+
ColumnLimit: 120
12+
ContinuationIndentWidth: 2
13+
Cpp11BracedListStyle: false
14+
DerivePointerAlignment: false
15+
IndentWidth: 4
16+
PointerAlignment: Left
17+
SpaceAfterCStyleCast: true
18+
TabWidth: 4
19+
UseTab: Never

.editorconfig

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
8+
[*.php]
9+
indent_style = space
10+
indent_size = 4
11+
trim_trailing_whitespace = true
12+
13+
[*.c]
14+
indent_style = space
15+
indent_size = 4
16+
trim_trailing_whitespace = true
17+
18+
[*.cpp]
19+
indent_style = space
20+
indent_size = 4
21+
trim_trailing_whitespace = true
22+
23+
[*.h]
24+
indent_style = space
25+
indent_size = 4
26+
trim_trailing_whitespace = true
27+
28+
[*.hpp]
29+
indent_style = space
30+
indent_size = 4
31+
trim_trailing_whitespace = true
32+
33+
[*.m4]
34+
indent_style = space
35+
indent_size = 2
36+
trim_trailing_whitespace = true
37+
38+
[*.md]
39+
indent_style = space
40+
indent_size = 4
41+
trim_trailing_whitespace = true

.gitignore

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
.libs
2+
Makefile
3+
Makefile.fragments
4+
Makefile.global
5+
Makefile.objects
6+
acinclude.m4
7+
aclocal.m4
8+
apm.la
9+
autom4te.cache/
10+
build/
11+
config.guess
12+
config.h
13+
config.h.in
14+
config.h.in~
15+
config.nice
16+
config.status
17+
config.sub
18+
configure
19+
configure.in
20+
install-sh
21+
libtool
22+
ltmain.sh
23+
missing
24+
mkinstalldirs
25+
modules/
26+
run-tests.php
27+
*.lo
28+
config.log
29+
.deps
30+
include/
31+
*.la
32+
*.log
33+
tests/*.diff
34+
tests/*.exp
35+
tests/*.out
36+
tests/*.php
37+
tests/*.sh

.travis.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
language: php
2+
3+
php:
4+
- 7.0
5+
- 7.1
6+
- nightly
7+
8+
script:
9+
- wget
10+
- phpize
11+
- ./configure --enable-uc --with-rocksdb=./rocksdb/
12+
- make
13+

LICENSE.txt

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
--------------------------------------------------------------------
2+
The PHP License, version 3.01
3+
Copyright (c) 1999 - 2014 The PHP Group. All rights reserved.
4+
--------------------------------------------------------------------
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, is permitted provided that the following conditions
8+
are met:
9+
10+
1. Redistributions of source code must retain the above copyright
11+
notice, this list of conditions and the following disclaimer.
12+
13+
2. Redistributions in binary form must reproduce the above copyright
14+
notice, this list of conditions and the following disclaimer in
15+
the documentation and/or other materials provided with the
16+
distribution.
17+
18+
3. The name "PHP" must not be used to endorse or promote products
19+
derived from this software without prior written permission. For
20+
written permission, please contact group@php.net.
21+
22+
4. Products derived from this software may not be called "PHP", nor
23+
may "PHP" appear in their name, without prior written permission
24+
from group@php.net. You may indicate that your software works in
25+
conjunction with PHP by saying "Foo for PHP" instead of calling
26+
it "PHP Foo" or "phpfoo"
27+
28+
5. The PHP Group may publish revised and/or new versions of the
29+
license from time to time. Each version will be given a
30+
distinguishing version number.
31+
Once covered code has been published under a particular version
32+
of the license, you may always continue to use it under the terms
33+
of that version. You may also choose to use such covered code
34+
under the terms of any subsequent version of the license
35+
published by the PHP Group. No one other than the PHP Group has
36+
the right to modify the terms applicable to covered code created
37+
under this License.
38+
39+
6. Redistributions of any form whatsoever must retain the following
40+
acknowledgment:
41+
"This product includes PHP software, freely available from
42+
<http://www.php.net/software/>".
43+
44+
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
45+
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
46+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
48+
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
49+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55+
OF THE POSSIBILITY OF SUCH DAMAGE.
56+
57+
--------------------------------------------------------------------
58+
59+
This software consists of voluntary contributions made by many
60+
individuals on behalf of the PHP Group.
61+
62+
The PHP Group can be contacted via Email at group@php.net.
63+
64+
For more information on the PHP Group and the PHP project,
65+
please see <http://www.php.net>.
66+
67+
PHP includes the Zend Engine, freely available at <http://www.zend.com>.

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# php-uc
2+
A PHP extension providing an APCu-compatible API built on Boost Interprocess.
3+
4+
## Building
5+
6+
1. Acquire build dependencies (Fedora instructions listed here):
7+
8+
sudo dnf install gcc-c++ boost boost-devel boost-interprocess boost-atomic
9+
10+
1. Build and install the PHP User Cache:
11+
12+
phpize
13+
./configure --enable-uc
14+
make
15+
sudo make install

TASKS.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
* Move DB initialization later so it runs after PHP-FPM drops privileges.
2+
* Fix `uc_clear_cache()`, possibly with optimization:
3+
https://github.com/facebook/rocksdb/wiki/Delete-A-Range-Of-Keys
4+
* Finish `UCIterator`.
5+
* Add existing APCu tests.
6+
* Add option to clear DB at PHP startup.
7+
* Use `rocksdb_writeoptions_disable_WAL` and write a telltale value on clean
8+
shutdown. Clear the full DB on startup if the value is missing.
9+
* Get static linking to RocksDB working.
10+
* Use kPointInTimeConsistency for WAL recovery.
11+
* Finish `.travis.yml`:
12+
13+
- php -n run-tests.php -n -d extension_dir=./modules/ -d extension=uc.so -d uc.enable=1 -p `phpenv which php` --show-diff --set-timeout 120

benchmark.php

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
// To run from the CLI:
4+
// php -d extension=modules/uc.so benchmark.php uc|apcu|memcache|sqlite
5+
6+
define('OPS', 1024 * 128 * 16);
7+
8+
function bsize($s)
9+
{
10+
foreach (array('','K','M','G') as $i => $k) {
11+
if ($s < 1024) break;
12+
$s/=1024;
13+
}
14+
return sprintf("%5.1f %sBytes",$s,$k);
15+
}
16+
17+
function show_fragmentation()
18+
{
19+
$mem = apcu_sma_info();
20+
// Fragementation: (freeseg - 1) / total_seg
21+
$nseg = $freeseg = $fragsize = $freetotal = 0;
22+
for($i=0; $i<$mem['num_seg']; $i++) {
23+
$ptr = 0;
24+
foreach($mem['block_lists'][$i] as $block) {
25+
if ($block['offset'] != $ptr) {
26+
++$nseg;
27+
}
28+
$ptr = $block['offset'] + $block['size'];
29+
/* Only consider blocks <5M for the fragmentation % */
30+
if($block['size']<(5*1024*1024)) $fragsize+=$block['size'];
31+
$freetotal+=$block['size'];
32+
}
33+
$freeseg += count($mem['block_lists'][$i]);
34+
}
35+
$frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg);
36+
echo 'Fragmentation: ' . $frag . PHP_EOL;
37+
}
38+
39+
global $argv;
40+
$backend = $argv[1];
41+
42+
switch ($backend) {
43+
case 'sqlite':
44+
$db = new PDO('sqlite:/var/tmp/php-uc.sqlite');
45+
$db->exec('CREATE TABLE uc (address TEXT PRIMARY KEY, data TEXT)');
46+
$store = $db->prepare('INSERT INTO uc (address, data) VALUES (:address, :data)');
47+
$fetch = $db->prepare('SELECT data FROM uc WHERE address = :address');
48+
$delete = $db->prepare('DELETE FROM uc WHERE address = :address');
49+
break;
50+
case 'memcache':
51+
$memcache_obj = memcache_connect('localhost', 11211);
52+
break;
53+
case 'apcu':
54+
case 'uc':
55+
break;
56+
default:
57+
echo 'Backend unknown: ' . $backend . PHP_EOL;
58+
die();
59+
}
60+
61+
echo 'Using backend: ' . $backend . PHP_EOL;
62+
63+
$bytes = 0;
64+
65+
for ($i = 0; $i < OPS; $i++) {
66+
if ($i % (OPS / 128) === 0) {
67+
echo 'Ops: ' . $i . ' / ' . OPS . ' (' . round($i/OPS * 100) . '%)' . PHP_EOL;
68+
// show_fragmentation();
69+
}
70+
$key = rand(1, 1024);
71+
$op = rand(0, 10);
72+
if ($op >= 0 && $op < 4) {
73+
$size = rand(1, 10000);
74+
$value = str_repeat('abcdefgh', $size);
75+
$bytes += $size * 8;
76+
switch ($backend) {
77+
case 'uc':
78+
uc_add('key' . $key, $value);
79+
break;
80+
case 'apcu':
81+
apcu_store('key' . $key, $value);
82+
break;
83+
}
84+
85+
//$memcache_obj->set('key' . $key, $value);
86+
//$store->bindValue(':address', 'key' . $key);
87+
//$store->bindValue(':data', $value);
88+
//$store->execute();
89+
}
90+
else if ($op >= 5 && $op < 9) {
91+
//apcu_fetch('key' . $key);
92+
//uc_fetch('key' . $key);
93+
//$memcache_obj->get('key' . $key);
94+
//$fetch->bindValue(':address', 'key' . $key);
95+
//$fetch->execute();
96+
}
97+
else {
98+
//apcu_delete('key' . $key);
99+
//uc_delete('key' . $key);
100+
//$memcache_obj->delete('key' . $key);
101+
//$delete->bindValue(':address', 'key' . $key);
102+
//$delete->execute();
103+
}
104+
}
105+
106+
//echo 'Wrote ' . round($bytes / 1024 / 1024) . ' MB and performed ' . OPS . ' operations.' . PHP_EOL;
107+
108+
//show_fragmentation();

config.m4

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
PHP_ARG_ENABLE(uc, whether to enable User Cache support,
2+
[ --enable-uc Enable User Cache support])
3+
4+
PHP_ARG_WITH(rocksdb, path to RocksDB for User Cache,
5+
[ --with-rocksdb=DIR Directory with static build of RocksDB])
6+
7+
if test "$PHP_UC" != "no"; then
8+
AC_DEFINE(UC, 1, [ ])
9+
10+
dnl Enable support for C++
11+
CXX_FLAGS="-std=c++14"
12+
CXXFLAGS="-std=c++14"
13+
AC_LANG_CPLUSPLUS
14+
PHP_REQUIRE_CXX()
15+
16+
PHP_ADD_LIBRARY(stdc++, 1, UC_SHARED_LIBADD)
17+
PHP_ADD_LIBRARY(boost_interprocess, 1, UC_SHARED_LIBADD)
18+
19+
uc_sources="uc.c \
20+
storage.cpp"
21+
22+
PHP_NEW_EXTENSION(uc, $uc_sources, $ext_shared)
23+
AC_DEFINE(HAVE_UC, 1, [ ])
24+
fi
25+

convert_tests.sh

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/sh
2+
sed -i 's/apc\.\([a-z_]*\)=/uc\.\1=/g' tests/*.phpt
3+
sed -i 's/apcu\.\([a-z_]*\)=/uc\.\1=/g' tests/*.phpt
4+
sed -i 's/apc_/uc_/g' tests/*.phpt
5+
sed -i 's/apcu_/uc_/g' tests/*.phpt
6+
sed -i 's/APCIterator/UCIterator/g' tests/*.phpt
7+
sed -i 's/APCuIterator/UCIterator/g' tests/*.phpt
8+
sed -i 's/APC: /UC: /' tests/*.phpt
9+

format.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
clang-format -i *.c *.h *.cpp *.hpp

0 commit comments

Comments
 (0)