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.

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