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.

targets.go 1.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright (c) 2021 Shivaram Lingamneni <slingamn@cs.stanford.edu>
  2. // released under the MIT license
  3. package history
  4. import (
  5. "sort"
  6. "time"
  7. )
  8. type TargetListing struct {
  9. CfName string
  10. Time time.Time
  11. }
  12. // Merge `base`, a paging window of targets, with `extras` (the target entries
  13. // for all joined channels).
  14. func MergeTargets(base []TargetListing, extra []TargetListing, start, end time.Time, limit int) (results []TargetListing) {
  15. if len(extra) == 0 {
  16. return base
  17. }
  18. SortCorrespondents(extra)
  19. start, end, ascending := MinMaxAsc(start, end, time.Time{})
  20. predicate := func(t time.Time) bool {
  21. return (start.IsZero() || start.Before(t)) && (end.IsZero() || end.After(t))
  22. }
  23. prealloc := len(base) + len(extra)
  24. if limit < prealloc {
  25. prealloc = limit
  26. }
  27. results = make([]TargetListing, 0, prealloc)
  28. if !ascending {
  29. ReverseCorrespondents(base)
  30. ReverseCorrespondents(extra)
  31. }
  32. for len(results) < limit {
  33. if len(extra) != 0 {
  34. if !predicate(extra[0].Time) {
  35. extra = extra[1:]
  36. continue
  37. }
  38. if len(base) != 0 {
  39. if base[0].Time.Before(extra[0].Time) == ascending {
  40. results = append(results, base[0])
  41. base = base[1:]
  42. } else {
  43. results = append(results, extra[0])
  44. extra = extra[1:]
  45. }
  46. } else {
  47. results = append(results, extra[0])
  48. extra = extra[1:]
  49. }
  50. } else if len(base) != 0 {
  51. results = append(results, base[0])
  52. base = base[1:]
  53. } else {
  54. break
  55. }
  56. }
  57. if !ascending {
  58. ReverseCorrespondents(results)
  59. }
  60. return
  61. }
  62. func ReverseCorrespondents(results []TargetListing) {
  63. // lol, generics when?
  64. for i, j := 0, len(results)-1; i < j; i, j = i+1, j-1 {
  65. results[i], results[j] = results[j], results[i]
  66. }
  67. }
  68. func SortCorrespondents(list []TargetListing) {
  69. sort.Slice(list, func(i, j int) bool {
  70. return list[i].Time.Before(list[j].Time)
  71. })
  72. }