You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

46 lines
988 B

  1. package state
  2. import (
  3. "sort"
  4. "time"
  5. )
  6. // weightedTime for computing a median.
  7. type weightedTime struct {
  8. Time time.Time
  9. Weight int64
  10. }
  11. // newWeightedTime with time and weight.
  12. func newWeightedTime(time time.Time, weight int64) *weightedTime {
  13. return &weightedTime{
  14. Time: time,
  15. Weight: weight,
  16. }
  17. }
  18. // weightedMedian computes weighted median time for a given array of WeightedTime and the total voting power.
  19. func weightedMedian(weightedTimes []*weightedTime, totalVotingPower int64) (res time.Time) {
  20. median := totalVotingPower / 2
  21. sort.Slice(weightedTimes, func(i, j int) bool {
  22. if weightedTimes[i] == nil {
  23. return false
  24. }
  25. if weightedTimes[j] == nil {
  26. return true
  27. }
  28. return weightedTimes[i].Time.UnixNano() < weightedTimes[j].Time.UnixNano()
  29. })
  30. for _, weightedTime := range weightedTimes {
  31. if weightedTime != nil {
  32. if median <= weightedTime.Weight {
  33. res = weightedTime.Time
  34. break
  35. }
  36. median -= weightedTime.Weight
  37. }
  38. }
  39. return
  40. }