Skip to content

Commit d047825

Browse files
committed
Use ordered array instead of heap for sb.endpoints
Signed-off-by: Christoph Ziebuhr <[email protected]>
1 parent a2e6eb2 commit d047825

4 files changed

Lines changed: 27 additions & 43 deletions

File tree

controller.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ create network namespaces and allocate interfaces for containers to use.
4444
package libnetwork
4545

4646
import (
47-
"container/heap"
4847
"fmt"
4948
"net"
5049
"path/filepath"
@@ -1085,7 +1084,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
10851084
sb = &sandbox{
10861085
id: sandboxID,
10871086
containerID: containerID,
1088-
endpoints: epHeap{},
1087+
endpoints: []*endpoint{},
10891088
epPriority: map[string]int{},
10901089
populatedEndpoints: map[string]struct{}{},
10911090
config: containerConfig{},
@@ -1094,8 +1093,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
10941093
}
10951094
}
10961095

1097-
heap.Init(&sb.endpoints)
1098-
10991096
sb.processOptions(options...)
11001097

11011098
c.Lock()

endpoint.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package libnetwork
22

33
import (
4-
"container/heap"
54
"encoding/json"
65
"fmt"
76
"net"
@@ -515,11 +514,13 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
515514
extEp := sb.getGatewayEndpoint()
516515

517516
sb.Lock()
518-
heap.Push(&sb.endpoints, ep)
517+
sb.addEndpoint(ep)
519518
sb.Unlock()
520519
defer func() {
521520
if err != nil {
521+
sb.Lock()
522522
sb.removeEndpoint(ep)
523+
sb.Unlock()
523524
}
524525
}()
525526

sandbox.go

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package libnetwork
22

33
import (
4-
"container/heap"
54
"encoding/json"
65
"fmt"
76
"net"
87
"strings"
98
"sync"
109
"time"
10+
"sort"
1111

1212
"github.com/docker/libnetwork/etchosts"
1313
"github.com/docker/libnetwork/netlabel"
@@ -63,8 +63,6 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
6363
}
6464
}
6565

66-
type epHeap []*endpoint
67-
6866
type sandbox struct {
6967
id string
7068
containerID string
@@ -75,7 +73,7 @@ type sandbox struct {
7573
resolver Resolver
7674
resolverOnce sync.Once
7775
refCnt int
78-
endpoints epHeap
76+
endpoints []*endpoint
7977
epPriority map[string]int
8078
populatedEndpoints map[string]struct{}
8179
joinLeaveDone chan struct{}
@@ -360,13 +358,22 @@ func (sb *sandbox) getConnectedEndpoints() []*endpoint {
360358
return eps
361359
}
362360

361+
func (sb *sandbox) addEndpoint(ep *endpoint) {
362+
l := len(sb.endpoints)
363+
i := sort.Search(l, func(j int) bool {
364+
return ep.Less(sb.endpoints[j])
365+
})
366+
367+
sb.endpoints = append(sb.endpoints, nil)
368+
copy(sb.endpoints[i+1:], sb.endpoints[i:])
369+
sb.endpoints[i] = ep
370+
}
371+
363372
func (sb *sandbox) removeEndpoint(ep *endpoint) {
364-
sb.Lock()
365-
defer sb.Unlock()
366373

367374
for i, e := range sb.endpoints {
368375
if e == ep {
369-
heap.Remove(&sb.endpoints, i)
376+
sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...)
370377
return
371378
}
372379
}
@@ -940,7 +947,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
940947
return nil
941948
}
942949

943-
heap.Remove(&sb.endpoints, index)
950+
sb.removeEndpoint(ep)
944951
for _, e := range sb.endpoints {
945952
if len(e.Gateway()) > 0 {
946953
gwepAfter = e
@@ -1165,19 +1172,14 @@ func OptionIngress() SandboxOption {
11651172
}
11661173
}
11671174

1168-
func (eh epHeap) Len() int { return len(eh) }
1169-
1170-
func (eh epHeap) Less(i, j int) bool {
1175+
func (epi *endpoint) Less(epj *endpoint) bool {
11711176
var (
11721177
cip, cjp int
11731178
ok bool
11741179
)
11751180

1176-
ci, _ := eh[i].getSandbox()
1177-
cj, _ := eh[j].getSandbox()
1178-
1179-
epi := eh[i]
1180-
epj := eh[j]
1181+
ci, _ := epi.getSandbox()
1182+
cj, _ := epj.getSandbox()
11811183

11821184
if epi.endpointInGWNetwork() {
11831185
return false
@@ -1207,40 +1209,26 @@ func (eh epHeap) Less(i, j int) bool {
12071209
}
12081210

12091211
if ci != nil {
1210-
cip, ok = ci.epPriority[eh[i].ID()]
1212+
cip, ok = ci.epPriority[epi.ID()]
12111213
if !ok {
12121214
cip = 0
12131215
}
12141216
}
12151217

12161218
if cj != nil {
1217-
cjp, ok = cj.epPriority[eh[j].ID()]
1219+
cjp, ok = cj.epPriority[epj.ID()]
12181220
if !ok {
12191221
cjp = 0
12201222
}
12211223
}
12221224

12231225
if cip == cjp {
1224-
return eh[i].network.Name() < eh[j].network.Name()
1226+
return epi.network.Name() < epj.network.Name()
12251227
}
12261228

12271229
return cip > cjp
12281230
}
12291231

1230-
func (eh epHeap) Swap(i, j int) { eh[i], eh[j] = eh[j], eh[i] }
1231-
1232-
func (eh *epHeap) Push(x interface{}) {
1233-
*eh = append(*eh, x.(*endpoint))
1234-
}
1235-
1236-
func (eh *epHeap) Pop() interface{} {
1237-
old := *eh
1238-
n := len(old)
1239-
x := old[n-1]
1240-
*eh = old[0 : n-1]
1241-
return x
1242-
}
1243-
12441232
func (sb *sandbox) NdotsSet() bool {
12451233
return sb.ndotsSet
12461234
}

sandbox_store.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package libnetwork
22

33
import (
4-
"container/heap"
54
"encoding/json"
65
"sync"
76

@@ -215,7 +214,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
215214
id: sbs.ID,
216215
controller: sbs.c,
217216
containerID: sbs.Cid,
218-
endpoints: epHeap{},
217+
endpoints: []*endpoint{},
219218
populatedEndpoints: map[string]struct{}{},
220219
dbIndex: sbs.dbIndex,
221220
isStub: true,
@@ -242,7 +241,6 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
242241
sb.processOptions(opts...)
243242
sb.restorePath()
244243
create = !sb.config.useDefaultSandBox
245-
heap.Init(&sb.endpoints)
246244
}
247245
sb.osSbox, err = osl.NewSandbox(sb.Key(), create, isRestore)
248246
if err != nil {
@@ -272,7 +270,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
272270
logrus.Errorf("failed to restore endpoint %s in %s for container %s due to %v", eps.Eid, eps.Nid, sb.ContainerID(), err)
273271
continue
274272
}
275-
heap.Push(&sb.endpoints, ep)
273+
sb.addEndpoint(ep)
276274
}
277275

278276
if _, ok := activeSandboxes[sb.ID()]; !ok {

0 commit comments

Comments
 (0)