@@ -1705,17 +1705,23 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
1705
1705
return
1706
1706
}
1707
1707
1708
+ if len (n .exemplars ) == 1 {
1709
+ // When the number of exemplars is 1, then
1710
+ // replace the existing exemplar with the new exemplar.
1711
+ n .exemplars [0 ] = e
1712
+ return
1713
+ }
1714
+ // From this point on, the number of exemplars is greater than 1.
1715
+
1708
1716
// When the number of exemplars exceeds the limit, remove one exemplar.
1709
1717
var (
1710
- rIdx int // The index where to remove the old exemplar.
1711
-
1712
1718
ot = time .Now () // Oldest timestamp seen.
1713
1719
otIdx = - 1 // Index of the exemplar with the oldest timestamp.
1714
1720
1715
- md = - 1.0 // Logarithm of the delta of the closest pair of exemplars.
1716
- mdIdx = - 1 // Index of the older exemplar within the closest pair.
1717
- cLog float64 // Logarithm of the current exemplar.
1718
- pLog float64 // Logarithm of the previous exemplar.
1721
+ md = - 1.0 // Logarithm of the delta of the closest pair of exemplars.
1722
+ rIdx = - 1 // Index of the older exemplar within the closest pair and where we need to insert the new exemplar .
1723
+ cLog float64 // Logarithm of the current exemplar.
1724
+ pLog float64 // Logarithm of the previous exemplar.
1719
1725
)
1720
1726
1721
1727
for i , exemplar := range n .exemplars {
@@ -1726,7 +1732,7 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
1726
1732
}
1727
1733
1728
1734
// Find the index at which to insert new the exemplar.
1729
- if * e .Value <= * exemplar .Value && nIdx == - 1 {
1735
+ if nIdx == - 1 && * e .Value <= * exemplar .Value {
1730
1736
nIdx = i
1731
1737
}
1732
1738
@@ -1738,11 +1744,13 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
1738
1744
}
1739
1745
diff := math .Abs (cLog - pLog )
1740
1746
if md == - 1 || diff < md {
1747
+ // The closest exemplar pair is this: |exemplar.[i] - n.exemplars[i-1].Value| is minimal.
1748
+ // Choose the exemplar with the older timestamp for replacement.
1741
1749
md = diff
1742
1750
if n .exemplars [i ].Timestamp .AsTime ().Before (n .exemplars [i - 1 ].Timestamp .AsTime ()) {
1743
- mdIdx = i
1751
+ rIdx = i
1744
1752
} else {
1745
- mdIdx = i - 1
1753
+ rIdx = i - 1
1746
1754
}
1747
1755
}
1748
1756
@@ -1753,8 +1761,11 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
1753
1761
if nIdx == - 1 {
1754
1762
nIdx = len (n .exemplars )
1755
1763
}
1764
+ // Here, we have the following relationships:
1765
+ // n.exemplars[nIdx-1].Value < e.Value <= n.exemplars[nIdx].Value
1756
1766
1757
1767
if otIdx != - 1 && e .Timestamp .AsTime ().Sub (ot ) > time .Duration (ttl ) {
1768
+ // If the oldest exemplar has expired, then replace it with the new exemplar.
1758
1769
rIdx = otIdx
1759
1770
} else {
1760
1771
// In the previous for loop, when calculating the closest pair of exemplars,
@@ -1764,23 +1775,22 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
1764
1775
if nIdx > 0 {
1765
1776
diff := math .Abs (elog - math .Log (n .exemplars [nIdx - 1 ].GetValue ()))
1766
1777
if diff < md {
1778
+ // The closest exemplar pair is this: |e.Value - n.exemplars[nIdx-1].Value| is minimal.
1779
+ // Assume that the exemplar we are inserting has a newer timestamp. This is not always
1780
+ // true, due to concurrency, but it's a good enough approximation.
1767
1781
md = diff
1768
- mdIdx = nIdx
1769
- if n .exemplars [nIdx - 1 ].Timestamp .AsTime ().Before (e .Timestamp .AsTime ()) {
1770
- mdIdx = nIdx - 1
1771
- }
1782
+ rIdx = nIdx - 1
1772
1783
}
1773
1784
}
1774
1785
if nIdx < len (n .exemplars ) {
1775
1786
diff := math .Abs (math .Log (n .exemplars [nIdx ].GetValue ()) - elog )
1776
1787
if diff < md {
1777
- mdIdx = nIdx
1778
- if n . exemplars [ nIdx ]. Timestamp . AsTime (). Before ( e . Timestamp . AsTime ()) {
1779
- mdIdx = nIdx
1780
- }
1788
+ // The closest exemplar pair is this: |n.exemplars[ nIdx].Value - e.Value| is minimal.
1789
+ // Assume that the exemplar we are inserting has a newer timestamp. This is not always
1790
+ // true, due to concurrency, but it's a good enough approximation.
1791
+ rIdx = nIdx
1781
1792
}
1782
1793
}
1783
- rIdx = mdIdx
1784
1794
}
1785
1795
1786
1796
// Adjust the slice according to rIdx and nIdx.
0 commit comments