etlrange.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package kubecost
  2. import (
  3. "fmt"
  4. "sync"
  5. "github.com/opencost/opencost/pkg/util/json"
  6. )
  7. // SetRange is a generic implementation of the SetRanges that act as containers. It covers the basic functionality that
  8. // is shared by the basic types but is meant to be extended by each implementation.
  9. type SetRange[T ETLSet] struct {
  10. lock sync.RWMutex
  11. sets []T
  12. }
  13. // Append attaches the given ETLSet to the end of the sets slice.
  14. // currently does not check that the window is correct.
  15. func (r *SetRange[T]) Append(that T) {
  16. if r == nil {
  17. return
  18. }
  19. r.lock.Lock()
  20. defer r.lock.Unlock()
  21. r.sets = append(r.sets, that)
  22. }
  23. // Each invokes the given function for each ETLSet in the SetRange
  24. func (r *SetRange[T]) Each(f func(int, T)) {
  25. if r == nil {
  26. return
  27. }
  28. for i, set := range r.sets {
  29. f(i, set)
  30. }
  31. }
  32. // Get retrieves the given index from the sets slice
  33. func (r *SetRange[T]) Get(i int) (T, error) {
  34. var set T
  35. if r == nil {
  36. return set, fmt.Errorf("SetRange: Get: is nil")
  37. }
  38. if i < 0 || i >= len(r.sets) {
  39. return set, fmt.Errorf("SetRange: Get: index out of range: %d", i)
  40. }
  41. r.lock.RLock()
  42. defer r.lock.RUnlock()
  43. return r.sets[i], nil
  44. }
  45. // Length returns the length of the sets slice
  46. func (r *SetRange[T]) Length() int {
  47. if r == nil || r.sets == nil {
  48. return 0
  49. }
  50. r.lock.RLock()
  51. defer r.lock.RUnlock()
  52. return len(r.sets)
  53. }
  54. // IsEmpty returns false if SetRange contains a single ETLSet that is not empty
  55. func (r *SetRange[T]) IsEmpty() bool {
  56. if r == nil || r.Length() == 0 {
  57. return true
  58. }
  59. r.lock.RLock()
  60. defer r.lock.RUnlock()
  61. for _, set := range r.sets {
  62. if !set.IsEmpty() {
  63. return false
  64. }
  65. }
  66. return true
  67. }
  68. // MarshalJSON converts SetRange to JSON
  69. func (r *SetRange[T]) MarshalJSON() ([]byte, error) {
  70. if r == nil {
  71. return json.Marshal([]T{})
  72. }
  73. r.lock.RLock()
  74. defer r.lock.RUnlock()
  75. return json.Marshal(r.sets)
  76. }