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.

56 lines
1.2 KiB

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