github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/packages/pyroscope-flamegraph/src/FlameGraph/decode.ts (about)

     1  import { Profile } from '@pyroscope/models/src';
     2  
     3  export function deltaDiffWrapperReverse(
     4    format: Profile['metadata']['format'],
     5    levels: Profile['flamebearer']['levels']
     6  ) {
     7    const mutableLevels = [...levels];
     8  
     9    function deltaDiff(
    10      lvls: Profile['flamebearer']['levels'],
    11      start: number,
    12      step: number
    13    ) {
    14      // eslint-disable-next-line no-restricted-syntax
    15      for (const level of lvls) {
    16        let total = 0;
    17        for (let i = start; i < level.length; i += step) {
    18          level[i] -= total;
    19          total += level[i] + level[i + 1];
    20        }
    21      }
    22    }
    23  
    24    if (format === 'double') {
    25      deltaDiff(mutableLevels, 0, 7);
    26      deltaDiff(mutableLevels, 3, 7);
    27    } else {
    28      deltaDiff(mutableLevels, 0, 4);
    29    }
    30  
    31    return mutableLevels;
    32  }
    33  
    34  export function deltaDiffWrapper(
    35    format: Profile['metadata']['format'],
    36    levels: Profile['flamebearer']['levels']
    37  ) {
    38    const mutableLevels = [...levels];
    39  
    40    function deltaDiff(
    41      lvls: Profile['flamebearer']['levels'],
    42      start: number,
    43      step: number
    44    ) {
    45      // eslint-disable-next-line no-restricted-syntax
    46      for (const level of lvls) {
    47        let prev = 0;
    48        for (let i = start; i < level.length; i += step) {
    49          level[i] += prev;
    50          prev = level[i] + level[i + 1];
    51        }
    52      }
    53    }
    54  
    55    if (format === 'double') {
    56      deltaDiff(mutableLevels, 0, 7);
    57      deltaDiff(mutableLevels, 3, 7);
    58    } else {
    59      deltaDiff(mutableLevels, 0, 4);
    60    }
    61  
    62    return mutableLevels;
    63  }
    64  
    65  /*
    66   * decodeLevels decodes an unecoded
    67   * It:
    68   * - expects input data to be not decoded (ie. not idempotent)
    69   * - mutates the 'flamebearer.levels' field in place
    70   */
    71  export function decodeFlamebearer(fb: Profile) {
    72    fb.flamebearer.levels = deltaDiffWrapper(
    73      fb.metadata.format,
    74      fb.flamebearer.levels
    75    );
    76  
    77    return fb;
    78  }