├── tests ├── hdrhistogram_new.phpt ├── hdrhistogram_new_iterator.phpt ├── hdrhistogram_004.phpt ├── hdrhistogram_006.phpt ├── hdrhistogram_no_serialize.phpt ├── hdrhistogram_002.phpt ├── hdrhistogram_005.phpt ├── hdrhistogram_003.phpt ├── hdrhistogram_014.phpt ├── hdrhistogram_011.phpt ├── hdrhistogram_clone.phpt ├── hdrhistogram_015.phpt ├── hdrhistogram_007.phpt ├── hdrhistogram_001.phpt ├── hdrhistogram_010.phpt ├── hdrhistogram_new_error.phpt ├── hdrhistogram_012_php8.phpt ├── hdrhistogram_012.phpt ├── hdrhistogram_009.phpt ├── hdrhistogram_009_php8.phpt ├── hdrhistogram_013.phpt └── hdrhistogram_008.phpt ├── composer.json ├── .github ├── actions │ ├── install-hdrhistogram-c │ │ └── action.yml │ └── install-php │ │ └── action.yml └── workflows │ └── ci.yml ├── .gitignore ├── php_hdrhistogram.h ├── LICENSE ├── config.m4 ├── hdrhistogram.stub.php ├── README.md ├── package.xml ├── hdrhistogram_legacy_arginfo.h ├── hdrhistogram_arginfo.h └── hdrhistogram.c /tests/hdrhistogram_new.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: Directly constructing a HdrHistogram\Histogram object works. 3 | --FILE-- 4 | 8 | --EXPECTF-- 9 | object(HdrHistogram\Histogram)#%d (0) { 10 | } 11 | -------------------------------------------------------------------------------- /tests/hdrhistogram_new_iterator.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: Directly constructing a HdrHistogram\Iterator object works. 3 | --FILE-- 4 | 9 | --EXPECTF-- 10 | object(HdrHistogram\Iterator)#%d (0) { 11 | } 12 | -------------------------------------------------------------------------------- /tests/hdrhistogram_004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Value At Percentile 3 | --FILE-- 4 | 16 | --EXPECTF-- 17 | perc(50): 50 18 | perc(95): 95 19 | -------------------------------------------------------------------------------- /tests/hdrhistogram_006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Merge Into 3 | --FILE-- 4 | 17 | --EXPECT-- 18 | dropped: 0 19 | count(a+b): 30 20 | -------------------------------------------------------------------------------- /tests/hdrhistogram_no_serialize.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: Serializing a HdrHistogram\Histogram object is not allowed. 3 | --FILE-- 4 | getMessage(), PHP_EOL; 10 | } catch (Exception $e) { 11 | echo $e->getMessage(), PHP_EOL; 12 | } 13 | ?> 14 | --EXPECTF-- 15 | Serialization of 'HdrHistogram\Histogram' is not allowed 16 | -------------------------------------------------------------------------------- /tests/hdrhistogram_002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Reset Histogram 3 | --FILE-- 4 | 15 | --EXPECTF-- 16 | Max: 1 17 | Count(1): 1 18 | Max: 0 19 | Count(1): 0 20 | -------------------------------------------------------------------------------- /tests/hdrhistogram_005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Value At Percentile 3 | --FILE-- 4 | 18 | --EXPECT-- 19 | count(a): 10 20 | count(b): 20 21 | count(a+b): 30 22 | -------------------------------------------------------------------------------- /tests/hdrhistogram_003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Corrected Values 3 | --FILE-- 4 | 20 | --EXPECTF-- 21 | Mean: 10.25 22 | Max: 20 23 | Mean: 10 24 | Max: 20 25 | -------------------------------------------------------------------------------- /tests/hdrhistogram_014.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_import version 2 with json hashmap 3 | --FILE-- 4 | 13 | --EXPECTF-- 14 | array(1) { 15 | ["v"]=> 16 | array(2) { 17 | [0]=> 18 | int(-331) 19 | [1]=> 20 | int(1) 21 | } 22 | } 23 | array(1) { 24 | ["v"]=> 25 | array(2) { 26 | [0]=> 27 | int(-331) 28 | [1]=> 29 | int(1) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/hdrhistogram_011.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Total Count 3 | --FILE-- 4 | 23 | --EXPECT-- 24 | Count with 0 entries: 0 25 | Count with 100 entries: 100 26 | Count with 200 entries: 200 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beberlei/hdrhistogram", 3 | "type": "php-ext", 4 | "license": "BSD-2-Clause", 5 | "description": "A PHP extension wrapper for the C hdrhistogram API.", 6 | "require": { 7 | "php": ">=7.0,<8.5" 8 | }, 9 | "php-ext": { 10 | "extension-name": "ext-hdrhistogram", 11 | "priority": 20, 12 | "configure-options": [ 13 | { 14 | "name": "with-hdrhistogram", 15 | "description": "Enable \"hdrhistogram\" extension support", 16 | "needs-value": true 17 | }, 18 | { 19 | "name": "with-hdrhistogram-static", 20 | "description": "Enable static linking of libhdr_histogram" 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/hdrhistogram_clone.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: Cloning a HdrHistogram\Histogram object works. 3 | --FILE-- 4 | 21 | --EXPECTF-- 22 | int(1) 23 | int(1) 24 | int(2) 25 | int(2) 26 | int(1) 27 | int(1) 28 | int(2) 29 | int(2) 30 | int(2) 31 | int(3) 32 | -------------------------------------------------------------------------------- /.github/actions/install-hdrhistogram-c/action.yml: -------------------------------------------------------------------------------- 1 | name: Install HdrHistogram_c 2 | inputs: 3 | type: 4 | required: true 5 | version: 6 | required: true 7 | runs: 8 | using: composite 9 | steps: 10 | - uses: actions/checkout@v4 11 | with: 12 | repository: HdrHistogram/HdrHistogram_c 13 | path: HdrHistogram_c 14 | ref: ${{ inputs.version }} 15 | 16 | - shell: bash 17 | working-directory: ./HdrHistogram_c/ 18 | run: | 19 | env ${{ inputs.type == 'sanitize' && 'CFLAGS="-g -O0 -fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address" CC=clang-16 CXX=clang++-16' || (inputs.type == 'debug' && 'CFLAGS="-g -O0"' || 'CFLAGS="-g -O2"') }} cmake . 20 | make VERBOSE=1 21 | sudo make install 22 | -------------------------------------------------------------------------------- /tests/hdrhistogram_015.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_import version 3 with negative skip counters 3 | --FILE-- 4 | 15 | --EXPECTF-- 16 | array(1) { 17 | ["v"]=> 18 | array(4) { 19 | [0]=> 20 | int(-100) 21 | [1]=> 22 | int(5) 23 | [2]=> 24 | int(-20) 25 | [3]=> 26 | int(1) 27 | } 28 | } 29 | array(1) { 30 | ["v"]=> 31 | array(4) { 32 | [0]=> 33 | int(-100) 34 | [1]=> 35 | int(5) 36 | [2]=> 37 | int(-20) 38 | [3]=> 39 | int(1) 40 | } 41 | } 42 | int(121) 43 | int(121) 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | hdrhistogram 2 | /.deps 3 | /Makefile 4 | /*.lo 5 | /*.loT 6 | /*.slo 7 | /*.mk 8 | /*.la 9 | /.libs 10 | /libs.mk 11 | /ac*.m4 12 | /build 13 | /config.h 14 | /config.h.in 15 | /config.nice 16 | /config.sub 17 | /configure 18 | /configure.in 19 | /config.status 20 | /config.cache 21 | /conftest 22 | /conftest.c 23 | /core 24 | /dynlib.m4 25 | /install-sh 26 | /ltmain.sh 27 | /include 28 | /Makefile.fragments 29 | /Makefile.global 30 | /Makefile.objects 31 | /missing 32 | /memory: 33 | /mkinstalldirs 34 | /modules 35 | /scan_makefile_in.awk 36 | /config.guess 37 | /*swo 38 | /*swp 39 | /*swn 40 | tags 41 | /tmp-php.ini 42 | /config.log 43 | /libtool 44 | /*.plg 45 | /*.patch 46 | /*.tgz 47 | /*.ncb 48 | /*.opt 49 | /*.dsw 50 | /autom4te.cache 51 | .svn 52 | /*~ 53 | tests/*.diff 54 | tests/*.out 55 | tests/*.php 56 | tests/*.sh 57 | tests/*.log 58 | tests/*.exp 59 | run-tests.php 60 | .gdb_history 61 | -------------------------------------------------------------------------------- /tests/hdrhistogram_007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Basic Iterator 3 | --FILE-- 4 | 19 | --EXPECT-- 20 | array(4) { 21 | ["value"]=> 22 | int(1) 23 | ["count_at_index"]=> 24 | int(1) 25 | ["count_to_index"]=> 26 | int(1) 27 | ["highest_equivalent_value"]=> 28 | int(1) 29 | } 30 | array(4) { 31 | ["value"]=> 32 | int(2) 33 | ["count_at_index"]=> 34 | int(1) 35 | ["count_to_index"]=> 36 | int(2) 37 | ["highest_equivalent_value"]=> 38 | int(2) 39 | } 40 | array(4) { 41 | ["value"]=> 42 | int(3) 43 | ["count_at_index"]=> 44 | int(10) 45 | ["count_to_index"]=> 46 | int(12) 47 | ["highest_equivalent_value"]=> 48 | int(3) 49 | } 50 | -------------------------------------------------------------------------------- /tests/hdrhistogram_001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Basic Functionality 3 | --FILE-- 4 | 30 | --EXPECTF-- 31 | object(HdrHistogram\Histogram)#%d (0) { 32 | } 33 | Memory: 820%d 34 | Recorded 35 | StdDev: 0.00 36 | Mean: 2 37 | StdDev: 0.82 38 | Min: 1 39 | Max: 3 40 | Recorded 41 | StdDev: 1.17 42 | Max: 4 43 | -------------------------------------------------------------------------------- /php_hdrhistogram.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_HDRHISTOGRAM_H 2 | #define PHP_HDRHISTOGRAM_H 3 | 4 | #include "hdr/hdr_histogram.h" 5 | 6 | extern zend_module_entry hdrhistogram_module_entry; 7 | #define phpext_hdrhistogram_ptr &hdrhistogram_module_entry 8 | #define PHP_HDR_HISTOGRAM_VERSION "0.5.0" 9 | 10 | PHP_MINIT_FUNCTION(hdrhistogram); 11 | PHP_MINFO_FUNCTION(hdrhistogram); 12 | 13 | PHP_FUNCTION(hdr_init); 14 | PHP_FUNCTION(hdr_get_memory_size); 15 | PHP_FUNCTION(hdr_mean); 16 | PHP_FUNCTION(hdr_stddev); 17 | PHP_FUNCTION(hdr_min); 18 | PHP_FUNCTION(hdr_max); 19 | PHP_FUNCTION(hdr_total_count); 20 | PHP_FUNCTION(hdr_record_value); 21 | PHP_FUNCTION(hdr_record_values); 22 | PHP_FUNCTION(hdr_record_corrected_value); 23 | PHP_FUNCTION(hdr_reset); 24 | PHP_FUNCTION(hdr_count_at_value); 25 | PHP_FUNCTION(hdr_value_at_percentile); 26 | PHP_FUNCTION(hdr_add); 27 | PHP_FUNCTION(hdr_merge_into); 28 | 29 | PHP_FUNCTION(hdr_iter_init); 30 | PHP_FUNCTION(hdr_iter_next); 31 | 32 | PHP_FUNCTION(hdr_percentile_iter_init); 33 | PHP_FUNCTION(hdr_percentile_iter_next); 34 | 35 | PHP_FUNCTION(hdr_export); 36 | PHP_FUNCTION(hdr_import); 37 | 38 | PHP_FUNCTION(hdr_base64_encode); 39 | PHP_FUNCTION(hdr_base64_decode); 40 | #endif 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Benjamin Eberlei 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /tests/hdrhistogram_010.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_export/hdr_import 3 | --FILE-- 4 | 37 | --EXPECTF-- 38 | array(2) { 39 | ["htv"]=> 40 | int(1000) 41 | ["v"]=> 42 | array(0) { 43 | } 44 | } 45 | array(2) { 46 | ["htv"]=> 47 | int(1000) 48 | ["v"]=> 49 | array(6) { 50 | [0]=> 51 | int(-1) 52 | [1]=> 53 | int(10) 54 | [2]=> 55 | int(20) 56 | [3]=> 57 | int(25) 58 | [4]=> 59 | int(-6) 60 | [5]=> 61 | int(10) 62 | } 63 | } 64 | SUCCESS 65 | 1: 10 66 | 2: 20 67 | 3: 25 68 | 10: 10 69 | -------------------------------------------------------------------------------- /tests/hdrhistogram_new_error.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: Error handling of Histogram::__construct() 3 | --FILE-- 4 | getMessage(), PHP_EOL; 10 | } catch (Exception $e) { 11 | echo $e->getMessage(), PHP_EOL; 12 | } 13 | 14 | try { 15 | $h = new HdrHistogram\Histogram(2, 3, 1); 16 | var_dump($h); 17 | } catch (Throwable $e) { 18 | echo $e->getMessage(), PHP_EOL; 19 | } catch (Exception $e) { 20 | echo $e->getMessage(), PHP_EOL; 21 | } 22 | 23 | try { 24 | $h = new HdrHistogram\Histogram(1, 100, 50); 25 | var_dump($h); 26 | } catch (Throwable $e) { 27 | echo $e->getMessage(), PHP_EOL; 28 | } catch (Exception $e) { 29 | echo $e->getMessage(), PHP_EOL; 30 | } 31 | 32 | try { 33 | $h = new HdrHistogram\Histogram(1, 100, 0); 34 | var_dump($h); 35 | } catch (Throwable $e) { 36 | echo $e->getMessage(), PHP_EOL; 37 | } catch (Exception $e) { 38 | echo $e->getMessage(), PHP_EOL; 39 | } 40 | ?> 41 | --EXPECTF-- 42 | HdrHistogram\Histogram::__construct(): Argument #1 ($lowestDiscernibleValue) must be greater than or equal to 1 43 | HdrHistogram\Histogram::__construct(): Argument #2 ($highestTrackableValue) must be greater than or equal to twice the value of argument #1 ($lowestDiscernibleValue) 44 | HdrHistogram\Histogram::__construct(): Argument #3 ($significantFigures) must be between 1 and 5 45 | HdrHistogram\Histogram::__construct(): Argument #3 ($significantFigures) must be between 1 and 5 46 | -------------------------------------------------------------------------------- /tests/hdrhistogram_012_php8.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_import Error Handling 3 | --SKIPIF-- 4 | 7 | --FILE-- 8 | 0, "htv" => 0, "sf" => 0, "sk" => 0, "c" => []]); 11 | try { 12 | $imported = hdr_import(); 13 | } catch (ArgumentCountError $e) { 14 | echo $e->getMessage()."\n"; 15 | } 16 | 17 | $imported = hdr_import([]); 18 | $imported = hdr_import(["ltv" => -1]); 19 | $imported = hdr_import(["ltv" => 1, "htv" => -10]); 20 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => -2]); 21 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "c" => null]); 22 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "b" => null]); 23 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "b" => null, "c" => null]); 24 | 25 | ?> 26 | --EXPECTF-- 27 | Warning: hdr_import(): lowest_trackable_value (ltv) must be >= 1. in %s 28 | hdr_import() expects exactly 1 argument, 0 given 29 | 30 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s 31 | 32 | Warning: hdr_import(): lowest_trackable_value (ltv) must be >= 1. in %s 33 | 34 | Warning: hdr_import(): highest_trackable_value (htv) must be >= 1. in %s 35 | 36 | Warning: hdr_import(): significant_figures (sf) must be 1, 2, or 3. in %s 37 | 38 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s 39 | 40 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s 41 | 42 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s 43 | -------------------------------------------------------------------------------- /tests/hdrhistogram_012.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_import Error Handling 3 | --SKIPIF-- 4 | = 80000) die("skip PHP < 8 only"); 6 | ?> 7 | --FILE-- 8 | 0, "htv" => 0, "sf" => 0, "sk" => 0, "c" => []]); 11 | $imported = hdr_import(); 12 | $imported = hdr_import([]); 13 | $imported = hdr_import(["ltv" => -1]); 14 | $imported = hdr_import(["ltv" => 1, "htv" => -10]); 15 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => -2]); 16 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "c" => null]); 17 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "b" => null]); 18 | $imported = hdr_import(["ltv" => 1, "htv" => 10, "sf" => 1, "b" => null, "c" => null]); 19 | 20 | ?> 21 | --EXPECTF-- 22 | Warning: hdr_import(): lowest_trackable_value (ltv) must be >= 1. in %s on line 3 23 | 24 | Warning: hdr_import() expects exactly 1 parameter, 0 given in %s on line 4 25 | 26 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s on line 5 27 | 28 | Warning: hdr_import(): lowest_trackable_value (ltv) must be >= 1. in %s on line 6 29 | 30 | Warning: hdr_import(): highest_trackable_value (htv) must be >= 1. in %s on line 7 31 | 32 | Warning: hdr_import(): significant_figures (sf) must be 1, 2, or 3. in %s on line 8 33 | 34 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s on line 9 35 | 36 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s on line 10 37 | 38 | Warning: hdr_import(): Missing counts (c) or bucket (b) key or not arrays. in %s on line 11 39 | -------------------------------------------------------------------------------- /tests/hdrhistogram_009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Base64 Encode/Decode 3 | --SKIPIF-- 4 | = 80000) die("skip PHP < 8 only"); 6 | ?> 7 | --FILE-- 8 | 35 | --EXPECTF-- 36 | 0: 1 37 | 1: 1 38 | 2: 1 39 | 3: 1 40 | 4: 1 41 | 5: 1 42 | 6: 1 43 | 7: 1 44 | 8: 1 45 | 9: 1 46 | 10: 1 47 | 11: 1 48 | 12: 1 49 | 13: 1 50 | 14: 1 51 | 15: 1 52 | 16: 1 53 | 17: 1 54 | 18: 1 55 | 19: 1 56 | 20: 1 57 | 21: 1 58 | 22: 1 59 | 23: 1 60 | 24: 1 61 | 25: 1 62 | 26: 1 63 | 27: 1 64 | 28: 1 65 | 29: 1 66 | 30: 1 67 | 31: 1 68 | 32: 2 69 | 34: 2 70 | 36: 2 71 | 38: 2 72 | 40: 2 73 | 42: 2 74 | 44: 2 75 | 46: 2 76 | 48: 2 77 | 50: 2 78 | 52: 2 79 | 54: 2 80 | 56: 2 81 | 58: 2 82 | 60: 2 83 | 62: 2 84 | 64: 4 85 | 68: 4 86 | 72: 4 87 | 76: 4 88 | 80: 4 89 | 84: 4 90 | 88: 4 91 | 92: 4 92 | 96: 4 93 | Total: 100 94 | 95 | Warning: hdr_base64_encode() expects parameter 1 to be HdrHistogram\Histogram, string given in %s on line 22 96 | 97 | Warning: hdr_base64_decode(): Cannot decode histogram in %s on line 23 98 | 0 99 | -------------------------------------------------------------------------------- /tests/hdrhistogram_009_php8.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | hdrhistogram: Base64 Encode/Decode 3 | --SKIPIF-- 4 | 8 | --FILE-- 9 | getMessage()."\n"; 34 | } 35 | echo hdr_base64_decode("foo"); 36 | 37 | echo hdr_max(hdr_base64_decode(hdr_base64_encode(hdr_init(1, 100, 1)))); 38 | 39 | ?> 40 | --EXPECTF-- 41 | 0: 1 42 | 1: 1 43 | 2: 1 44 | 3: 1 45 | 4: 1 46 | 5: 1 47 | 6: 1 48 | 7: 1 49 | 8: 1 50 | 9: 1 51 | 10: 1 52 | 11: 1 53 | 12: 1 54 | 13: 1 55 | 14: 1 56 | 15: 1 57 | 16: 1 58 | 17: 1 59 | 18: 1 60 | 19: 1 61 | 20: 1 62 | 21: 1 63 | 22: 1 64 | 23: 1 65 | 24: 1 66 | 25: 1 67 | 26: 1 68 | 27: 1 69 | 28: 1 70 | 29: 1 71 | 30: 1 72 | 31: 1 73 | 32: 2 74 | 34: 2 75 | 36: 2 76 | 38: 2 77 | 40: 2 78 | 42: 2 79 | 44: 2 80 | 46: 2 81 | 48: 2 82 | 50: 2 83 | 52: 2 84 | 54: 2 85 | 56: 2 86 | 58: 2 87 | 60: 2 88 | 62: 2 89 | 64: 4 90 | 68: 4 91 | 72: 4 92 | 76: 4 93 | 80: 4 94 | 84: 4 95 | 88: 4 96 | 92: 4 97 | 96: 4 98 | Total: 100 99 | hdr_base64_encode(): Argument #1 ($hdr) must be of type HdrHistogram\Histogram, string given 100 | 101 | Warning: hdr_base64_decode(): Cannot decode histogram in %s on line %d 102 | 0 103 | -------------------------------------------------------------------------------- /tests/hdrhistogram_013.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | HdrHistogram: hdr_import version 1 3 | --FILE-- 4 | 16 | --EXPECTF-- 17 | array(1) { 18 | ["v"]=> 19 | array(6) { 20 | [0]=> 21 | int(-106) 22 | [1]=> 23 | int(1) 24 | [2]=> 25 | int(-183) 26 | [3]=> 27 | int(1) 28 | [4]=> 29 | int(-444) 30 | [5]=> 31 | int(1) 32 | } 33 | } 34 | array(1) { 35 | ["v"]=> 36 | array(6) { 37 | [0]=> 38 | int(-106) 39 | [1]=> 40 | int(1) 41 | [2]=> 42 | int(-183) 43 | [3]=> 44 | int(1) 45 | [4]=> 46 | int(-444) 47 | [5]=> 48 | int(1) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_WITH(hdrhistogram, 2 | [if to enable the "hdrhistogram" extension], 3 | [ --with-hdrhistogram[=DIR] Enable "hdrhistogram" extension support]) 4 | 5 | if test "$PHP_HDRHISTOGRAM" != "no"; then 6 | PHP_ARG_WITH(hdrhistogram_static, 7 | [whether libhdr_histogram should be linked statically], 8 | [ --with-hdrhistogram-static 9 | Enable static linking of libhdr_histogram], no, no) 10 | 11 | if test "$PHP_HDRHISTOGRAM_STATIC" = "yes"; then 12 | LIBNAME=hdr_histogram_static 13 | else 14 | LIBNAME=hdr_histogram 15 | fi 16 | 17 | AC_PATH_PROG(PKG_CONFIG, pkg-config, no) 18 | 19 | if test "$PHP_HDRHISTOGRAM" = "yes" -a -x "$PKG_CONFIG" && $PKG_CONFIG --exists $LIBNAME; then 20 | 21 | AC_MSG_CHECKING([for hdrhistogram from pkg-config]) 22 | LIBHDR_CFLAGS=`$PKG_CONFIG $LIBNAME --cflags` 23 | LIBHDR_LIBDIR=`$PKG_CONFIG $LIBNAME --libs` 24 | LIBHDR_VERSON=`$PKG_CONFIG $LIBNAME --modversion` 25 | AC_MSG_RESULT(found $LIBHDR_VERSON) 26 | PHP_EVAL_LIBLINE($LIBHDR_LIBDIR, HDRHISTOGRAM_SHARED_LIBADD) 27 | PHP_EVAL_INCLINE($LIBHDR_CFLAGS) 28 | else 29 | SEARCH_PATH="/usr/local /usr" 30 | SEARCH_FOR="/include/hdr/hdr_histogram.h" # you most likely want to change this 31 | 32 | if test -r $PHP_HDRHISTOGRAM/$SEARCH_FOR; then 33 | HDRHISTOGRAM_PATH=$PHP_HDRHISTOGRAM 34 | else 35 | AC_MSG_CHECKING([for hdrhistogram files in default path]) 36 | for i in $SEARCH_PATH ; do 37 | if test -r $i/$SEARCH_FOR; then 38 | HDRHISTOGRAM_PATH=$i 39 | AC_MSG_RESULT(found in $i) 40 | fi 41 | done 42 | fi 43 | 44 | if test -z "$HDRHISTOGRAM_PATH"; then 45 | AC_MSG_RESULT([not found]) 46 | AC_MSG_ERROR([Please reinstall the hdrhistogram library]) 47 | fi 48 | 49 | PHP_ADD_INCLUDE($HDRHISTOGRAM_PATH/include) 50 | 51 | AC_SEARCH_LIBS(hdr_init, $LIBNAME, 52 | [ 53 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $HDRHISTOGRAM_PATH/$PHP_LIBDIR, HDRHISTOGRAM_SHARED_LIBADD) 54 | ],[ 55 | AC_MSG_ERROR([wrong hdrhistogram lib version or lib not found]) 56 | ],[ 57 | -L$HDRHISTOGRAM_PATH/$PHP_LIBDIR -lm 58 | ] 59 | ) 60 | fi 61 | 62 | old_CPPFLAGS=$CPPFLAGS 63 | CPPFLAGS="$CPPFLAGS $INCLUDES" 64 | AC_CHECK_HEADERS([hdr/hdr_histogram_version.h]) 65 | CPPFLAGS=$old_CPPFLAGS 66 | 67 | old_CPPFLAGS=$CPPFLAGS 68 | CPPFLAGS="$CPPFLAGS $INCLUDES" 69 | AC_CHECK_MEMBER([struct hdr_histogram.lowest_discernible_value], [ 70 | AC_DEFINE(HAVE_HDR_HISTOGRAM_LOWEST_DISCERNIBLE_VALUE, 1, [ ]) 71 | ], [], [#include "hdr/hdr_histogram.h"]) 72 | CPPFLAGS=$old_CPPFLAGS 73 | 74 | PHP_SUBST(HDRHISTOGRAM_SHARED_LIBADD) 75 | 76 | PHP_NEW_EXTENSION(hdrhistogram, hdrhistogram.c, $ext_shared) 77 | fi 78 | -------------------------------------------------------------------------------- /hdrhistogram.stub.php: -------------------------------------------------------------------------------- 1 | 18 | --EXPECT-- 19 | 0-2.5%: 110 20 | 2.5-5%: 109 21 | 5-7.5%: 108 22 | 7.5-10%: 106 23 | 10-12.5%: 105 24 | 12.5-15%: 103 25 | 15-17.5%: 102 26 | 17.5-20%: 100 27 | 20-22.5%: 99 28 | 22.5-25%: 97 29 | 25-27.5%: 96 30 | 27.5-30%: 94 31 | 30-32.5%: 93 32 | 32.5-35%: 91 33 | 35-37.5%: 89 34 | 37.5-40%: 88 35 | 40-42.5%: 86 36 | 42.5-45%: 84 37 | 45-47.5%: 82 38 | 47.5-50%: 80 39 | 50-51.25%: 157 40 | 51.25-52.5%: 157 41 | 52.5-53.75%: 153 42 | 53.75-55%: 153 43 | 55-56.25%: 149 44 | 56.25-57.5%: 149 45 | 57.5-58.75%: 145 46 | 58.75-60%: 141 47 | 60-61.25%: 141 48 | 61.25-62.5%: 137 49 | 62.5-63.75%: 137 50 | 63.75-65%: 133 51 | 65-66.25%: 133 52 | 66.25-67.5%: 129 53 | 67.5-68.75%: 129 54 | 68.75-70%: 125 55 | 70-71.25%: 121 56 | 71.25-72.5%: 121 57 | 72.5-73.75%: 117 58 | 73.75-75%: 113 59 | 75-75.625%: 113 60 | 75.625-76.25%: 109 61 | 76.25-76.875%: 109 62 | 76.875-77.5%: 109 63 | 77.5-78.125%: 105 64 | 78.125-78.75%: 105 65 | 78.75-79.375%: 105 66 | 79.375-80%: 101 67 | 80-80.625%: 101 68 | 80.625-81.25%: 101 69 | 81.25-81.875%: 97 70 | 81.875-82.5%: 97 71 | 82.5-83.125%: 182 72 | 83.125-83.75%: 182 73 | 83.75-84.375%: 182 74 | 84.375-85%: 182 75 | 85-85.625%: 182 76 | 85.625-86.25%: 166 77 | 86.25-86.875%: 166 78 | 86.875-87.5%: 166 79 | 87.5-87.8125%: 166 80 | 87.8125-88.125%: 166 81 | 88.125-88.4375%: 150 82 | 88.4375-88.75%: 150 83 | 88.75-89.0625%: 150 84 | 89.0625-89.375%: 150 85 | 89.375-89.6875%: 150 86 | 89.6875-90%: 150 87 | 90-90.3125%: 150 88 | 90.3125-90.625%: 150 89 | 90.625-90.9375%: 134 90 | 90.9375-91.25%: 134 91 | 91.25-91.5625%: 134 92 | 91.5625-91.875%: 134 93 | 91.875-92.1875%: 134 94 | 92.1875-92.5%: 134 95 | 92.5-92.8125%: 134 96 | 92.8125-93.125%: 118 97 | 93.125-93.4375%: 118 98 | 93.4375-93.75%: 118 99 | 93.75-93.90625%: 118 100 | 93.90625-94.0625%: 118 101 | 94.0625-94.21875%: 118 102 | 94.21875-94.375%: 118 103 | 94.375-94.53125%: 118 104 | 94.53125-94.6875%: 118 105 | 94.6875-94.84375%: 102 106 | 94.84375-95%: 102 107 | 95-95.15625%: 102 108 | 95.15625-95.3125%: 102 109 | 95.3125-95.46875%: 102 110 | 95.46875-95.625%: 102 111 | 95.625-95.78125%: 102 112 | 95.78125-95.9375%: 102 113 | 95.9375-96.09375%: 102 114 | 96.09375-96.25%: 102 115 | 96.25-96.40625%: 102 116 | 96.40625-96.5625%: 86 117 | 96.5625-96.71875%: 86 118 | 96.71875-96.875%: 86 119 | 96.875-96.953125%: 86 120 | 96.953125-97.03125%: 86 121 | 97.03125-97.109375%: 86 122 | 97.109375-97.1875%: 86 123 | 97.1875-97.265625%: 86 124 | 97.265625-97.34375%: 86 125 | 97.34375-97.421875%: 86 126 | 97.421875-97.5%: 86 127 | 97.5-97.578125%: 86 128 | 97.578125-97.65625%: 86 129 | 97.65625-97.734375%: 86 130 | 97.734375-97.8125%: 86 131 | 97.8125-97.890625%: 70 132 | 97.890625-97.96875%: 70 133 | 97.96875-98.046875%: 70 134 | 98.046875-98.125%: 70 135 | 98.125-98.203125%: 70 136 | 98.203125-98.28125%: 70 137 | 98.28125-98.359375%: 70 138 | 98.359375-98.4375%: 70 139 | 98.4375-98.4765625%: 70 140 | 98.4765625-98.515625%: 70 141 | 98.515625-98.5546875%: 70 142 | 98.5546875-98.59375%: 70 143 | 98.59375-98.6328125%: 70 144 | 98.6328125-98.671875%: 70 145 | 98.671875-98.7109375%: 70 146 | 98.7109375-98.75%: 70 147 | 98.75-98.7890625%: 70 148 | 98.7890625-98.828125%: 70 149 | 98.828125-98.8671875%: 70 150 | 98.8671875-98.90625%: 70 151 | 98.90625-98.9453125%: 70 152 | 98.9453125-98.984375%: 54 153 | 98.984375-99.0234375%: 54 154 | 99.0234375-99.0625%: 54 155 | 99.0625-99.1015625%: 54 156 | 99.1015625-99.140625%: 54 157 | 99.140625-99.1796875%: 54 158 | 99.1796875-99.21875%: 54 159 | 99.21875-99.23828125%: 54 160 | 99.23828125-99.2578125%: 54 161 | 99.2578125-99.27734375%: 54 162 | 99.27734375-99.296875%: 54 163 | 99.296875-99.31640625%: 54 164 | 99.31640625-99.3359375%: 54 165 | 99.3359375-99.35546875%: 54 166 | 99.35546875-99.375%: 54 167 | 99.375-99.39453125%: 54 168 | 99.39453125-99.4140625%: 54 169 | 99.4140625-99.43359375%: 54 170 | 99.43359375-99.453125%: 54 171 | 99.453125-99.47265625%: 54 172 | 99.47265625-99.4921875%: 54 173 | 99.4921875-99.51171875%: 54 174 | 99.51171875-99.53125%: 54 175 | 99.53125-99.55078125%: 54 176 | 99.55078125-99.5703125%: 54 177 | 99.5703125-99.58984375%: 54 178 | 99.58984375-99.609375%: 54 179 | 99.609375-99.619140625%: 54 180 | 99.619140625-99.62890625%: 54 181 | 99.62890625-99.638671875%: 54 182 | 99.638671875-99.6484375%: 54 183 | 99.6484375-99.658203125%: 54 184 | 99.658203125-99.66796875%: 54 185 | 99.66796875-99.677734375%: 54 186 | 99.677734375-99.6875%: 54 187 | 99.6875-99.697265625%: 54 188 | 99.697265625-99.70703125%: 54 189 | 99.70703125-99.716796875%: 54 190 | 99.716796875-99.7265625%: 54 191 | 99.7265625-99.736328125%: 54 192 | 99.736328125-99.74609375%: 54 193 | 99.74609375-99.755859375%: 54 194 | 99.755859375-99.765625%: 54 195 | 99.765625-99.775390625%: 54 196 | 99.775390625-99.78515625%: 54 197 | 99.78515625-99.794921875%: 54 198 | 99.794921875-99.8046875%: 54 199 | 99.8046875-99.8095703125%: 54 200 | 99.8095703125-99.814453125%: 54 201 | 99.814453125-99.8193359375%: 54 202 | 99.8193359375-99.82421875%: 11 203 | 100-99.82421875%: 11 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hdrhistogram-php 2 | 3 | A PHP extension wrapping the [HdrHistogram C API](https://github.com/HdrHistogram/HdrHistogram_c). 4 | 5 | License: New-BSD 2 Clause 6 | 7 | ## Description 8 | 9 | HdrHistogram: A High Dynamic Range Histogram. 10 | 11 | A Histogram that supports recording and analyzing sampled data value counts across a configurable integer value range with configurable value precision within the range. Value precision is expressed as the number of significant digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolution at any given level. 12 | 13 | [Website/Documentation](http://hdrhistogram.org) 14 | 15 | ## Installation 16 | 17 | This extension depends on HdrHistogram C API (version 0.9.8 or higher), you can install it easily: 18 | 19 | $ git clone git@github.com:HdrHistogram/HdrHistogram_c 20 | $ cd HdrHistogram_c 21 | $ cmake . 22 | $ make 23 | $ sudo make install 24 | 25 | Then you can compile this extension: 26 | 27 | $ phpize 28 | $ ./configure 29 | $ make 30 | $ sudo make install 31 | 32 | You can then load the extension in your PHP.ini: 33 | 34 | extension=hdrhistogram.so 35 | 36 | ## Example 37 | 38 | The API is very similar to the C code: 39 | 40 | ```php 41 | > $GITHUB_PATH 143 | 144 | - name: Show PHP Information 145 | run: | 146 | set -ex 147 | 148 | which php 149 | php -v 150 | if ! php -v |grep -q "${{ steps.install-php.outputs.version }}"; then 151 | echo "ERROR: Wrong PHP version" 152 | exit 1 153 | fi 154 | php -i 155 | 156 | - run: phpize 157 | 158 | - name: configure 159 | timeout-minutes: 1 160 | run: | 161 | ./configure \ 162 | ${{ matrix.static && '--with-hdrhistogram-static' || '' }} \ 163 | ${{ matrix.debug == 'sanitize' && 'CFLAGS="-g -fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address" CC=clang-16 CXX=clang++-16' || 'CFLAGS="-g"' }} 164 | 165 | - name: make 166 | timeout-minutes: 1 167 | run: | 168 | set -ex 169 | 170 | make -j$(getconf _NPROCESSORS_ONLN) 171 | 172 | - name: "Show hdrhistogram Version" 173 | id: hdrhistogram-version 174 | run: | 175 | set -ex 176 | 177 | echo "version=$(php -dextension=.libs/hdrhistogram.so -r "echo phpversion('hdrhistogram');")" >> $GITHUB_OUTPUT 178 | 179 | php -dextension=.libs/hdrhistogram.so -i 180 | 181 | - name: run-tests.php for hdrhistogram ${{ steps.hdrhistogram-version.outputs.version }} 182 | timeout-minutes: 5 183 | run: | 184 | set -ex 185 | 186 | export TEST_PHP_EXECUTABLE="$(pwd)/php/target/bin/php" 187 | export TEST_PHP_CGI_EXECUTABLE="$(pwd)/php/target/bin/php-cgi" 188 | noProgress="$(php run-tests.php -h |grep -o -m1 -- '--no-progress' || true)" 189 | if php run-tests.php -h |grep -q -- '--show-slow'; then 190 | showSlow="--show-slow 500" 191 | else 192 | showSlow="" 193 | fi 194 | asan="${{ matrix.debug == 'sanitize' && '--asan' || '' }}" 195 | 196 | php run-tests.php $noProgress $showSlow $asan --show-diff -d extension="$(pwd)/.libs/hdrhistogram.so" -q 197 | env: 198 | REPORT_EXIT_STATUS: 1 199 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | hdr_histogram 4 | pecl.php.net 5 | A PHP extension wrapper for the C hdrhistogram API 6 | HdrHistogram: A High Dynamic Range Histogram. A Histogram that supports recording and analyzing sampled data value counts across a configurable integer value range with configurable value precision within the range. Value precision is expressed as the number of significant digits in the value recording, and provides control over value quantization behavior across the value range and the subsequent value resolution at any given level. 7 | 8 | Benjamin Eberlei 9 | beberlei 10 | beberlei@php.net 11 | yes 12 | 13 | 2024-04-22 14 | 15 | 0.5.0 16 | 0.5.0 17 | 18 | 19 | beta 20 | beta 21 | 22 | New BSD 23 | 24 | - Migrate from resource to object of new HdrHistogram\Histogram class 25 | - add HdrHistogram\Iterator and HdrHistogram\Iterator\Percentile classes 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 7.0.0 67 | 68 | 69 | 1.10.0 70 | 71 | 72 | 73 | hdrhistogram 74 | 75 | 76 | 77 | 2015-12-31 78 | 79 | 0.1.0 80 | 0.1.0 81 | 82 | 83 | beta 84 | beta 85 | 86 | New BSD 87 | 88 | - Initial release 89 | 90 | 91 | 92 | 2016-07-17 93 | 94 | 0.2.0 95 | 0.2.0 96 | 97 | 98 | beta 99 | beta 100 | 101 | New BSD 102 | 103 | - Update APIs 104 | - some fixes 105 | 106 | 107 | 108 | 2016-08-17 109 | 110 | 0.3.0 111 | 0.3.0 112 | 113 | 114 | beta 115 | beta 116 | 117 | New BSD 118 | 119 | - Improve serialized array size by introducing skip counter 120 | - Validate inputs into hdr_import are in their range 121 | 122 | 123 | 124 | 2018-01-01 125 | 126 | 0.4.0 127 | 0.4.0 128 | 129 | 130 | beta 131 | beta 132 | 133 | New BSD 134 | 135 | - Introduce new hdr_import/hdr_export serialization format that saves a lot of space and improves performance. 136 | - Remove PHP 5 support 137 | 138 | 139 | 140 | 2018-01-01 141 | 142 | 0.4.1 143 | 0.4.1 144 | 145 | 146 | beta 147 | beta 148 | 149 | New BSD 150 | 151 | - Improve validation in hdr_import 152 | 153 | 154 | 155 | 2018-01-22 156 | 157 | 0.4.2 158 | 0.4.2 159 | 160 | 161 | beta 162 | beta 163 | 164 | New BSD 165 | 166 | - Improve serialized array size by introducing negative skip counters 167 | 168 | 169 | 170 | 2021-08-25 171 | 172 | 0.4.3 173 | 0.4.2 174 | 175 | 176 | beta 177 | beta 178 | 179 | New BSD 180 | 181 | - PHP 8 support 182 | - Update to hdr->lowest_discernible_value instead of lowest_trackable_value in latest HdrHistogram_C 183 | 184 | 185 | 186 | 2021-09-26 187 | 188 | 0.4.4 189 | 0.4.2 190 | 191 | 192 | beta 193 | beta 194 | 195 | New BSD 196 | 197 | - Revert lowest_discernible_value change as that is not yet released as stsable in HdrHistogram_C 198 | 199 | 200 | 201 | 202 | 205 | 206 | -------------------------------------------------------------------------------- /hdrhistogram_legacy_arginfo.h: -------------------------------------------------------------------------------- 1 | /* This is a generated file, edit the .stub.php file instead. 2 | * Stub hash: 4e91058eaa9a3defd0e052aa081bb9c4d8ea7b12 */ 3 | 4 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_init, 0, 0, 3) 5 | ZEND_ARG_INFO(0, lowest_trackable_value) 6 | ZEND_ARG_INFO(0, highest_trackable_value) 7 | ZEND_ARG_INFO(0, significant_figures) 8 | ZEND_END_ARG_INFO() 9 | 10 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_get_memory_size, 0, 0, 1) 11 | ZEND_ARG_INFO(0, hdr) 12 | ZEND_END_ARG_INFO() 13 | 14 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_record_value, 0, 0, 2) 15 | ZEND_ARG_INFO(0, hdr) 16 | ZEND_ARG_INFO(0, value) 17 | ZEND_END_ARG_INFO() 18 | 19 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_record_values, 0, 0, 3) 20 | ZEND_ARG_INFO(0, hdr) 21 | ZEND_ARG_INFO(0, value) 22 | ZEND_ARG_INFO(0, count) 23 | ZEND_END_ARG_INFO() 24 | 25 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_record_corrected_value, 0, 0, 3) 26 | ZEND_ARG_INFO(0, hdr) 27 | ZEND_ARG_INFO(0, value) 28 | ZEND_ARG_INFO(0, expected_interval) 29 | ZEND_END_ARG_INFO() 30 | 31 | #define arginfo_hdr_mean arginfo_hdr_get_memory_size 32 | 33 | #define arginfo_hdr_stddev arginfo_hdr_get_memory_size 34 | 35 | #define arginfo_hdr_min arginfo_hdr_get_memory_size 36 | 37 | #define arginfo_hdr_max arginfo_hdr_get_memory_size 38 | 39 | #define arginfo_hdr_total_count arginfo_hdr_get_memory_size 40 | 41 | #define arginfo_hdr_reset arginfo_hdr_get_memory_size 42 | 43 | #define arginfo_hdr_count_at_value arginfo_hdr_record_value 44 | 45 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_value_at_percentile, 0, 0, 2) 46 | ZEND_ARG_INFO(0, hdr) 47 | ZEND_ARG_INFO(0, percentile) 48 | ZEND_END_ARG_INFO() 49 | 50 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_add, 0, 0, 2) 51 | ZEND_ARG_INFO(0, hdr1) 52 | ZEND_ARG_INFO(0, hdr2) 53 | ZEND_END_ARG_INFO() 54 | 55 | #define arginfo_hdr_merge_into arginfo_hdr_add 56 | 57 | #define arginfo_hdr_iter_init arginfo_hdr_get_memory_size 58 | 59 | #define arginfo_hdr_iter_next arginfo_hdr_get_memory_size 60 | 61 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_percentile_iter_init, 0, 0, 2) 62 | ZEND_ARG_INFO(0, hdr) 63 | ZEND_ARG_INFO(0, ticks_per_half_distance) 64 | ZEND_END_ARG_INFO() 65 | 66 | #define arginfo_hdr_percentile_iter_next arginfo_hdr_get_memory_size 67 | 68 | #define arginfo_hdr_export arginfo_hdr_get_memory_size 69 | 70 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_import, 0, 0, 1) 71 | ZEND_ARG_INFO(0, import) 72 | ZEND_END_ARG_INFO() 73 | 74 | #define arginfo_hdr_base64_encode arginfo_hdr_get_memory_size 75 | 76 | ZEND_BEGIN_ARG_INFO_EX(arginfo_hdr_base64_decode, 0, 0, 1) 77 | ZEND_ARG_INFO(0, data) 78 | ZEND_END_ARG_INFO() 79 | 80 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Histogram___construct, 0, 0, 3) 81 | ZEND_ARG_INFO(0, lowestDiscernibleValue) 82 | ZEND_ARG_INFO(0, highestTrackableValue) 83 | ZEND_ARG_INFO(0, significantFigures) 84 | ZEND_END_ARG_INFO() 85 | 86 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Iterator___construct, 0, 0, 1) 87 | ZEND_ARG_INFO(0, histogram) 88 | ZEND_END_ARG_INFO() 89 | 90 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Iterator_Percentile___construct, 0, 0, 2) 91 | ZEND_ARG_INFO(0, histogram) 92 | ZEND_ARG_INFO(0, ticksPerHalfDistance) 93 | ZEND_END_ARG_INFO() 94 | 95 | 96 | ZEND_FUNCTION(hdr_init); 97 | ZEND_FUNCTION(hdr_get_memory_size); 98 | ZEND_FUNCTION(hdr_record_value); 99 | ZEND_FUNCTION(hdr_record_values); 100 | ZEND_FUNCTION(hdr_record_corrected_value); 101 | ZEND_FUNCTION(hdr_mean); 102 | ZEND_FUNCTION(hdr_stddev); 103 | ZEND_FUNCTION(hdr_min); 104 | ZEND_FUNCTION(hdr_max); 105 | ZEND_FUNCTION(hdr_total_count); 106 | ZEND_FUNCTION(hdr_reset); 107 | ZEND_FUNCTION(hdr_count_at_value); 108 | ZEND_FUNCTION(hdr_value_at_percentile); 109 | ZEND_FUNCTION(hdr_add); 110 | ZEND_FUNCTION(hdr_merge_into); 111 | ZEND_FUNCTION(hdr_iter_init); 112 | ZEND_FUNCTION(hdr_iter_next); 113 | ZEND_FUNCTION(hdr_percentile_iter_init); 114 | ZEND_FUNCTION(hdr_percentile_iter_next); 115 | ZEND_FUNCTION(hdr_export); 116 | ZEND_FUNCTION(hdr_import); 117 | ZEND_FUNCTION(hdr_base64_encode); 118 | ZEND_FUNCTION(hdr_base64_decode); 119 | ZEND_METHOD(HdrHistogram_Histogram, __construct); 120 | ZEND_METHOD(HdrHistogram_Iterator, __construct); 121 | ZEND_METHOD(HdrHistogram_Iterator_Percentile, __construct); 122 | 123 | 124 | static const zend_function_entry ext_functions[] = { 125 | ZEND_FE(hdr_init, arginfo_hdr_init) 126 | ZEND_FE(hdr_get_memory_size, arginfo_hdr_get_memory_size) 127 | ZEND_FE(hdr_record_value, arginfo_hdr_record_value) 128 | ZEND_FE(hdr_record_values, arginfo_hdr_record_values) 129 | ZEND_FE(hdr_record_corrected_value, arginfo_hdr_record_corrected_value) 130 | ZEND_FE(hdr_mean, arginfo_hdr_mean) 131 | ZEND_FE(hdr_stddev, arginfo_hdr_stddev) 132 | ZEND_FE(hdr_min, arginfo_hdr_min) 133 | ZEND_FE(hdr_max, arginfo_hdr_max) 134 | ZEND_FE(hdr_total_count, arginfo_hdr_total_count) 135 | ZEND_FE(hdr_reset, arginfo_hdr_reset) 136 | ZEND_FE(hdr_count_at_value, arginfo_hdr_count_at_value) 137 | ZEND_FE(hdr_value_at_percentile, arginfo_hdr_value_at_percentile) 138 | ZEND_FE(hdr_add, arginfo_hdr_add) 139 | ZEND_FE(hdr_merge_into, arginfo_hdr_merge_into) 140 | ZEND_FE(hdr_iter_init, arginfo_hdr_iter_init) 141 | ZEND_FE(hdr_iter_next, arginfo_hdr_iter_next) 142 | ZEND_FE(hdr_percentile_iter_init, arginfo_hdr_percentile_iter_init) 143 | ZEND_FE(hdr_percentile_iter_next, arginfo_hdr_percentile_iter_next) 144 | ZEND_FE(hdr_export, arginfo_hdr_export) 145 | ZEND_FE(hdr_import, arginfo_hdr_import) 146 | ZEND_FE(hdr_base64_encode, arginfo_hdr_base64_encode) 147 | ZEND_FE(hdr_base64_decode, arginfo_hdr_base64_decode) 148 | ZEND_FE_END 149 | }; 150 | 151 | 152 | static const zend_function_entry class_HdrHistogram_Histogram_methods[] = { 153 | ZEND_ME(HdrHistogram_Histogram, __construct, arginfo_class_HdrHistogram_Histogram___construct, ZEND_ACC_PUBLIC) 154 | ZEND_FE_END 155 | }; 156 | 157 | 158 | static const zend_function_entry class_HdrHistogram_Iterator_methods[] = { 159 | ZEND_ME(HdrHistogram_Iterator, __construct, arginfo_class_HdrHistogram_Iterator___construct, ZEND_ACC_PUBLIC) 160 | ZEND_FE_END 161 | }; 162 | 163 | 164 | static const zend_function_entry class_HdrHistogram_Iterator_Percentile_methods[] = { 165 | ZEND_ME(HdrHistogram_Iterator_Percentile, __construct, arginfo_class_HdrHistogram_Iterator_Percentile___construct, ZEND_ACC_PUBLIC) 166 | ZEND_FE_END 167 | }; 168 | 169 | static zend_class_entry *register_class_HdrHistogram_Histogram(void) 170 | { 171 | zend_class_entry ce, *class_entry; 172 | 173 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram", "Histogram", class_HdrHistogram_Histogram_methods); 174 | class_entry = zend_register_internal_class_ex(&ce, NULL); 175 | #if (PHP_VERSION_ID >= 80100) 176 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 177 | #elif (PHP_VERSION_ID >= 80000) 178 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 179 | #elif (PHP_VERSION_ID >= 70000) 180 | class_entry->ce_flags |= ZEND_ACC_FINAL; 181 | #endif 182 | 183 | return class_entry; 184 | } 185 | 186 | static zend_class_entry *register_class_HdrHistogram_Iterator(void) 187 | { 188 | zend_class_entry ce, *class_entry; 189 | 190 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram", "Iterator", class_HdrHistogram_Iterator_methods); 191 | class_entry = zend_register_internal_class_ex(&ce, NULL); 192 | #if (PHP_VERSION_ID >= 80100) 193 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 194 | #elif (PHP_VERSION_ID >= 80000) 195 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 196 | #elif (PHP_VERSION_ID >= 70000) 197 | class_entry->ce_flags |= ZEND_ACC_FINAL; 198 | #endif 199 | 200 | return class_entry; 201 | } 202 | 203 | static zend_class_entry *register_class_HdrHistogram_Iterator_Percentile(void) 204 | { 205 | zend_class_entry ce, *class_entry; 206 | 207 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram\\Iterator", "Percentile", class_HdrHistogram_Iterator_Percentile_methods); 208 | class_entry = zend_register_internal_class_ex(&ce, NULL); 209 | #if (PHP_VERSION_ID >= 80100) 210 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 211 | #elif (PHP_VERSION_ID >= 80000) 212 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 213 | #elif (PHP_VERSION_ID >= 70000) 214 | class_entry->ce_flags |= ZEND_ACC_FINAL; 215 | #endif 216 | 217 | return class_entry; 218 | } 219 | -------------------------------------------------------------------------------- /.github/actions/install-php/action.yml: -------------------------------------------------------------------------------- 1 | name: Install PHP 2 | inputs: 3 | version: 4 | required: true 5 | type: 6 | required: true 7 | zts: 8 | required: true 9 | outputs: 10 | version: 11 | value: ${{ steps.determine-php-version.outputs.version }} 12 | runs: 13 | using: composite 14 | steps: 15 | - name: apt update 16 | shell: bash 17 | run: sudo apt-get update 18 | 19 | - name: Install runtime libraries 20 | shell: bash 21 | run: | 22 | sudo apt-get install -y \ 23 | '?and(?name(^libicu[0-9]+$),?source-package(icu))' \ 24 | libmcrypt4 \ 25 | libmemcached11 \ 26 | librabbitmq4 \ 27 | librdkafka1 \ 28 | '?name(^libzip[0-9]+$)' 29 | 30 | - name: Determine PHP version 31 | id: determine-php-version 32 | shell: bash 33 | run: | 34 | set -ex 35 | if ! command -v jq > /dev/null; then 36 | sudo apt-get install -y jq 37 | fi 38 | if [[ "${{ inputs.version }}" = *-dev ]]; then 39 | curl -fsSL "https://www.php.net/release-candidates.php?format=json" -o version.json 40 | version="$(cat version.json |jq -r --arg version "${{ inputs.version }}" '.releases[] |select(.version |startswith($version |sub("-dev"; "."))).version')" 41 | archive="$(cat version.json |jq -r --arg version "${{ inputs.version }}" '.releases[] |select(.version |startswith($version |sub("-dev"; "."))).files.gz.path')" 42 | else 43 | curl -fsSL "https://www.php.net/releases/index.php?json&max=1&version=${{ inputs.version }}" -o version.json 44 | version="$(cat version.json |jq -r 'keys[0]')" 45 | archive="$(cat version.json |jq -r '.[] .source[] |select(.filename |endswith(".gz")) |"https://www.php.net/distributions/" + .filename')" 46 | fi 47 | 48 | printf "version=%s\n" "$version" >> $GITHUB_OUTPUT 49 | printf "archive=%s\n" "$archive" >> $GITHUB_OUTPUT 50 | 51 | - name: Determine Ubuntu version 52 | id: determine-ubuntu-version 53 | shell: bash 54 | run: | 55 | set -ex 56 | # No quotes around the subshell, because we want word-splitting. 57 | printf "version=%s-%s\n" $(lsb_release --short --release --id 2>/dev/null) >> $GITHUB_OUTPUT 58 | 59 | - name: Download OpenSSL 1.1 packages 60 | shell: bash 61 | run: | 62 | if dpkg --compare-versions "${{ steps.determine-php-version.outputs.version }}" lt 8.1.0; then 63 | curl -fL --max-time 30 -O http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb 64 | curl -fL --max-time 30 -O http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.24_amd64.deb 65 | curl -fL --max-time 30 -O https://ports.ubuntu.com/ubuntu-ports/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.24_arm64.deb 66 | curl -fL --max-time 30 -O https://ports.ubuntu.com/ubuntu-ports/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.24_arm64.deb 67 | 68 | # Indentation is intentionally off due to the heredoc syntax. 69 | sha256sum --check --ignore-missing << "EOF" 70 | 33e1678adfea3847e0bbcbb26a643fd0dad38874c9e00def0d4d61dbc589083c *libssl-dev_1.1.1f-1ubuntu2.24_amd64.deb 71 | a664d282a0b19fb687c1b9f5a06abcf879bc5643c6e8be435f13c187d13a5b6a *libssl-dev_1.1.1f-1ubuntu2.24_arm64.deb 72 | 7cf39d70a639017d1dd7c8d36daa2258063608688e449fddf40ffdd46f992a78 *libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb 73 | dded4572af8b0a9e0310909f211a519cc6409fda31ea81132a77e268b0ec0f2f *libssl1.1_1.1.1f-1ubuntu2.24_arm64.deb 74 | EOF 75 | 76 | case "${{ runner.arch}}" in 77 | "X64") 78 | sudo apt-get install -y ./libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb 79 | ;; 80 | "ARM64") 81 | sudo apt-get install -y ./libssl1.1_1.1.1f-1ubuntu2.24_arm64.deb 82 | ;; 83 | esac 84 | fi 85 | 86 | - name: Cache PHP 87 | id: cache-php 88 | uses: actions/cache@v4 89 | with: 90 | path: php/target/ 91 | key: php-${{ inputs.type == 'sanitize' && 'sanitizers' || (inputs.type == 'debug' && 'debug' || 'release') }}-${{ inputs.zts == 'zts' && 'zts' || 'nts' }}-${{ runner.arch }}-${{ steps.determine-php-version.outputs.version }}-${{ steps.determine-ubuntu-version.outputs.version }}-${{ hashFiles('**/.github/actions/install-php/**/*') }} 92 | 93 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 94 | shell: bash 95 | run: mkdir php/ 96 | 97 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 98 | shell: bash 99 | run: sudo apt-get remove --purge --autoremove 'php*-*' 'libmemcached*' 100 | 101 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 102 | shell: bash 103 | run: curl -fsSL "${{ steps.determine-php-version.outputs.archive }}" |tar xz -C php --strip-components=1 104 | 105 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 106 | shell: bash 107 | run: | 108 | sudo apt-get install -y \ 109 | libcurl4-openssl-dev \ 110 | libmcrypt-dev \ 111 | libmemcached-dev \ 112 | libicu-dev \ 113 | libonig-dev \ 114 | librabbitmq-dev \ 115 | librdkafka-dev \ 116 | libsqlite3-dev \ 117 | libssl-dev \ 118 | libxml2-dev \ 119 | libzip-dev \ 120 | zlib1g-dev 121 | 122 | if dpkg --compare-versions "${{ steps.determine-php-version.outputs.version }}" lt 8.1.0; then 123 | case "${{ runner.arch}}" in 124 | "X64") 125 | sudo apt-get install -y --allow-downgrades ./libssl-dev_1.1.1f-1ubuntu2.24_amd64.deb 126 | ;; 127 | "ARM64") 128 | sudo apt-get install -y --allow-downgrades ./libssl-dev_1.1.1f-1ubuntu2.24_arm64.deb 129 | ;; 130 | esac 131 | fi 132 | 133 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 134 | shell: bash 135 | working-directory: ./php/ 136 | run: | 137 | if dpkg --compare-versions "${{ steps.determine-php-version.outputs.version }}" ge 8.0.0; then 138 | zts='--enable-zts' 139 | else 140 | zts='--enable-maintainer-zts' 141 | fi 142 | if dpkg --compare-versions "${{ steps.determine-php-version.outputs.version }}" ge 7.4.0; then 143 | zip='--with-zip' 144 | else 145 | zip='--enable-zip' 146 | fi 147 | 148 | ./configure \ 149 | --enable-option-checking=fatal \ 150 | --prefix=$(pwd)/target/ \ 151 | --with-pear \ 152 | ${{ (inputs.type == 'debug' || inputs.type == 'sanitize') && '--enable-debug' || '' }} \ 153 | ${{ inputs.type == 'sanitize' && 'CFLAGS="-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address" CC=clang-16 CXX=clang++-16' || '' }} \ 154 | ${{ inputs.zts == 'zts' && '$zts' || '' }} \ 155 | --enable-fpm \ 156 | --enable-soap \ 157 | --enable-mbstring \ 158 | --with-curl \ 159 | --with-mysqli \ 160 | --with-openssl \ 161 | --with-pdo-mysql \ 162 | $zip \ 163 | --with-zlib 164 | 165 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 166 | shell: bash 167 | working-directory: ./php/ 168 | run: | 169 | make -j$(getconf _NPROCESSORS_ONLN) 170 | 171 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 172 | shell: bash 173 | working-directory: ./php/ 174 | run: | 175 | make install 176 | 177 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 178 | shell: bash 179 | working-directory: ./php/ 180 | run: | 181 | gh release --repo php/pie download --pattern pie.phar 182 | gh attestation verify --repo php/pie pie.phar 183 | mv pie.phar $(pwd)/target/bin/pie 184 | chmod +x $(pwd)/target/bin/pie 185 | env: 186 | GH_TOKEN: ${{ github.token }} 187 | 188 | - if: ${{ steps.cache-php.outputs.cache-hit != 'true' }} 189 | shell: bash 190 | working-directory: ./php/ 191 | run: | 192 | gh release --repo composer/composer download --pattern composer.phar 193 | gh attestation verify --repo composer/composer composer.phar 194 | mv composer.phar $(pwd)/target/bin/composer 195 | chmod +x $(pwd)/target/bin/composer 196 | env: 197 | GH_TOKEN: ${{ github.token }} 198 | -------------------------------------------------------------------------------- /hdrhistogram_arginfo.h: -------------------------------------------------------------------------------- 1 | /* This is a generated file, edit the .stub.php file instead. 2 | * Stub hash: 4e91058eaa9a3defd0e052aa081bb9c4d8ea7b12 */ 3 | 4 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_init, 0, 3, HdrHistogram\\Histogram, MAY_BE_FALSE) 5 | ZEND_ARG_TYPE_INFO(0, lowest_trackable_value, IS_LONG, 0) 6 | ZEND_ARG_TYPE_INFO(0, highest_trackable_value, IS_LONG, 0) 7 | ZEND_ARG_TYPE_INFO(0, significant_figures, IS_LONG, 0) 8 | ZEND_END_ARG_INFO() 9 | 10 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_get_memory_size, 0, 1, IS_LONG, 0) 11 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 12 | ZEND_END_ARG_INFO() 13 | 14 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_record_value, 0, 2, _IS_BOOL, 0) 15 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 16 | ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) 17 | ZEND_END_ARG_INFO() 18 | 19 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_record_values, 0, 3, _IS_BOOL, 0) 20 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 21 | ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) 22 | ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0) 23 | ZEND_END_ARG_INFO() 24 | 25 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_record_corrected_value, 0, 3, _IS_BOOL, 0) 26 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 27 | ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) 28 | ZEND_ARG_TYPE_INFO(0, expected_interval, IS_LONG, 0) 29 | ZEND_END_ARG_INFO() 30 | 31 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_mean, 0, 1, IS_DOUBLE, 0) 32 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 33 | ZEND_END_ARG_INFO() 34 | 35 | #define arginfo_hdr_stddev arginfo_hdr_mean 36 | 37 | #define arginfo_hdr_min arginfo_hdr_get_memory_size 38 | 39 | #define arginfo_hdr_max arginfo_hdr_get_memory_size 40 | 41 | #define arginfo_hdr_total_count arginfo_hdr_get_memory_size 42 | 43 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_reset, 0, 1, IS_VOID, 0) 44 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 45 | ZEND_END_ARG_INFO() 46 | 47 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_count_at_value, 0, 2, IS_LONG, 0) 48 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 49 | ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) 50 | ZEND_END_ARG_INFO() 51 | 52 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_value_at_percentile, 0, 2, IS_LONG, 0) 53 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 54 | ZEND_ARG_TYPE_INFO(0, percentile, IS_DOUBLE, 0) 55 | ZEND_END_ARG_INFO() 56 | 57 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_add, 0, 2, HdrHistogram\\Histogram, MAY_BE_FALSE) 58 | ZEND_ARG_OBJ_INFO(0, hdr1, HdrHistogram\\Histogram, 0) 59 | ZEND_ARG_OBJ_INFO(0, hdr2, HdrHistogram\\Histogram, 0) 60 | ZEND_END_ARG_INFO() 61 | 62 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_merge_into, 0, 2, IS_LONG, 0) 63 | ZEND_ARG_OBJ_INFO(0, hdr1, HdrHistogram\\Histogram, 0) 64 | ZEND_ARG_OBJ_INFO(0, hdr2, HdrHistogram\\Histogram, 0) 65 | ZEND_END_ARG_INFO() 66 | 67 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_iter_init, 0, 1, HdrHistogram\\Iterator, MAY_BE_FALSE) 68 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 69 | ZEND_END_ARG_INFO() 70 | 71 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hdr_iter_next, 0, 1, MAY_BE_FALSE|MAY_BE_ARRAY) 72 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Iterator, 0) 73 | ZEND_END_ARG_INFO() 74 | 75 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_percentile_iter_init, 0, 2, HdrHistogram\\Iterator\\Percentile, MAY_BE_FALSE) 76 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 77 | ZEND_ARG_TYPE_INFO(0, ticks_per_half_distance, IS_LONG, 0) 78 | ZEND_END_ARG_INFO() 79 | 80 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hdr_percentile_iter_next, 0, 1, MAY_BE_FALSE|MAY_BE_ARRAY) 81 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Iterator\\Percentile, 0) 82 | ZEND_END_ARG_INFO() 83 | 84 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hdr_export, 0, 1, IS_ARRAY, 0) 85 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 86 | ZEND_END_ARG_INFO() 87 | 88 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_import, 0, 1, HdrHistogram\\Histogram, MAY_BE_FALSE) 89 | ZEND_ARG_TYPE_INFO(0, import, IS_ARRAY, 0) 90 | ZEND_END_ARG_INFO() 91 | 92 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hdr_base64_encode, 0, 1, MAY_BE_FALSE|MAY_BE_STRING) 93 | ZEND_ARG_OBJ_INFO(0, hdr, HdrHistogram\\Histogram, 0) 94 | ZEND_END_ARG_INFO() 95 | 96 | ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_hdr_base64_decode, 0, 1, HdrHistogram\\Histogram, MAY_BE_FALSE) 97 | ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) 98 | ZEND_END_ARG_INFO() 99 | 100 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Histogram___construct, 0, 0, 3) 101 | ZEND_ARG_TYPE_INFO(0, lowestDiscernibleValue, IS_LONG, 0) 102 | ZEND_ARG_TYPE_INFO(0, highestTrackableValue, IS_LONG, 0) 103 | ZEND_ARG_TYPE_INFO(0, significantFigures, IS_LONG, 0) 104 | ZEND_END_ARG_INFO() 105 | 106 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Iterator___construct, 0, 0, 1) 107 | ZEND_ARG_OBJ_INFO(0, histogram, HdrHistogram\\Histogram, 0) 108 | ZEND_END_ARG_INFO() 109 | 110 | ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HdrHistogram_Iterator_Percentile___construct, 0, 0, 2) 111 | ZEND_ARG_OBJ_INFO(0, histogram, HdrHistogram\\Histogram, 0) 112 | ZEND_ARG_TYPE_INFO(0, ticksPerHalfDistance, IS_LONG, 0) 113 | ZEND_END_ARG_INFO() 114 | 115 | 116 | ZEND_FUNCTION(hdr_init); 117 | ZEND_FUNCTION(hdr_get_memory_size); 118 | ZEND_FUNCTION(hdr_record_value); 119 | ZEND_FUNCTION(hdr_record_values); 120 | ZEND_FUNCTION(hdr_record_corrected_value); 121 | ZEND_FUNCTION(hdr_mean); 122 | ZEND_FUNCTION(hdr_stddev); 123 | ZEND_FUNCTION(hdr_min); 124 | ZEND_FUNCTION(hdr_max); 125 | ZEND_FUNCTION(hdr_total_count); 126 | ZEND_FUNCTION(hdr_reset); 127 | ZEND_FUNCTION(hdr_count_at_value); 128 | ZEND_FUNCTION(hdr_value_at_percentile); 129 | ZEND_FUNCTION(hdr_add); 130 | ZEND_FUNCTION(hdr_merge_into); 131 | ZEND_FUNCTION(hdr_iter_init); 132 | ZEND_FUNCTION(hdr_iter_next); 133 | ZEND_FUNCTION(hdr_percentile_iter_init); 134 | ZEND_FUNCTION(hdr_percentile_iter_next); 135 | ZEND_FUNCTION(hdr_export); 136 | ZEND_FUNCTION(hdr_import); 137 | ZEND_FUNCTION(hdr_base64_encode); 138 | ZEND_FUNCTION(hdr_base64_decode); 139 | ZEND_METHOD(HdrHistogram_Histogram, __construct); 140 | ZEND_METHOD(HdrHistogram_Iterator, __construct); 141 | ZEND_METHOD(HdrHistogram_Iterator_Percentile, __construct); 142 | 143 | 144 | static const zend_function_entry ext_functions[] = { 145 | ZEND_FE(hdr_init, arginfo_hdr_init) 146 | ZEND_FE(hdr_get_memory_size, arginfo_hdr_get_memory_size) 147 | ZEND_FE(hdr_record_value, arginfo_hdr_record_value) 148 | ZEND_FE(hdr_record_values, arginfo_hdr_record_values) 149 | ZEND_FE(hdr_record_corrected_value, arginfo_hdr_record_corrected_value) 150 | ZEND_FE(hdr_mean, arginfo_hdr_mean) 151 | ZEND_FE(hdr_stddev, arginfo_hdr_stddev) 152 | ZEND_FE(hdr_min, arginfo_hdr_min) 153 | ZEND_FE(hdr_max, arginfo_hdr_max) 154 | ZEND_FE(hdr_total_count, arginfo_hdr_total_count) 155 | ZEND_FE(hdr_reset, arginfo_hdr_reset) 156 | ZEND_FE(hdr_count_at_value, arginfo_hdr_count_at_value) 157 | ZEND_FE(hdr_value_at_percentile, arginfo_hdr_value_at_percentile) 158 | ZEND_FE(hdr_add, arginfo_hdr_add) 159 | ZEND_FE(hdr_merge_into, arginfo_hdr_merge_into) 160 | ZEND_FE(hdr_iter_init, arginfo_hdr_iter_init) 161 | ZEND_FE(hdr_iter_next, arginfo_hdr_iter_next) 162 | ZEND_FE(hdr_percentile_iter_init, arginfo_hdr_percentile_iter_init) 163 | ZEND_FE(hdr_percentile_iter_next, arginfo_hdr_percentile_iter_next) 164 | ZEND_FE(hdr_export, arginfo_hdr_export) 165 | ZEND_FE(hdr_import, arginfo_hdr_import) 166 | ZEND_FE(hdr_base64_encode, arginfo_hdr_base64_encode) 167 | ZEND_FE(hdr_base64_decode, arginfo_hdr_base64_decode) 168 | ZEND_FE_END 169 | }; 170 | 171 | 172 | static const zend_function_entry class_HdrHistogram_Histogram_methods[] = { 173 | ZEND_ME(HdrHistogram_Histogram, __construct, arginfo_class_HdrHistogram_Histogram___construct, ZEND_ACC_PUBLIC) 174 | ZEND_FE_END 175 | }; 176 | 177 | 178 | static const zend_function_entry class_HdrHistogram_Iterator_methods[] = { 179 | ZEND_ME(HdrHistogram_Iterator, __construct, arginfo_class_HdrHistogram_Iterator___construct, ZEND_ACC_PUBLIC) 180 | ZEND_FE_END 181 | }; 182 | 183 | 184 | static const zend_function_entry class_HdrHistogram_Iterator_Percentile_methods[] = { 185 | ZEND_ME(HdrHistogram_Iterator_Percentile, __construct, arginfo_class_HdrHistogram_Iterator_Percentile___construct, ZEND_ACC_PUBLIC) 186 | ZEND_FE_END 187 | }; 188 | 189 | static zend_class_entry *register_class_HdrHistogram_Histogram(void) 190 | { 191 | zend_class_entry ce, *class_entry; 192 | 193 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram", "Histogram", class_HdrHistogram_Histogram_methods); 194 | class_entry = zend_register_internal_class_ex(&ce, NULL); 195 | #if (PHP_VERSION_ID >= 80100) 196 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 197 | #elif (PHP_VERSION_ID >= 80000) 198 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 199 | #elif (PHP_VERSION_ID >= 70000) 200 | class_entry->ce_flags |= ZEND_ACC_FINAL; 201 | #endif 202 | 203 | return class_entry; 204 | } 205 | 206 | static zend_class_entry *register_class_HdrHistogram_Iterator(void) 207 | { 208 | zend_class_entry ce, *class_entry; 209 | 210 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram", "Iterator", class_HdrHistogram_Iterator_methods); 211 | class_entry = zend_register_internal_class_ex(&ce, NULL); 212 | #if (PHP_VERSION_ID >= 80100) 213 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 214 | #elif (PHP_VERSION_ID >= 80000) 215 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 216 | #elif (PHP_VERSION_ID >= 70000) 217 | class_entry->ce_flags |= ZEND_ACC_FINAL; 218 | #endif 219 | 220 | return class_entry; 221 | } 222 | 223 | static zend_class_entry *register_class_HdrHistogram_Iterator_Percentile(void) 224 | { 225 | zend_class_entry ce, *class_entry; 226 | 227 | INIT_NS_CLASS_ENTRY(ce, "HdrHistogram\\Iterator", "Percentile", class_HdrHistogram_Iterator_Percentile_methods); 228 | class_entry = zend_register_internal_class_ex(&ce, NULL); 229 | #if (PHP_VERSION_ID >= 80100) 230 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE; 231 | #elif (PHP_VERSION_ID >= 80000) 232 | class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES; 233 | #elif (PHP_VERSION_ID >= 70000) 234 | class_entry->ce_flags |= ZEND_ACC_FINAL; 235 | #endif 236 | 237 | return class_entry; 238 | } 239 | -------------------------------------------------------------------------------- /hdrhistogram.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #include "php.h" 6 | #include "ext/standard/info.h" 7 | #include "Zend/zend_exceptions.h" 8 | #include "Zend/zend_interfaces.h" 9 | #include "hdr/hdr_histogram.h" 10 | #include "hdr/hdr_histogram_log.h" 11 | #ifdef HAVE_HDR_HDR_HISTOGRAM_VERSION_H 12 | #include "hdr/hdr_histogram_version.h" 13 | #endif 14 | #include "php_hdrhistogram.h" 15 | 16 | #if PHP_VERSION_ID < 80000 17 | #include "hdrhistogram_legacy_arginfo.h" 18 | #else 19 | #include "hdrhistogram_arginfo.h" 20 | #endif 21 | 22 | static zend_class_entry *php_HdrHistogram_Histogram_ce; 23 | static zend_object_handlers php_hdrhistogram_histogram_object_handlers; 24 | 25 | struct php_hdrhistogram_histogram { 26 | struct hdr_histogram *histogram; 27 | zend_object std; 28 | }; 29 | 30 | static inline struct php_hdrhistogram_histogram *php_hdrhistogram_histogram_from_object(zend_object *object) { 31 | return (struct php_hdrhistogram_histogram *)((char *)(object) - XtOffsetOf(struct php_hdrhistogram_histogram, std)); 32 | } 33 | 34 | static zend_object *php_hdrhistogram_histogram_new(zend_class_entry *ce) 35 | { 36 | struct php_hdrhistogram_histogram *histogram; 37 | #if PHP_VERSION_ID >= 70300 38 | histogram = zend_object_alloc(sizeof(struct php_hdrhistogram_histogram), ce); 39 | #else 40 | histogram = ecalloc(1, sizeof(struct php_hdrhistogram_histogram) + sizeof(zval) * (ce->default_properties_count - 1)); 41 | #endif 42 | 43 | zend_object_std_init(&histogram->std, ce); 44 | object_properties_init(&histogram->std, ce); 45 | histogram->std.handlers = &php_hdrhistogram_histogram_object_handlers; 46 | 47 | histogram->histogram = NULL; 48 | 49 | return &histogram->std; 50 | } 51 | 52 | static void php_hdrhistogram_histogram_free(zend_object *object) 53 | { 54 | struct php_hdrhistogram_histogram *histogram = php_hdrhistogram_histogram_from_object(object); 55 | 56 | if (histogram->histogram) { 57 | hdr_close(histogram->histogram); 58 | } 59 | 60 | zend_object_std_dtor(&histogram->std); 61 | } 62 | 63 | #if PHP_VERSION_ID < 80000 64 | static zend_object *php_hdrhistogram_histogram_clone(zval *zval) 65 | #else 66 | static zend_object *php_hdrhistogram_histogram_clone(zend_object *object) 67 | #endif 68 | { 69 | #if PHP_VERSION_ID < 80000 70 | zend_object *object = Z_OBJ_P(zval); 71 | #endif 72 | struct php_hdrhistogram_histogram *old = php_hdrhistogram_histogram_from_object(object); 73 | struct php_hdrhistogram_histogram *new = php_hdrhistogram_histogram_from_object(old->std.ce->create_object(old->std.ce)); 74 | 75 | struct hdr_histogram *hdr_new; 76 | int res; 77 | 78 | #ifdef HAVE_HDR_HISTOGRAM_LOWEST_DISCERNIBLE_VALUE 79 | res = hdr_init(old->histogram->lowest_discernible_value, old->histogram->highest_trackable_value, old->histogram->significant_figures, &hdr_new); 80 | #else 81 | res = hdr_init(old->histogram->lowest_trackable_value, old->histogram->highest_trackable_value, old->histogram->significant_figures, &hdr_new); 82 | #endif 83 | 84 | if (res != 0) { 85 | zend_throw_error(zend_ce_error, "Unable to initialize HdrHistogram."); 86 | return NULL; 87 | } 88 | 89 | new->histogram = hdr_new; 90 | 91 | int64_t dropped = hdr_add(new->histogram, old->histogram); 92 | ZEND_ASSERT(dropped == 0); 93 | if (dropped != 0) { 94 | zend_throw_error(zend_ce_error, "Unable to transfer values from old histogram."); 95 | return NULL; 96 | } 97 | 98 | return &new->std; 99 | } 100 | 101 | static zend_class_entry *php_HdrHistogram_Iterator_ce; 102 | static zend_object_handlers php_hdrhistogram_iterator_object_handlers; 103 | 104 | struct php_hdrhistogram_iterator { 105 | struct hdr_iter *iterator; 106 | zend_object std; 107 | }; 108 | 109 | static inline struct php_hdrhistogram_iterator *php_hdrhistogram_iterator_from_object(zend_object *object) { 110 | return (struct php_hdrhistogram_iterator *)((char *)(object) - XtOffsetOf(struct php_hdrhistogram_iterator, std)); 111 | } 112 | 113 | static zend_object *php_hdrhistogram_iterator_new(zend_class_entry *ce) 114 | { 115 | struct php_hdrhistogram_iterator *iterator; 116 | #if PHP_VERSION_ID >= 70300 117 | iterator = zend_object_alloc(sizeof(struct php_hdrhistogram_iterator), ce); 118 | #else 119 | iterator = ecalloc(1, sizeof(struct php_hdrhistogram_iterator) + sizeof(zval) * (ce->default_properties_count - 1)); 120 | #endif 121 | 122 | zend_object_std_init(&iterator->std, ce); 123 | object_properties_init(&iterator->std, ce); 124 | iterator->std.handlers = &php_hdrhistogram_iterator_object_handlers; 125 | 126 | iterator->iterator = NULL; 127 | 128 | return &iterator->std; 129 | } 130 | 131 | static void php_hdrhistogram_iterator_free(zend_object *object) 132 | { 133 | struct php_hdrhistogram_iterator *iterator = php_hdrhistogram_iterator_from_object(object); 134 | 135 | efree(iterator->iterator); 136 | 137 | zend_object_std_dtor(&iterator->std); 138 | } 139 | 140 | static zend_class_entry *php_HdrHistogram_Iterator_Percentile_ce; 141 | 142 | zend_module_entry hdrhistogram_module_entry = { 143 | STANDARD_MODULE_HEADER, 144 | "hdrhistogram", 145 | ext_functions, /* List of functions exposed */ 146 | PHP_MINIT(hdrhistogram), /* Module init callback */ 147 | NULL, /* Module shutdown callback */ 148 | NULL, /* Request init callback */ 149 | NULL, /* Request shutdown callback */ 150 | PHP_MINFO(hdrhistogram), /* Module info callback */ 151 | PHP_HDR_HISTOGRAM_VERSION, 152 | STANDARD_MODULE_PROPERTIES 153 | }; 154 | 155 | #ifdef COMPILE_DL_HDRHISTOGRAM 156 | ZEND_GET_MODULE(hdrhistogram) 157 | #endif 158 | 159 | PHP_MINIT_FUNCTION(hdrhistogram) 160 | { 161 | php_HdrHistogram_Histogram_ce = register_class_HdrHistogram_Histogram(); 162 | php_HdrHistogram_Histogram_ce->create_object = php_hdrhistogram_histogram_new; 163 | memcpy(&php_hdrhistogram_histogram_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 164 | php_hdrhistogram_histogram_object_handlers.offset = XtOffsetOf(struct php_hdrhistogram_histogram, std); 165 | php_hdrhistogram_histogram_object_handlers.free_obj = php_hdrhistogram_histogram_free; 166 | php_hdrhistogram_histogram_object_handlers.clone_obj = php_hdrhistogram_histogram_clone; 167 | #if PHP_VERSION_ID < 80100 168 | php_HdrHistogram_Histogram_ce->serialize = zend_class_serialize_deny; 169 | php_HdrHistogram_Histogram_ce->unserialize = zend_class_unserialize_deny; 170 | #endif 171 | 172 | php_HdrHistogram_Iterator_ce = register_class_HdrHistogram_Iterator(); 173 | php_HdrHistogram_Iterator_ce->create_object = php_hdrhistogram_iterator_new; 174 | memcpy(&php_hdrhistogram_iterator_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 175 | php_hdrhistogram_iterator_object_handlers.offset = XtOffsetOf(struct php_hdrhistogram_iterator, std); 176 | php_hdrhistogram_iterator_object_handlers.free_obj = php_hdrhistogram_iterator_free; 177 | php_hdrhistogram_iterator_object_handlers.clone_obj = NULL; 178 | #if PHP_VERSION_ID < 80100 179 | php_HdrHistogram_Iterator_ce->serialize = zend_class_serialize_deny; 180 | php_HdrHistogram_Iterator_ce->unserialize = zend_class_unserialize_deny; 181 | #endif 182 | 183 | php_HdrHistogram_Iterator_Percentile_ce = register_class_HdrHistogram_Iterator_Percentile(); 184 | php_HdrHistogram_Iterator_Percentile_ce->create_object = php_hdrhistogram_iterator_new; 185 | #if PHP_VERSION_ID < 80100 186 | php_HdrHistogram_Iterator_Percentile_ce->serialize = zend_class_serialize_deny; 187 | php_HdrHistogram_Iterator_Percentile_ce->unserialize = zend_class_unserialize_deny; 188 | #endif 189 | 190 | return SUCCESS; 191 | } 192 | 193 | PHP_MINFO_FUNCTION(hdrhistogram) 194 | { 195 | php_info_print_table_start(); 196 | 197 | php_info_print_table_row(2, "hdrhistogram support", "enabled"); 198 | php_info_print_table_row(2, "Extension version", PHP_HDR_HISTOGRAM_VERSION); 199 | #ifdef HDR_HISTOGRAM_VERSION 200 | php_info_print_table_row(2, "Library version", HDR_HISTOGRAM_VERSION); 201 | #endif 202 | } 203 | 204 | ZEND_METHOD(HdrHistogram_Histogram, __construct) 205 | { 206 | zend_long lowest_discernible_value, highest_trackable_value, significant_figures; 207 | 208 | ZEND_PARSE_PARAMETERS_START(3, 3) 209 | Z_PARAM_LONG(lowest_discernible_value); 210 | Z_PARAM_LONG(highest_trackable_value); 211 | Z_PARAM_LONG(significant_figures); 212 | ZEND_PARSE_PARAMETERS_END(); 213 | 214 | if (lowest_discernible_value < 1) { 215 | #if PHP_VERSION_ID >= 80000 216 | zend_argument_value_error(1, "must be greater than or equal to 1"); 217 | #else 218 | zend_throw_exception_ex(NULL, 0, "%s(): Argument #%d ($%s) must be greater than or equal to 1", "HdrHistogram\\Histogram::__construct", 1, "lowestDiscernibleValue"); 219 | #endif 220 | return; 221 | } 222 | 223 | if (highest_trackable_value < lowest_discernible_value * 2) { 224 | #if PHP_VERSION_ID >= 80000 225 | zend_argument_value_error(2, "must be greater than or equal to twice the value of argument #%d ($%s)", 1, "lowestDiscernibleValue"); 226 | #else 227 | zend_throw_exception_ex(NULL, 0, "%s(): Argument #%d ($%s) must be greater than or equal to twice the value of argument #%d ($%s)", "HdrHistogram\\Histogram::__construct", 2, "highestTrackableValue", 1, "lowestDiscernibleValue"); 228 | #endif 229 | return; 230 | } 231 | 232 | if (significant_figures < 1 || significant_figures > 5) { 233 | #if PHP_VERSION_ID >= 80000 234 | zend_argument_value_error(3, "must be between 1 and 5"); 235 | #else 236 | zend_throw_exception_ex(NULL, 0, "%s(): Argument #%d ($%s) must be between 1 and 5", "HdrHistogram\\Histogram::__construct", 3, "significantFigures"); 237 | #endif 238 | return; 239 | } 240 | 241 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(getThis())); 242 | 243 | struct hdr_histogram *hdr; 244 | int res = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &hdr); 245 | 246 | if (res != 0) { 247 | zend_throw_error(zend_ce_error, "Unable to initialize HdrHistogram."); 248 | return; 249 | } 250 | 251 | h->histogram = hdr; 252 | } 253 | 254 | ZEND_METHOD(HdrHistogram_Iterator, __construct) 255 | { 256 | zval *zhdr; 257 | 258 | ZEND_PARSE_PARAMETERS_START(1, 1) 259 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 260 | ZEND_PARSE_PARAMETERS_END(); 261 | 262 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 263 | 264 | struct hdr_iter *iterator = emalloc(sizeof(*iterator)); 265 | hdr_iter_init(iterator, hdr); 266 | 267 | object_init_ex(return_value, php_HdrHistogram_Iterator_ce); 268 | struct php_hdrhistogram_iterator *i = php_hdrhistogram_iterator_from_object(Z_OBJ_P(getThis())); 269 | i->iterator = iterator; 270 | } 271 | 272 | ZEND_METHOD(HdrHistogram_Iterator_Percentile, __construct) 273 | { 274 | zval *zhdr; 275 | zend_long ticks_per_half_distance; 276 | 277 | ZEND_PARSE_PARAMETERS_START(2, 2) 278 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 279 | Z_PARAM_LONG(ticks_per_half_distance); 280 | ZEND_PARSE_PARAMETERS_END(); 281 | 282 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 283 | 284 | struct hdr_iter *iterator = emalloc(sizeof(*iterator)); 285 | hdr_iter_percentile_init(iterator, hdr, ticks_per_half_distance); 286 | 287 | object_init_ex(return_value, php_HdrHistogram_Iterator_ce); 288 | struct php_hdrhistogram_iterator *i = php_hdrhistogram_iterator_from_object(Z_OBJ_P(getThis())); 289 | i->iterator = iterator; 290 | } 291 | 292 | PHP_FUNCTION(hdr_init) 293 | { 294 | zend_long lowest_discernible_value, highest_trackable_value, significant_figures; 295 | 296 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", 297 | &lowest_discernible_value, &highest_trackable_value, &significant_figures) == FAILURE) { 298 | php_error_docref(NULL, E_WARNING, "Invalid arguments passed."); 299 | 300 | RETURN_FALSE; 301 | } 302 | 303 | struct hdr_histogram *hdr; 304 | int res = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &hdr); 305 | 306 | if (res == 0) { 307 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 308 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 309 | h->histogram = hdr; 310 | } else if (res == EINVAL) { 311 | php_error_docref(NULL, E_WARNING, "Lowest trackable value has to be >= 1."); 312 | 313 | RETURN_FALSE; 314 | } else if (res == ENOMEM) { 315 | php_error_docref(NULL, E_WARNING, "Memory error in hdr_init allocation."); 316 | 317 | RETURN_FALSE; 318 | } 319 | } 320 | 321 | PHP_FUNCTION(hdr_get_memory_size) 322 | { 323 | zval *zhdr; 324 | 325 | ZEND_PARSE_PARAMETERS_START(1, 1) 326 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 327 | ZEND_PARSE_PARAMETERS_END(); 328 | 329 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 330 | 331 | RETURN_LONG(hdr_get_memory_size(hdr)); 332 | } 333 | 334 | PHP_FUNCTION(hdr_mean) 335 | { 336 | zval *zhdr; 337 | 338 | ZEND_PARSE_PARAMETERS_START(1, 1) 339 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 340 | ZEND_PARSE_PARAMETERS_END(); 341 | 342 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 343 | 344 | RETURN_DOUBLE(hdr_mean(hdr)); 345 | } 346 | 347 | PHP_FUNCTION(hdr_stddev) 348 | { 349 | zval *zhdr; 350 | 351 | ZEND_PARSE_PARAMETERS_START(1, 1) 352 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 353 | ZEND_PARSE_PARAMETERS_END(); 354 | 355 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 356 | 357 | RETURN_DOUBLE(hdr_stddev(hdr)); 358 | } 359 | 360 | 361 | PHP_FUNCTION(hdr_min) 362 | { 363 | zval *zhdr; 364 | 365 | ZEND_PARSE_PARAMETERS_START(1, 1) 366 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 367 | ZEND_PARSE_PARAMETERS_END(); 368 | 369 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 370 | 371 | RETURN_LONG(hdr_min(hdr)); 372 | } 373 | 374 | PHP_FUNCTION(hdr_max) 375 | { 376 | zval *zhdr; 377 | 378 | ZEND_PARSE_PARAMETERS_START(1, 1) 379 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 380 | ZEND_PARSE_PARAMETERS_END(); 381 | 382 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 383 | 384 | RETURN_LONG(hdr_max(hdr)); 385 | } 386 | 387 | PHP_FUNCTION(hdr_total_count) 388 | { 389 | zval *zhdr; 390 | 391 | ZEND_PARSE_PARAMETERS_START(1, 1) 392 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 393 | ZEND_PARSE_PARAMETERS_END(); 394 | 395 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 396 | 397 | RETURN_LONG(hdr->total_count); 398 | } 399 | 400 | PHP_FUNCTION(hdr_record_value) 401 | { 402 | zval *zhdr; 403 | zend_long value; 404 | 405 | ZEND_PARSE_PARAMETERS_START(2, 2) 406 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 407 | Z_PARAM_LONG(value); 408 | ZEND_PARSE_PARAMETERS_END(); 409 | 410 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 411 | 412 | if (hdr_record_value(hdr, value) == 0) { 413 | RETURN_FALSE; 414 | } 415 | 416 | RETURN_TRUE; 417 | } 418 | 419 | PHP_FUNCTION(hdr_record_values) 420 | { 421 | zval *zhdr; 422 | zend_long value; 423 | zend_long count; 424 | 425 | ZEND_PARSE_PARAMETERS_START(3, 3) 426 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 427 | Z_PARAM_LONG(value); 428 | Z_PARAM_LONG(count); 429 | ZEND_PARSE_PARAMETERS_END(); 430 | 431 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 432 | 433 | if (hdr_record_values(hdr, value, count) == 0) { 434 | RETURN_FALSE; 435 | } 436 | 437 | RETURN_TRUE; 438 | } 439 | 440 | PHP_FUNCTION(hdr_record_corrected_value) 441 | { 442 | zval *zhdr; 443 | zend_long value; 444 | zend_long expected_interval; 445 | 446 | ZEND_PARSE_PARAMETERS_START(3, 3) 447 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 448 | Z_PARAM_LONG(value); 449 | Z_PARAM_LONG(expected_interval); 450 | ZEND_PARSE_PARAMETERS_END(); 451 | 452 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 453 | 454 | if (hdr_record_corrected_value(hdr, value, expected_interval)) { 455 | RETURN_TRUE; 456 | } 457 | 458 | RETURN_FALSE; 459 | } 460 | 461 | PHP_FUNCTION(hdr_reset) 462 | { 463 | zval *zhdr; 464 | 465 | ZEND_PARSE_PARAMETERS_START(1, 1) 466 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 467 | ZEND_PARSE_PARAMETERS_END(); 468 | 469 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 470 | 471 | hdr_reset(hdr); 472 | } 473 | 474 | PHP_FUNCTION(hdr_count_at_value) 475 | { 476 | zval *zhdr; 477 | zend_long value; 478 | 479 | ZEND_PARSE_PARAMETERS_START(2, 2) 480 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 481 | Z_PARAM_LONG(value); 482 | ZEND_PARSE_PARAMETERS_END(); 483 | 484 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 485 | 486 | RETURN_LONG(hdr_count_at_value(hdr, value)); 487 | } 488 | 489 | PHP_FUNCTION(hdr_value_at_percentile) 490 | { 491 | zval *zhdr; 492 | double percentile; 493 | 494 | ZEND_PARSE_PARAMETERS_START(2, 2) 495 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 496 | Z_PARAM_DOUBLE(percentile); 497 | ZEND_PARSE_PARAMETERS_END(); 498 | 499 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 500 | 501 | RETURN_LONG(hdr_value_at_percentile(hdr, percentile)); 502 | } 503 | 504 | PHP_FUNCTION(hdr_add) 505 | { 506 | zval *a, *b; 507 | 508 | ZEND_PARSE_PARAMETERS_START(2, 2) 509 | Z_PARAM_OBJECT_OF_CLASS(a, php_HdrHistogram_Histogram_ce); 510 | Z_PARAM_OBJECT_OF_CLASS(b, php_HdrHistogram_Histogram_ce); 511 | ZEND_PARSE_PARAMETERS_END(); 512 | 513 | struct hdr_histogram *hdra = php_hdrhistogram_histogram_from_object(Z_OBJ_P(a))->histogram; 514 | struct hdr_histogram *hdrb = php_hdrhistogram_histogram_from_object(Z_OBJ_P(b))->histogram; 515 | 516 | struct hdr_histogram *hdr_new; 517 | 518 | int res; 519 | #ifdef HAVE_HDR_HISTOGRAM_LOWEST_DISCERNIBLE_VALUE 520 | res = hdr_init(hdra->lowest_discernible_value, hdra->highest_trackable_value, hdra->significant_figures, &hdr_new); 521 | #else 522 | res = hdr_init(hdra->lowest_trackable_value, hdra->highest_trackable_value, hdra->significant_figures, &hdr_new); 523 | #endif 524 | hdr_add(hdr_new, hdra); 525 | hdr_add(hdr_new, hdrb); 526 | 527 | if (res == 0) { 528 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 529 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 530 | h->histogram = hdr_new; 531 | } else if (res == EINVAL) { 532 | php_error_docref(NULL, E_WARNING, "Lowest trackable value has to be >= 1."); 533 | 534 | RETURN_FALSE; 535 | } else if (res == ENOMEM) { 536 | php_error_docref(NULL, E_WARNING, "Memory error in hdr_init allocation."); 537 | 538 | RETURN_FALSE; 539 | } 540 | } 541 | 542 | PHP_FUNCTION(hdr_merge_into) 543 | { 544 | zval *a, *b; 545 | 546 | ZEND_PARSE_PARAMETERS_START(2, 2) 547 | Z_PARAM_OBJECT_OF_CLASS(a, php_HdrHistogram_Histogram_ce); 548 | Z_PARAM_OBJECT_OF_CLASS(b, php_HdrHistogram_Histogram_ce); 549 | ZEND_PARSE_PARAMETERS_END(); 550 | 551 | struct hdr_histogram *hdra = php_hdrhistogram_histogram_from_object(Z_OBJ_P(a))->histogram; 552 | struct hdr_histogram *hdrb = php_hdrhistogram_histogram_from_object(Z_OBJ_P(b))->histogram; 553 | 554 | RETURN_LONG(hdr_add(hdra, hdrb)); 555 | } 556 | 557 | PHP_FUNCTION(hdr_iter_init) 558 | { 559 | zval *zhdr; 560 | 561 | ZEND_PARSE_PARAMETERS_START(1, 1) 562 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 563 | ZEND_PARSE_PARAMETERS_END(); 564 | 565 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 566 | 567 | struct hdr_iter *iterator = emalloc(sizeof(*iterator)); 568 | hdr_iter_init(iterator, hdr); 569 | 570 | object_init_ex(return_value, php_HdrHistogram_Iterator_ce); 571 | struct php_hdrhistogram_iterator *i = php_hdrhistogram_iterator_from_object(Z_OBJ_P(return_value)); 572 | i->iterator = iterator; 573 | } 574 | 575 | PHP_FUNCTION(hdr_percentile_iter_init) 576 | { 577 | zval *zhdr; 578 | zend_long ticks_per_half_distance; 579 | 580 | ZEND_PARSE_PARAMETERS_START(2, 2) 581 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 582 | Z_PARAM_LONG(ticks_per_half_distance); 583 | ZEND_PARSE_PARAMETERS_END(); 584 | 585 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 586 | 587 | struct hdr_iter *iterator = emalloc(sizeof(*iterator)); 588 | hdr_iter_percentile_init(iterator, hdr, ticks_per_half_distance); 589 | 590 | object_init_ex(return_value, php_HdrHistogram_Iterator_Percentile_ce); 591 | struct php_hdrhistogram_iterator *i = php_hdrhistogram_iterator_from_object(Z_OBJ_P(return_value)); 592 | i->iterator = iterator; 593 | } 594 | 595 | PHP_FUNCTION(hdr_iter_next) 596 | { 597 | zval *zhdr; 598 | 599 | ZEND_PARSE_PARAMETERS_START(1, 1) 600 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Iterator_ce); 601 | ZEND_PARSE_PARAMETERS_END(); 602 | 603 | struct hdr_iter *iterator = php_hdrhistogram_iterator_from_object(Z_OBJ_P(zhdr))->iterator; 604 | 605 | if (hdr_iter_next(iterator)) { 606 | array_init(return_value); 607 | add_assoc_long(return_value, "value", iterator->value); 608 | add_assoc_long(return_value, "count_at_index", iterator->count); 609 | add_assoc_long(return_value, "count_to_index", iterator->cumulative_count); 610 | add_assoc_long(return_value, "highest_equivalent_value", iterator->highest_equivalent_value); 611 | } else { 612 | RETURN_FALSE; 613 | } 614 | } 615 | 616 | PHP_FUNCTION(hdr_percentile_iter_next) 617 | { 618 | zval *zhdr; 619 | 620 | ZEND_PARSE_PARAMETERS_START(1, 1) 621 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Iterator_Percentile_ce); 622 | ZEND_PARSE_PARAMETERS_END(); 623 | 624 | struct hdr_iter *iterator = php_hdrhistogram_iterator_from_object(Z_OBJ_P(zhdr))->iterator; 625 | 626 | if (hdr_iter_next(iterator)) { 627 | array_init(return_value); 628 | add_assoc_long(return_value, "value", iterator->value); 629 | add_assoc_long(return_value, "count_at_index", iterator->count); 630 | add_assoc_long(return_value, "count_to_index", iterator->cumulative_count); 631 | add_assoc_long(return_value, "highest_equivalent_value", iterator->highest_equivalent_value); 632 | add_assoc_long(return_value, "seen_last_value", iterator->specifics.percentiles.seen_last_value); 633 | add_assoc_long(return_value, "ticks_per_half_distance", iterator->specifics.percentiles.ticks_per_half_distance); 634 | add_assoc_double(return_value, "percentile_to_iterate_to", iterator->specifics.percentiles.percentile_to_iterate_to); 635 | add_assoc_double(return_value, "percentile", iterator->specifics.percentiles.percentile); 636 | } else { 637 | RETURN_FALSE; 638 | } 639 | } 640 | 641 | PHP_FUNCTION(hdr_export) 642 | { 643 | zval *zhdr; 644 | 645 | ZEND_PARSE_PARAMETERS_START(1, 1) 646 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 647 | ZEND_PARSE_PARAMETERS_END(); 648 | 649 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 650 | 651 | array_init(return_value); 652 | 653 | #ifdef HAVE_HDR_HISTOGRAM_LOWEST_DISCERNIBLE_VALUE 654 | if (hdr->lowest_discernible_value > 1) { 655 | add_assoc_long(return_value, "ltv", hdr->lowest_discernible_value); 656 | } 657 | #else 658 | if (hdr->lowest_trackable_value > 1) { 659 | add_assoc_long(return_value, "ltv", hdr->lowest_trackable_value); 660 | } 661 | #endif 662 | if (hdr->highest_trackable_value != 60000) { 663 | add_assoc_long(return_value, "htv", hdr->highest_trackable_value); 664 | } 665 | if (hdr->significant_figures != 2) { 666 | add_assoc_long(return_value, "sf", hdr->significant_figures); 667 | } 668 | 669 | zval values; 670 | array_init(&values); 671 | 672 | int64_t found = 0; 673 | zend_long skipped = 0; 674 | int32_t i; 675 | for (i = 0; i < hdr->counts_len; i++) { 676 | if (found >= hdr->total_count) { 677 | break; 678 | } 679 | if (hdr->counts[i] == 0) { 680 | skipped--; 681 | } else { 682 | if (skipped < 0) { 683 | add_next_index_long(&values, skipped); 684 | skipped = 0; 685 | } 686 | add_next_index_long(&values, (zend_long)hdr->counts[i]); 687 | } 688 | 689 | found += hdr->counts[i]; 690 | } 691 | 692 | add_assoc_zval(return_value, "v", &values); 693 | } 694 | 695 | PHP_FUNCTION(hdr_import) 696 | { 697 | struct hdr_histogram *hdr; 698 | zval *import, *value, *item; 699 | long lowest_discernible_value, highest_trackable_value, significant_figures; 700 | int res, count; 701 | zend_ulong i, bucket, skipped; 702 | 703 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &import) == FAILURE) { 704 | RETURN_FALSE; 705 | } 706 | 707 | if ((value = zend_hash_str_find(Z_ARRVAL_P(import), "ltv", strlen("ltv"))) != NULL) { 708 | lowest_discernible_value = Z_LVAL_P(value); 709 | } else { 710 | lowest_discernible_value = 1; 711 | } 712 | 713 | if (lowest_discernible_value <= 0) { 714 | php_error_docref(NULL, E_WARNING, "lowest_trackable_value (ltv) must be >= 1."); 715 | RETURN_FALSE; 716 | } 717 | 718 | if ((value = zend_hash_str_find(Z_ARRVAL_P(import), "htv", strlen("htv"))) != NULL) { 719 | highest_trackable_value = Z_LVAL_P(value); 720 | } else { 721 | highest_trackable_value = 60000; 722 | } 723 | 724 | if (highest_trackable_value <= 0) { 725 | php_error_docref(NULL, E_WARNING, "highest_trackable_value (htv) must be >= 1."); 726 | RETURN_FALSE; 727 | } 728 | 729 | if ((value = zend_hash_str_find(Z_ARRVAL_P(import), "sf", strlen("sf"))) != NULL) { 730 | significant_figures = Z_LVAL_P(value); 731 | } else { 732 | significant_figures = 2; 733 | } 734 | 735 | if (significant_figures <= 0 || significant_figures > 3) { 736 | php_error_docref(NULL, E_WARNING, "significant_figures (sf) must be 1, 2, or 3."); 737 | RETURN_FALSE; 738 | } 739 | 740 | if ((value = zend_hash_str_find(Z_ARRVAL_P(import), "sk", strlen("sk"))) != NULL) { 741 | skipped = Z_LVAL_P(value); 742 | } else { 743 | skipped = 0; 744 | } 745 | 746 | if (skipped < 0 || lowest_discernible_value < 1 || highest_trackable_value < lowest_discernible_value || significant_figures < 1) { 747 | php_error_docref(NULL, E_WARNING, "Invalid values for ltv, htv, sf or sk keys given."); 748 | RETURN_FALSE; 749 | } 750 | 751 | value = zend_hash_str_find(Z_ARRVAL_P(import), "v", strlen("v")); 752 | 753 | // version 3 format 754 | if (value != NULL && Z_TYPE_P(value) == IS_ARRAY) { 755 | count = zend_hash_num_elements(Z_ARRVAL_P(value)); 756 | res = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &hdr); 757 | 758 | if (res == 0) { 759 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 760 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 761 | h->histogram = hdr; 762 | } else if (res == EINVAL) { 763 | php_error_docref(NULL, E_WARNING, "Lowest trackable value has to be >= 1."); 764 | 765 | RETURN_FALSE; 766 | } else if (res == ENOMEM) { 767 | php_error_docref(NULL, E_WARNING, "Memory error in hdr_init allocation."); 768 | 769 | RETURN_FALSE; 770 | } 771 | 772 | zend_string *key; 773 | zend_ulong num_key; 774 | int bucket = 0; 775 | ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(value), num_key, key, item) { 776 | (void)num_key; 777 | if (!key && bucket < hdr->counts_len) { 778 | convert_to_long_ex(item); 779 | if (Z_LVAL_P(item) > 0) { 780 | hdr->counts[bucket] = Z_LVAL_P(item); 781 | bucket++; 782 | } else { 783 | bucket += (Z_LVAL_P(item) * -1); 784 | } 785 | } 786 | } ZEND_HASH_FOREACH_END(); 787 | 788 | hdr_reset_internal_counters(hdr); 789 | hdr->normalizing_index_offset = 0; 790 | hdr->conversion_ratio = 1.0; 791 | 792 | return; 793 | } 794 | 795 | value = zend_hash_str_find(Z_ARRVAL_P(import), "c", strlen("c")); 796 | 797 | // version 1 format 798 | if (value != NULL && Z_TYPE_P(value) == IS_ARRAY) { 799 | count = zend_hash_num_elements(Z_ARRVAL_P(value)); 800 | 801 | res = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &hdr); 802 | 803 | if (res == 0) { 804 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 805 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 806 | h->histogram = hdr; 807 | } else if (res == EINVAL) { 808 | php_error_docref(NULL, E_WARNING, "Lowest trackable value has to be >= 1."); 809 | 810 | RETURN_FALSE; 811 | } else if (res == ENOMEM) { 812 | php_error_docref(NULL, E_WARNING, "Memory error in hdr_init allocation."); 813 | 814 | RETURN_FALSE; 815 | } 816 | 817 | for (i = 0; i < skipped; i++) { 818 | if (i < hdr->counts_len) { 819 | hdr->counts[i] = 0; 820 | } 821 | } 822 | 823 | for (i = 0; i < count; i++) { 824 | if ((item = zend_hash_index_find(Z_ARRVAL_P(value), i)) != NULL) { 825 | bucket = i + skipped; 826 | if (bucket < hdr->counts_len) { 827 | convert_to_long_ex(item); 828 | if (Z_LVAL_P(item) > 0) { 829 | hdr->counts[bucket] = Z_LVAL_P(item); 830 | } 831 | } 832 | } 833 | } 834 | 835 | hdr_reset_internal_counters(hdr); 836 | hdr->normalizing_index_offset = 0; 837 | hdr->conversion_ratio = 1.0; 838 | 839 | return; 840 | } 841 | 842 | value = zend_hash_str_find(Z_ARRVAL_P(import), "b", strlen("b")); 843 | 844 | // version 2 format 845 | if (value != NULL && Z_TYPE_P(value) == IS_ARRAY) { 846 | res = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &hdr); 847 | 848 | if (res == 0) { 849 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 850 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 851 | h->histogram = hdr; 852 | } else if (res == EINVAL) { 853 | php_error_docref(NULL, E_WARNING, "Lowest trackable value has to be >= 1."); 854 | 855 | RETURN_FALSE; 856 | } else if (res == ENOMEM) { 857 | php_error_docref(NULL, E_WARNING, "Memory error in hdr_init allocation."); 858 | 859 | RETURN_FALSE; 860 | } 861 | 862 | zend_string *key; 863 | zend_ulong num_key; 864 | ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(value), num_key, key, item) { 865 | if (!key) { 866 | if (num_key < hdr->counts_len) { 867 | convert_to_long_ex(item); 868 | if (Z_LVAL_P(item) > 0) { 869 | hdr->counts[num_key] = Z_LVAL_P(item); 870 | } 871 | } 872 | } 873 | } ZEND_HASH_FOREACH_END(); 874 | 875 | hdr_reset_internal_counters(hdr); 876 | hdr->normalizing_index_offset = 0; 877 | hdr->conversion_ratio = 1.0; 878 | } else { 879 | php_error_docref(NULL, E_WARNING, "Missing counts (c) or bucket (b) key or not arrays."); 880 | RETURN_FALSE; 881 | } 882 | } 883 | 884 | PHP_FUNCTION(hdr_base64_encode) 885 | { 886 | zval *zhdr; 887 | 888 | ZEND_PARSE_PARAMETERS_START(1, 1) 889 | Z_PARAM_OBJECT_OF_CLASS(zhdr, php_HdrHistogram_Histogram_ce); 890 | ZEND_PARSE_PARAMETERS_END(); 891 | 892 | struct hdr_histogram *hdr = php_hdrhistogram_histogram_from_object(Z_OBJ_P(zhdr))->histogram; 893 | 894 | char *result = NULL; 895 | 896 | if (hdr_log_encode(hdr, &result) != 0) { 897 | php_error_docref(NULL, E_WARNING, "Cannot encode histogram"); 898 | 899 | RETURN_FALSE; 900 | } 901 | 902 | RETVAL_STRING(result); 903 | free(result); 904 | } 905 | 906 | PHP_FUNCTION(hdr_base64_decode) 907 | { 908 | zend_string *data; 909 | 910 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &data) == FAILURE) { 911 | RETURN_FALSE; 912 | } 913 | 914 | struct hdr_histogram *hdr = NULL; 915 | 916 | if (hdr_log_decode(&hdr, ZSTR_VAL(data), ZSTR_LEN(data)) != 0) { 917 | php_error_docref(NULL, E_WARNING, "Cannot decode histogram"); 918 | 919 | RETURN_FALSE; 920 | } 921 | 922 | object_init_ex(return_value, php_HdrHistogram_Histogram_ce); 923 | struct php_hdrhistogram_histogram *h = php_hdrhistogram_histogram_from_object(Z_OBJ_P(return_value)); 924 | h->histogram = hdr; 925 | } 926 | --------------------------------------------------------------------------------