Skip to content

Commit 784c03a

Browse files
committed
pkg/status: use conditions map instead of slice
1 parent 8db004b commit 784c03a

File tree

2 files changed

+72
-39
lines changed

2 files changed

+72
-39
lines changed

pkg/status/conditions.go

+52-39
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,19 @@ func (c Condition) IsUnknown() bool {
7373
return c.Status == corev1.ConditionUnknown
7474
}
7575

76-
// DeepCopyInto copies in into out.
77-
func (in *Condition) DeepCopyInto(out *Condition) {
78-
*out = *in
76+
// DeepCopy returns a deep copy of the condition
77+
func (c *Condition) DeepCopy() *Condition {
78+
if c == nil {
79+
return nil
80+
}
81+
out := *c
82+
return &out
7983
}
8084

8185
// Conditions is a set of Condition instances.
82-
type Conditions []Condition
86+
//
87+
// +kubebuilder:validation:Type=array
88+
type Conditions map[ConditionType]Condition
8389

8490
// NewConditions initializes a set of conditions with the given list of
8591
// conditions.
@@ -95,10 +101,8 @@ func NewConditions(conds ...Condition) Conditions {
95101
// ConditionType. If found, it returns `condition.IsTrue()`. If not found,
96102
// it returns false.
97103
func (conditions Conditions) IsTrue(t ConditionType) bool {
98-
for _, condition := range conditions {
99-
if condition.Type == t {
100-
return condition.IsTrue()
101-
}
104+
if condition, ok := conditions[t]; ok {
105+
return condition.IsTrue()
102106
}
103107
return false
104108
}
@@ -107,10 +111,8 @@ func (conditions Conditions) IsTrue(t ConditionType) bool {
107111
// ConditionType. If found, it returns `condition.IsFalse()`. If not found,
108112
// it returns false.
109113
func (conditions Conditions) IsFalse(t ConditionType) bool {
110-
for _, condition := range conditions {
111-
if condition.Type == t {
112-
return condition.IsFalse()
113-
}
114+
if condition, ok := conditions[t]; ok {
115+
return condition.IsFalse()
114116
}
115117
return false
116118
}
@@ -119,10 +121,8 @@ func (conditions Conditions) IsFalse(t ConditionType) bool {
119121
// ConditionType. If found, it returns `condition.IsUnknown()`. If not found,
120122
// it returns true.
121123
func (conditions Conditions) IsUnknown(t ConditionType) bool {
122-
for _, condition := range conditions {
123-
if condition.Type == t {
124-
return condition.IsUnknown()
125-
}
124+
if condition, ok := conditions[t]; ok {
125+
return condition.IsUnknown()
126126
}
127127
return true
128128
}
@@ -131,34 +131,31 @@ func (conditions Conditions) IsUnknown(t ConditionType) bool {
131131
// condition. It returns a boolean value indicating whether the set condition
132132
// is new or was a change to the existing condition with the same type.
133133
func (conditions *Conditions) SetCondition(newCond Condition) bool {
134-
if conditions == nil {
135-
*conditions = make([]Condition, 0)
134+
if conditions == nil || *conditions == nil {
135+
*conditions = make(map[ConditionType]Condition)
136136
}
137137
newCond.LastTransitionTime = metav1.Time{Time: clock.Now()}
138-
for i, condition := range *conditions {
139-
if condition.Type == newCond.Type {
140-
if condition.Status == newCond.Status {
141-
newCond.LastTransitionTime = condition.LastTransitionTime
142-
}
143-
changed := condition.Status != newCond.Status ||
144-
condition.Reason != newCond.Reason ||
145-
condition.Message != newCond.Message
146-
(*conditions)[i] = newCond
147-
return changed
138+
139+
if condition, ok := (*conditions)[newCond.Type]; ok {
140+
if condition.Status == newCond.Status {
141+
newCond.LastTransitionTime = condition.LastTransitionTime
148142
}
143+
changed := condition.Status != newCond.Status ||
144+
condition.Reason != newCond.Reason ||
145+
condition.Message != newCond.Message
146+
(*conditions)[newCond.Type] = newCond
147+
return changed
149148
}
150-
*conditions = append(*conditions, newCond)
149+
(*conditions)[newCond.Type] = newCond
151150
return true
152151
}
153152

154153
// GetCondition searches the set of conditions for the condition with the given
155154
// ConditionType and returns it. If the matching condition is not found,
156155
// GetCondition returns nil.
157156
func (conditions Conditions) GetCondition(t ConditionType) *Condition {
158-
for _, condition := range conditions {
159-
if condition.Type == t {
160-
return &condition
161-
}
157+
if condition, ok := conditions[t]; ok {
158+
return &condition
162159
}
163160
return nil
164161
}
@@ -167,21 +164,37 @@ func (conditions Conditions) GetCondition(t ConditionType) *Condition {
167164
// the conditions set. If no condition with that type is found, RemoveCondition
168165
// returns without performing any action.
169166
func (conditions *Conditions) RemoveCondition(t ConditionType) bool {
170-
for i, condition := range *conditions {
171-
if condition.Type == t {
172-
*conditions = append((*conditions)[:i], (*conditions)[i+1:]...)
173-
return true
174-
}
167+
if conditions == nil || *conditions == nil {
168+
return false
169+
}
170+
if _, ok := (*conditions)[t]; ok {
171+
delete(*conditions, t)
172+
return true
175173
}
176174
return false
177175
}
178176

179177
// MarshalJSON marshals the set of conditions as a JSON array, sorted by
180178
// condition type.
181179
func (conditions Conditions) MarshalJSON() ([]byte, error) {
182-
conds := []Condition(conditions)
180+
conds := []Condition{}
181+
for _, condition := range conditions {
182+
conds = append(conds, condition)
183+
}
183184
sort.Slice(conds, func(a, b int) bool {
184185
return conds[a].Type < conds[b].Type
185186
})
186187
return json.Marshal(conds)
187188
}
189+
190+
func (conditions *Conditions) UnmarshalJSON(data []byte) error {
191+
*conditions = make(map[ConditionType]Condition)
192+
conds := []Condition{}
193+
if err := json.Unmarshal(data, &conds); err != nil {
194+
return err
195+
}
196+
for _, condition := range conds {
197+
(*conditions)[condition.Type] = condition
198+
}
199+
return nil
200+
}

pkg/status/conditions_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,26 @@ func withLastTransitionTime(c Condition, t time.Time) Condition {
6969
return c
7070
}
7171

72+
func TestConditionDeepCopy(t *testing.T) {
73+
var n *Condition
74+
assert.Nil(t, n.DeepCopy())
75+
76+
a := generateCondition("A", corev1.ConditionTrue)
77+
aCopy := a.DeepCopy()
78+
if &a == aCopy {
79+
t.Errorf("Expected and actual point to the same object: %p %#v", &a, &a)
80+
}
81+
if &a.Status == &aCopy.Status {
82+
t.Errorf("Expected and actual point to the same object: %p %#v", &a.Status, &a.Status)
83+
}
84+
if &a.Reason == &aCopy.Reason {
85+
t.Errorf("Expected and actual point to the same object: %p %#v", &a.Reason, &a.Reason)
86+
}
87+
if &a.Message == &aCopy.Message {
88+
t.Errorf("Expected and actual point to the same object: %p %#v", &a.Message, &a.Message)
89+
}
90+
}
91+
7292
func TestConditionsSetEmpty(t *testing.T) {
7393
conditions := initConditions()
7494

0 commit comments

Comments
 (0)