-
Notifications
You must be signed in to change notification settings - Fork 0
/
reconcile_containers.go
172 lines (138 loc) · 4.47 KB
/
reconcile_containers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package main
import (
"log"
"sort"
)
type AddItemFunc func(string, interface{})
type UpdateItemFunc func(string, interface{})
type ItemEqualFunc func(interface{}, interface{}) bool
type RemoveItemFunc func(string)
// ReconcileMaps compares two maps; one with old data and one with new data and calls the various argument functions reflecting what operations are necessary to transform the old map into the new.
func ReconcileMaps(oldMap map[string]interface{}, newMap map[string]interface{}, addItem AddItemFunc, updateItem UpdateItemFunc, removeItem RemoveItemFunc, itemsAreEqual ItemEqualFunc) bool {
changesMade := false
var oldKeys []string
var newKeys []string
for key := range oldMap {
oldKeys = append(oldKeys, key)
}
sort.Strings(oldKeys)
for key := range newMap {
newKeys = append(newKeys, key)
}
sort.Strings(newKeys)
newKeyIndex := 0
oldKeyIndex := 0
for {
// if there are no more old keys, the remaining new keys need to be added
if oldKeyIndex >= len(oldKeys) {
break
}
// If there are no more new keys, the remaining old keys need to be removed.
if newKeyIndex >= len(newKeys) {
break
}
oldKey := oldKeys[oldKeyIndex]
newKey := newKeys[newKeyIndex]
log.Printf("COMPARING old key '%s' with new key '%s'\n", oldKey, newKey)
if oldKey == newKey {
// Keys are the same, see if the values are the same
oldValue := oldMap[oldKey]
newValue := newMap[oldKey]
if !itemsAreEqual(oldValue, newValue) {
// Value changed
updateItem(oldKey, newValue)
log.Printf("COMPARE: Updating [%s] = %s", oldKey, newValue.(string))
changesMade = true
} else {
log.Printf("COMPARE: No change to [%s] = %s", oldKey, newValue.(string))
}
newKeyIndex++
oldKeyIndex++
} else if oldKey < newKey {
// 'oldKey' was removed
oldValue := oldMap[oldKey].(string)
removeItem(oldKey)
log.Printf("COMPARE: Removing [%s] = %s", oldKey, oldValue)
changesMade = true
oldKeyIndex++
} else {
// 'newKey' was added
newValue := newMap[newKey]
addItem(newKey, newValue)
log.Printf("COMPARE: Adding [%s] = %s", newKey, newValue.(string))
newKeyIndex++
changesMade = true
}
}
// Remove any remaining old keys
for ; oldKeyIndex < len(oldKeys); oldKeyIndex++ {
oldKey := oldKeys[oldKeyIndex]
oldValue := oldMap[oldKey].(string)
removeItem(oldKey)
log.Printf("COMPARE: Removing at end [%s] = %s", oldKey, oldValue)
changesMade = true
}
// Add any remaining new keys
for ; newKeyIndex < len(newKeys); newKeyIndex++ {
newKey := newKeys[newKeyIndex]
newValue := newMap[newKey]
addItem(newKey, newValue)
log.Printf("COMPARE: Adding at end [%s] = %s", newKey, newValue.(string))
changesMade = true
}
return changesMade
}
type AddSliceItemFunc func(string)
type RemoveSliceItemFunc func(string)
// ReconcileSlices compares two slices; one with old data and one with new data and calls the various argument functions reflecting what operations are necessary to transform the old slice into the new.
func ReconcileSlices(oldSlice []string, newSlice []string, addItem AddSliceItemFunc, removeItem RemoveSliceItemFunc) bool {
changesMade := false
sort.Strings(oldSlice)
sort.Strings(newSlice)
newSliceIndex := 0
oldSliceIndex := 0
for {
// if there are no more old values, the remaining new values need to be added
if oldSliceIndex >= len(oldSlice) {
break
}
// If there are no more new values, the remaining old values need to be removed.
if newSliceIndex >= len(newSlice) {
break
}
oldValue := oldSlice[oldSliceIndex]
newValue := newSlice[newSliceIndex]
log.Printf("COMPARING old value '%s' with new value '%s'\n", oldValue, newValue)
if oldValue == newValue {
newSliceIndex++
oldSliceIndex++
} else if oldValue < newValue {
// 'oldValue' was removed
removeItem(oldValue)
log.Printf("COMPARE: Removing [%s]", oldValue)
changesMade = true
oldSliceIndex++
} else {
// 'newValue' was added
addItem(newValue)
log.Printf("COMPARE: Adding [%s]", newValue)
newSliceIndex++
changesMade = true
}
}
// Remove any remaining old values
for ; oldSliceIndex < len(oldSlice); oldSliceIndex++ {
oldValue := oldSlice[oldSliceIndex]
removeItem(oldValue)
log.Printf("COMPARE: Removing [%s]", oldValue)
changesMade = true
}
// Add any remaining new values
for ; newSliceIndex < len(newSlice); newSliceIndex++ {
newValue := newSlice[newSliceIndex]
addItem(newValue)
log.Printf("COMPARE: Adding at end [%s]", newValue)
changesMade = true
}
return changesMade
}