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 }