Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-versions: [7.4, 8.0, 8.1, 8.2, 8.3, 8.4]
php-versions: [ 7.4, 8.0, 8.1, 8.2, 8.3, 8.4 ]

steps:
- name: Checkout code
Expand All @@ -26,6 +26,9 @@ jobs:
php-version: ${{ matrix.php-versions }}
tools: composer

- name: Validate composer.json and composer.lock
run: composer validate --no-check-all --no-check-publish

- name: Install dependencies
run: composer install --prefer-dist --no-progress

Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"email": "ben.poulson@perfbase.com"
}
],
"scripts": {
"lint": "composer run-script phpstan && composer run-script test",
"test": "phpunit",
"phpstan": "phpstan analyse --memory-limit=2G"
},
"require": {
"php": ">=7.4 <8.5",
"ext-curl": "*",
Expand Down
11 changes: 0 additions & 11 deletions src/Exception/PerfbaseApiKeyMissingException.php

This file was deleted.

8 changes: 8 additions & 0 deletions src/Exception/PerfbaseEncodingException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Perfbase\SDK\Exception;

class PerfbaseEncodingException extends PerfbaseException
{

}
14 changes: 2 additions & 12 deletions src/Exception/PerfbaseException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,12 @@
namespace Perfbase\SDK\Exception;

use Exception;
use Perfbase\SDK\Utils\TranslationUtil;
use Throwable;

class PerfbaseException extends Exception
{

/**
* @param string $translation
* @param array<scalar> $values
* @param int $code
* @param Throwable|null $previous
* @throws PerfbaseTranslationNotFoundException
*/
public function __construct(string $translation, array $values = [], int $code = 0, ?Throwable $previous = null)
public function __construct(string $message = "")
{
$message = TranslationUtil::get($translation, $values);
parent::__construct($message, $code, $previous);
parent::__construct($message);
}
}
11 changes: 0 additions & 11 deletions src/Exception/PerfbaseExtensionMissingException.php

This file was deleted.

8 changes: 8 additions & 0 deletions src/Exception/PerfbaseInvalidConfigException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Perfbase\SDK\Exception;

class PerfbaseInvalidConfigException extends PerfbaseException
{

}
11 changes: 0 additions & 11 deletions src/Exception/PerfbaseNonScalarMetaDataException.php

This file was deleted.

5 changes: 1 addition & 4 deletions src/Exception/PerfbaseStateException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@

class PerfbaseStateException extends PerfbaseException
{
public function __construct(string $translation = 'state_exception', array $values = [])
{
parent::__construct($translation, $values);
}

}
11 changes: 0 additions & 11 deletions src/Exception/PerfbaseTranslationNotFoundException.php

This file was deleted.

6 changes: 3 additions & 3 deletions src/Http/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use GuzzleHttp\Client as GuzzleClient;
use JsonException;
use Perfbase\SDK\Config;
use Perfbase\SDK\Exception\PerfbaseApiKeyMissingException;
use Perfbase\SDK\Exception\PerfbaseInvalidConfigException;
use Throwable;

class ApiClient
Expand All @@ -29,12 +29,12 @@ class ApiClient
private GuzzleClient $httpClient;

/**
* @throws PerfbaseApiKeyMissingException
* @throws PerfbaseInvalidConfigException
*/
public function __construct(Config $config)
{
if (!is_string($config->api_key)) {
throw new PerfbaseApiKeyMissingException();
throw new PerfbaseInvalidConfigException();
}

$this->config = $config;
Expand Down
4 changes: 2 additions & 2 deletions src/Perfbase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Perfbase\SDK;

use Perfbase\SDK\Exception\PerfbaseApiKeyMissingException;
use Perfbase\SDK\Exception\PerfbaseInvalidConfigException;
use Perfbase\SDK\Exception\PerfbaseStateException;
use Perfbase\SDK\Tracing\TraceInstance;
use Perfbase\SDK\Utils\ExtensionUtils;
Expand Down Expand Up @@ -53,7 +53,7 @@ public static function hasInstance(): bool
* @param Config $config
* @return TraceInstance
* @throws PerfbaseStateException
* @throws PerfbaseApiKeyMissingException
* @throws PerfbaseInvalidConfigException
*/
public static function createInstance(Config $config): TraceInstance
{
Expand Down
130 changes: 130 additions & 0 deletions src/Tracing/Compression/Compressor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace Perfbase\SDK\Tracing\Compression;

class Compressor
{
/**
* Glossary of atomic tokens (class names, method names, etc.) mapped to an integer ID. We only store them once.
* @var array<int, string>
*/
public array $glossary = [];

/**
* Glossary map.
* @var array<string, int>
*/
public array $glossaryMap = [];

/**
* The next glossary ID to use.
* @var int
*/
public int $nextGlossaryId = 0;

/**
* The root node. It has an array of children (keyed "c"), each child has:
* 'k' => int[] (array of glossary IDs for this segment),
* 'c' => array of children,
* 'v' => value if it's a leaf
* @var array<mixed>
*/
public array $map = ['c' => []];

/**
* Return the glossary ID for a given string token.
* @param string $token
* @return int
*/
private function getGlossaryId(string $token): int
{
if (isset($this->glossaryMap[$token])) {
return $this->glossaryMap[$token];
}
$id = $this->nextGlossaryId++;
$this->glossary[$id] = $token;
$this->glossaryMap[$token] = $id;
return $id;
}

/**
* Insert a single key => value into the trie.
* This method has a recursive function call, so phpstan gets really confused.
* @param array<string,mixed> $node Current trie node
* @param array<array<int>> $segmentsOfSegments Each element = array of integer IDs for that segment
* @param array<int|string> $value
*/
private function trieInsert(array &$node, array $segmentsOfSegments, array $value): void
{
// If we’ve consumed all segments, store the value here
if (!$segmentsOfSegments) {
$node['v'] = $value;
return;
}

// Grab the next segment (array of integer token IDs)
$currentSeg = array_shift($segmentsOfSegments);

// If no children yet, add an empty array
if (!isset($node['c'])) {
$node['c'] = [];
}
// Child array. We'll see if there's a child with the same `k`
// @phpstan-ignore-next-line
foreach ($node['c'] as &$child) {
// @phpstan-ignore-next-line
if (isset($child['k']) && $child['k'] === $currentSeg) {
// Found a match; recurse
// @phpstan-ignore-next-line
$this->trieInsert($child, $segmentsOfSegments, $value);
return;
}
}
// No child with these tokens => create a new child
$newChild = [
'k' => $currentSeg, // array of integers
'c' => []
];

// @phpstan-ignore-next-line
$node['c'][] = $newChild;

// Insert value deeper
// @phpstan-ignore-next-line
$this->trieInsert($node['c'][count($node['c']) - 1], $segmentsOfSegments, $value);
}

/**
* Compress the data.
* @param array<string, array<int|string>> $data
* @return array<mixed>
*/
public function execute(array $data): array
{
/** Build the trie from all data */
foreach ($data as $longKey => $val) {
// 1) Split on '~' => segments
$segments = explode('~', $longKey);

// 2) For each segment, split on '::', map each token to a glossary ID
$segmentsOfSegments = [];
foreach ($segments as $segment) {
$subParts = explode('::', $segment);
$subPartIds = array_map([$this, 'getGlossaryId'], $subParts);
$segmentsOfSegments[] = $subPartIds;
}

// 3) Insert into trie
// @phpstan-ignore-next-line
$this->trieInsert($this->map, $segmentsOfSegments, $val);
}

return [
'compressor' => 'trie',
'data' => [
'glossary' => $this->glossary,
'map' => $this->map
]
];
}
}
Loading
Loading