1
1
package complexscheduler
2
2
3
3
import (
4
+ "container/heap"
4
5
"sort"
5
6
6
7
"github.com/projecteru2/core/types"
@@ -11,6 +12,37 @@ type resourceInfo struct {
11
12
pieces int64
12
13
}
13
14
15
+ type resourceInfoHeap []resourceInfo
16
+
17
+ // Len .
18
+ func (r resourceInfoHeap ) Len () int {
19
+ return len (r )
20
+ }
21
+
22
+ // Less .
23
+ func (r resourceInfoHeap ) Less (i , j int ) bool {
24
+ return r [i ].pieces > r [j ].pieces
25
+ }
26
+
27
+ // Swap .
28
+ func (r resourceInfoHeap ) Swap (i , j int ) {
29
+ r [i ], r [j ] = r [j ], r [i ]
30
+ }
31
+
32
+ // Push .
33
+ func (r * resourceInfoHeap ) Push (x interface {}) {
34
+ * r = append (* r , x .(resourceInfo ))
35
+ }
36
+
37
+ // Pop .
38
+ func (r * resourceInfoHeap ) Pop () interface {} {
39
+ old := * r
40
+ n := len (old )
41
+ x := old [n - 1 ]
42
+ * r = old [:n - 1 ]
43
+ return x
44
+ }
45
+
14
46
type host struct {
15
47
full []resourceInfo
16
48
fragment []resourceInfo
@@ -183,26 +215,45 @@ func (h *host) getFragmentsResult(resources []resourceInfo, fragments ...int64)
183
215
184
216
func (h * host ) getFullResult (full int , resources []resourceInfo ) []types.ResourceMap {
185
217
result := []types.ResourceMap {}
218
+ resourceHeap := & resourceInfoHeap {}
219
+ indexMap := map [string ]int {}
220
+ for i , resource := range resources {
221
+ indexMap [resource .id ] = i
222
+ resourceHeap .Push (resourceInfo {id : resource .id , pieces : resource .pieces })
223
+ }
224
+ heap .Init (resourceHeap )
186
225
187
- for len (resources )/ full > 0 {
188
- count , rem := len (resources )/ full , len (resources )% full
189
- newResources := []resourceInfo {}
190
- for i := 0 ; i < count ; i ++ {
191
- plan := types.ResourceMap {}
192
- for j := i * full ; j < i * full + full ; j ++ {
193
- // 洗掉没配额的
194
- last := resources [j ].pieces - int64 (h .share )
195
- if last > 0 {
196
- newResources = append (newResources , resourceInfo {resources [j ].id , last })
197
- }
198
- plan [resources [j ].id ] = int64 (h .share )
226
+ for resourceHeap .Len () >= full {
227
+ plan := types.ResourceMap {}
228
+ resourcesToPush := []resourceInfo {}
229
+
230
+ for i := 0 ; i < full ; i ++ {
231
+ resource := heap .Pop (resourceHeap ).(resourceInfo )
232
+ plan [resource .id ] = int64 (h .share )
233
+
234
+ resource .pieces -= int64 (h .share )
235
+ if resource .pieces > 0 {
236
+ resourcesToPush = append (resourcesToPush , resource )
199
237
}
200
- result = append (result , plan )
201
238
}
202
239
203
- resources = append (newResources , resources [len (resources )- rem :]... )
240
+ result = append (result , plan )
241
+ for _ , resource := range resourcesToPush {
242
+ heap .Push (resourceHeap , resource )
243
+ }
204
244
}
205
245
246
+ // Try to ensure the effectiveness of the previous priority
247
+ sumOfIds := func (r types.ResourceMap ) int {
248
+ sum := 0
249
+ for id := range r {
250
+ sum += indexMap [id ]
251
+ }
252
+ return sum
253
+ }
254
+
255
+ sort .Slice (result , func (i , j int ) bool { return sumOfIds (result [i ]) < sumOfIds (result [j ]) })
256
+
206
257
return result
207
258
}
208
259
0 commit comments