scaleSampleRates.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import {clampPercentRate} from 'sentry/views/settings/dynamicSampling/utils/clampNumer';
  2. interface ScalingItem {
  3. count: number;
  4. sampleRate: number;
  5. }
  6. /**
  7. * Scales the sample rates of items proportionally to their current sample rate.
  8. */
  9. export function scaleSampleRates<T extends ScalingItem>({
  10. items,
  11. sampleRate,
  12. }: {
  13. items: T[];
  14. sampleRate: number;
  15. }): {
  16. scaledItems: T[];
  17. } {
  18. const totalSpans = items.reduce((acc, item) => acc + item.count, 0);
  19. const oldSampleRate = items.reduce(
  20. (acc, item) => acc + item.sampleRate * (item.count / totalSpans),
  21. 0
  22. );
  23. if (sampleRate === oldSampleRate) {
  24. return {scaledItems: items};
  25. }
  26. if (
  27. oldSampleRate === 0 ||
  28. oldSampleRate === 1 ||
  29. sampleRate === 0 ||
  30. sampleRate === 1
  31. ) {
  32. return {
  33. scaledItems: items.map(item => ({
  34. ...item,
  35. sampleRate,
  36. })),
  37. };
  38. }
  39. const newSampled = totalSpans * sampleRate;
  40. let factor = sampleRate / oldSampleRate;
  41. let remainingTotal = totalSpans;
  42. let remainingSampleCount = newSampled;
  43. let remainingOldSampleCount = totalSpans * oldSampleRate;
  44. const sortedItems = items.toSorted((a, b) => a.count - b.count);
  45. const scaledItems: T[] = [];
  46. for (const item of sortedItems) {
  47. const newProjectRate = clampPercentRate(item.sampleRate * factor);
  48. const newProjectSampleCount = item.count * newProjectRate;
  49. remainingTotal -= item.count;
  50. remainingSampleCount -= newProjectSampleCount;
  51. remainingOldSampleCount -= item.count * item.sampleRate;
  52. const newTargetRate = remainingSampleCount / remainingTotal;
  53. const remainingTotalRef = remainingTotal;
  54. const remainingOldSampleRate = remainingOldSampleCount / remainingTotalRef;
  55. factor = newTargetRate / remainingOldSampleRate;
  56. scaledItems.push({
  57. ...item,
  58. sampleRate: newProjectRate,
  59. });
  60. }
  61. return {scaledItems};
  62. }