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

     1  import { Flamebearer } from '@pyroscope/models/src';
     2  
     3  export function isSameFlamebearer(
     4    prevFlame: Flamebearer,
     5    currFlame: Flamebearer
     6  ) {
     7    // We first compare simple fields, since they are faster
     8    if (prevFlame.format !== currFlame.format) {
     9      return false;
    10    }
    11  
    12    if (prevFlame.numTicks !== currFlame.numTicks) {
    13      return false;
    14    }
    15  
    16    if (prevFlame.sampleRate !== currFlame.sampleRate) {
    17      return false;
    18    }
    19  
    20    if (prevFlame.units !== currFlame.units) {
    21      return false;
    22    }
    23  
    24    if (prevFlame.names?.length !== currFlame?.names.length) {
    25      return false;
    26    }
    27  
    28    if (prevFlame.levels.length !== currFlame.levels.length) {
    29      return false;
    30    }
    31  
    32    // Most likely names is smaller, so let's start with it
    33    // Are all names the same?
    34    if (
    35      !prevFlame.names.every((a, i) => {
    36        return a === currFlame.names[i];
    37      })
    38    ) {
    39      return false;
    40    }
    41  
    42    if (!areLevelsTheSame(prevFlame.levels, currFlame.levels)) {
    43      return false;
    44    }
    45  
    46    // Fallback in case new fields are added
    47    return (
    48      JSON.stringify({
    49        ...prevFlame,
    50        levels: undefined,
    51        names: undefined,
    52      }) ===
    53      JSON.stringify({
    54        ...currFlame,
    55        levels: undefined,
    56        names: undefined,
    57      })
    58    );
    59  }
    60  
    61  function areLevelsTheSame(
    62    l1: Flamebearer['levels'],
    63    l2: Flamebearer['levels']
    64  ) {
    65    if (l1.length !== l2.length) {
    66      return false;
    67    }
    68  
    69    // eslint-disable-next-line no-plusplus
    70    for (let i = 0; i < l1.length; i++) {
    71      if (l1[i].length !== l2[i].length) {
    72        return false;
    73      }
    74  
    75      // eslint-disable-next-line no-plusplus
    76      for (let j = 0; j < l1[i].length; j++) {
    77        if (l1[i][j] !== l2[i][j]) {
    78          return false;
    79        }
    80      }
    81    }
    82  
    83    return true;
    84  }