@@ -1705,17 +1705,23 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
17051705 return
17061706 }
17071707
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+
17081716 // When the number of exemplars exceeds the limit, remove one exemplar.
17091717 var (
1710- rIdx int // The index where to remove the old exemplar.
1711-
17121718 ot = time.Now() // Oldest timestamp seen.
17131719 otIdx = -1 // Index of the exemplar with the oldest timestamp.
17141720
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.
17191725 )
17201726
17211727 for i, exemplar := range n.exemplars {
@@ -1726,7 +1732,7 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
17261732 }
17271733
17281734 // 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 {
17301736 nIdx = i
17311737 }
17321738
@@ -1738,11 +1744,13 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
17381744 }
17391745 diff := math.Abs(cLog - pLog)
17401746 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.
17411749 md = diff
17421750 if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) {
1743- mdIdx = i
1751+ rIdx = i
17441752 } else {
1745- mdIdx = i - 1
1753+ rIdx = i - 1
17461754 }
17471755 }
17481756
@@ -1753,8 +1761,11 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
17531761 if nIdx == -1 {
17541762 nIdx = len(n.exemplars)
17551763 }
1764+ // Here, we have the following relationships:
1765+ // n.exemplars[nIdx-1].Value < e.Value <= n.exemplars[nIdx].Value
17561766
17571767 if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl {
1768+ // If the oldest exemplar has expired, then replace it with the new exemplar.
17581769 rIdx = otIdx
17591770 } else {
17601771 // In the previous for loop, when calculating the closest pair of exemplars,
@@ -1764,23 +1775,22 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) {
17641775 if nIdx > 0 {
17651776 diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue()))
17661777 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.
17671781 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
17721783 }
17731784 }
17741785 if nIdx < len(n.exemplars) {
17751786 diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog)
17761787 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
17811792 }
17821793 }
1783- rIdx = mdIdx
17841794 }
17851795
17861796 // Adjust the slice according to rIdx and nIdx.
0 commit comments