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 }