set.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package pricing
  2. import (
  3. "maps"
  4. "slices"
  5. "github.com/opencost/opencost/core/pkg/unit"
  6. )
  7. type PricingSet struct {
  8. Nodes []*NodePricing `json:"nodes" yaml:"nodes"`
  9. Volumes []*VolumePricing `json:"volumes" yaml:"volumes"`
  10. }
  11. func (ps *PricingSet) IsEmpty() bool {
  12. if ps == nil {
  13. return true
  14. }
  15. return len(ps.Nodes) == 0 && len(ps.Volumes) == 0
  16. }
  17. func (ps *PricingSet) Currencies() []unit.Currency {
  18. if ps == nil {
  19. return []unit.Currency{}
  20. }
  21. currencies := map[unit.Currency]struct{}{}
  22. for _, np := range ps.Nodes {
  23. for _, curr := range np.GetCurrencies() {
  24. currencies[curr] = struct{}{}
  25. }
  26. }
  27. for _, vp := range ps.Volumes {
  28. for _, curr := range vp.GetCurrencies() {
  29. currencies[curr] = struct{}{}
  30. }
  31. }
  32. return slices.Collect(maps.Keys(currencies))
  33. }
  34. // Sort sorts the pricing data to ensure deterministic serialization.
  35. // Sorted by: Provider, Region, <Instance/Volume>Type
  36. func (ps *PricingSet) Sort() {
  37. if ps == nil {
  38. return
  39. }
  40. // Sort nodes
  41. slices.SortFunc(ps.Nodes, func(a, b *NodePricing) int {
  42. // Compare by Provider
  43. if a.Properties.Provider != b.Properties.Provider {
  44. if a.Properties.Provider < b.Properties.Provider {
  45. return -1
  46. }
  47. return 1
  48. }
  49. // Compare by Region
  50. if a.Properties.Region != b.Properties.Region {
  51. if a.Properties.Region < b.Properties.Region {
  52. return -1
  53. }
  54. return 1
  55. }
  56. // Compare by InstanceType
  57. if a.Properties.InstanceType != b.Properties.InstanceType {
  58. if a.Properties.InstanceType < b.Properties.InstanceType {
  59. return -1
  60. }
  61. return 1
  62. }
  63. return 0
  64. })
  65. // Sort volumes
  66. slices.SortFunc(ps.Volumes, func(a, b *VolumePricing) int {
  67. // Compare by Provider
  68. if a.Properties.Provider != b.Properties.Provider {
  69. if a.Properties.Provider < b.Properties.Provider {
  70. return -1
  71. }
  72. return 1
  73. }
  74. // Compare by Region
  75. if a.Properties.Region != b.Properties.Region {
  76. if a.Properties.Region < b.Properties.Region {
  77. return -1
  78. }
  79. return 1
  80. }
  81. // Compare by VolumeType
  82. if a.Properties.VolumeType < b.Properties.VolumeType {
  83. return -1
  84. }
  85. if a.Properties.VolumeType > b.Properties.VolumeType {
  86. return 1
  87. }
  88. return 0
  89. })
  90. }