Skip to content

Commit

Permalink
APCng storage - avoid worst-case memory usage in buildPermutationTree
Browse files Browse the repository at this point in the history
  • Loading branch information
Princemachiavelli committed Jun 21, 2023
1 parent 82e42b5 commit 317ee2c
Showing 1 changed file with 14 additions and 24 deletions.
38 changes: 14 additions & 24 deletions src/Prometheus/Storage/APCng.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,31 +414,22 @@ private function metaData(array $data): array
* [15] => ['/metrics', 'get', 'fail'], [16] => ['/metrics', 'post', 'success'], [17] => ['/metrics', 'post', 'fail']
* @param array<string> $labelNames
* @param array<array> $labelValues
* @return array<array>
* @return Generator<array>
*/
private function buildPermutationTree(array $labelNames, array $labelValues): array /** @phpstan-ignore-line */
{
$treeRowCount = count(array_keys($labelNames));
$numElements = 1;
$treeInfo = [];
for ($i = $treeRowCount - 1; $i >= 0; $i--) {
$treeInfo[$i]['numInRow'] = count($labelValues[$i]);
$numElements *= $treeInfo[$i]['numInRow'];
$treeInfo[$i]['numInTree'] = $numElements;
}

$map = array_fill(0, $numElements, []);
for ($row = 0; $row < $treeRowCount; $row++) {
$col = $i = 0;
while ($i < $numElements) {
$val = $labelValues[$row][$col];
$map[$i] = array_merge($map[$i], array($val));
if (++$i % ($treeInfo[$row]['numInTree'] / $treeInfo[$row]['numInRow']) == 0) {
$col = ++$col % $treeInfo[$row]['numInRow'];
}
private function buildPermutationTree(array $labelValues): \Generator /** @phpstan-ignore-line */
{
if($labelValues){
$lastIndex = array_key_last($labelValues);
if($currentValue = array_pop($labelValues)){
foreach($this->buildPermutationTree($labelValues) as $prefix){
foreach($currentValue as $value){
yield $prefix + [$lastIndex => $value];
}
}
}
} else {
yield [];
}
return $map;
}

/**
Expand Down Expand Up @@ -539,10 +530,9 @@ private function getValues(string $type, array $metaData): array /** @phpstan-ig
if (isset($metaData['buckets'])) {
$metaData['buckets'][] = 'sum';
$labels[] = $metaData['buckets'];
$metaData['labelNames'][] = '__histogram_buckets';
}

$labelValuesList = $this->buildPermutationTree($metaData['labelNames'], $labels);
$labelValuesList = $this->buildPermutationTree($labels);
unset($labels);
$histogramBucket = '';
foreach ($labelValuesList as $labelValues) {
Expand Down

0 comments on commit 317ee2c

Please sign in to comment.