func (m *WindowlessMovingPercentile) Update(operation func(value float64) float64) {
	m.mu.Lock()
	defer m.mu.Unlock()
	newValue, _ := m.add(m.value)
	m.value = operation(newValue)
}
Update will update the value given an operation function
package measurements
import (
	"fmt"
	"sync"
)
type WindowlessMovingPercentile struct {
	p            float64
	deltaInitial float64
	value      float64
	delta      float64
	deltaState *SimpleMovingVariance
	seenCount int
	mu sync.RWMutex
}
func NewWindowlessMovingPercentile(
	p float64,  
	deltaInitial float64,
	movingAvgAlphaAvg float64,
	movingVarianceAlphaVar float64,
) (*WindowlessMovingPercentile, error) {
	if p <= 0 || p >= 1 {
		return nil, fmt.Errorf("p must be between (0,1)")
	}
	variance, err := NewSimpleMovingVariance(movingAvgAlphaAvg, movingVarianceAlphaVar)
	if err != nil {
		return nil, err
	}
	return &WindowlessMovingPercentile{
		p:            p,
		deltaInitial: deltaInitial,
		delta:        deltaInitial,
		deltaState:   variance,
	}, nil
}
func (m *WindowlessMovingPercentile) Add(value float64) (float64, bool) {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.add(value)
}
func (m *WindowlessMovingPercentile) add(value float64) (float64, bool) {
	changed := false
	if m.seenCount < 2 {
		m.seenCount++
	}
	originalDelta := m.delta
	stdev, _ := m.deltaState.Add(value)
	if m.seenCount >= 2 {
		m.delta = m.deltaInitial * stdev
		if m.delta != originalDelta {
			changed = true
		}
	}
	newValue := float64(m.value)
	if m.seenCount == 1 {
		newValue = value
		changed = true
	} else if value < m.value {
		newValue = m.value - m.delta/m.p
	} else if value > m.value {
		newValue = m.value + m.delta/(1-m.p)
	}
	if newValue != m.value {
		changed = true
	}
	m.value = newValue
	return m.value, changed
}
func (m *WindowlessMovingPercentile) Get() float64 {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.value
}
func (m *WindowlessMovingPercentile) Reset() {
	m.mu.Lock()
	m.value = 0
	m.seenCount = 0
	m.mu.Unlock()
}