Permalink
Browse files

Use ordered array instead of heap for sb.endpoints

Signed-off-by: Christoph Ziebuhr <chris@codefrickler.de>
  • Loading branch information...
cziebuhr committed Feb 27, 2018
1 parent a2e6eb2 commit d047825d4d156bc4cf01bfe410cb61b3bc33f572
Showing with 27 additions and 43 deletions.
  1. +1 −4 controller.go
  2. +3 −2 endpoint.go
  3. +21 −33 sandbox.go
  4. +2 −4 sandbox_store.go
@@ -44,7 +44,6 @@ create network namespaces and allocate interfaces for containers to use.
package libnetwork
import (
"container/heap"
"fmt"
"net"
"path/filepath"
@@ -1085,7 +1084,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
sb = &sandbox{
id: sandboxID,
containerID: containerID,
endpoints: epHeap{},
endpoints: []*endpoint{},
epPriority: map[string]int{},
populatedEndpoints: map[string]struct{}{},
config: containerConfig{},
@@ -1094,8 +1093,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
}
}
heap.Init(&sb.endpoints)
sb.processOptions(options...)
c.Lock()
@@ -1,7 +1,6 @@
package libnetwork
import (
"container/heap"
"encoding/json"
"fmt"
"net"
@@ -515,11 +514,13 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
extEp := sb.getGatewayEndpoint()
sb.Lock()
heap.Push(&sb.endpoints, ep)
sb.addEndpoint(ep)
sb.Unlock()
defer func() {
if err != nil {
sb.Lock()
sb.removeEndpoint(ep)
sb.Unlock()
}
}()
@@ -1,13 +1,13 @@
package libnetwork
import (
"container/heap"
"encoding/json"
"fmt"
"net"
"strings"
"sync"
"time"
"sort"
"github.com/docker/libnetwork/etchosts"
"github.com/docker/libnetwork/netlabel"
@@ -63,8 +63,6 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
}
}
type epHeap []*endpoint
type sandbox struct {
id string
containerID string
@@ -75,7 +73,7 @@ type sandbox struct {
resolver Resolver
resolverOnce sync.Once
refCnt int
endpoints epHeap
endpoints []*endpoint
epPriority map[string]int
populatedEndpoints map[string]struct{}
joinLeaveDone chan struct{}
@@ -360,13 +358,22 @@ func (sb *sandbox) getConnectedEndpoints() []*endpoint {
return eps
}
func (sb *sandbox) addEndpoint(ep *endpoint) {
l := len(sb.endpoints)
i := sort.Search(l, func(j int) bool {
return ep.Less(sb.endpoints[j])
})
sb.endpoints = append(sb.endpoints, nil)
copy(sb.endpoints[i+1:], sb.endpoints[i:])
sb.endpoints[i] = ep
}
func (sb *sandbox) removeEndpoint(ep *endpoint) {
sb.Lock()
defer sb.Unlock()
for i, e := range sb.endpoints {
if e == ep {
heap.Remove(&sb.endpoints, i)
sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...)
return
}
}
@@ -940,7 +947,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
return nil
}
heap.Remove(&sb.endpoints, index)
sb.removeEndpoint(ep)
for _, e := range sb.endpoints {
if len(e.Gateway()) > 0 {
gwepAfter = e
@@ -1165,19 +1172,14 @@ func OptionIngress() SandboxOption {
}
}
func (eh epHeap) Len() int { return len(eh) }
func (eh epHeap) Less(i, j int) bool {
func (epi *endpoint) Less(epj *endpoint) bool {
var (
cip, cjp int
ok bool
)
ci, _ := eh[i].getSandbox()
cj, _ := eh[j].getSandbox()
epi := eh[i]
epj := eh[j]
ci, _ := epi.getSandbox()
cj, _ := epj.getSandbox()
if epi.endpointInGWNetwork() {
return false
@@ -1207,40 +1209,26 @@ func (eh epHeap) Less(i, j int) bool {
}
if ci != nil {
cip, ok = ci.epPriority[eh[i].ID()]
cip, ok = ci.epPriority[epi.ID()]
if !ok {
cip = 0
}
}
if cj != nil {
cjp, ok = cj.epPriority[eh[j].ID()]
cjp, ok = cj.epPriority[epj.ID()]
if !ok {
cjp = 0
}
}
if cip == cjp {
return eh[i].network.Name() < eh[j].network.Name()
return epi.network.Name() < epj.network.Name()
}
return cip > cjp
}
func (eh epHeap) Swap(i, j int) { eh[i], eh[j] = eh[j], eh[i] }
func (eh *epHeap) Push(x interface{}) {
*eh = append(*eh, x.(*endpoint))
}
func (eh *epHeap) Pop() interface{} {
old := *eh
n := len(old)
x := old[n-1]
*eh = old[0 : n-1]
return x
}
func (sb *sandbox) NdotsSet() bool {
return sb.ndotsSet
}
@@ -1,7 +1,6 @@
package libnetwork
import (
"container/heap"
"encoding/json"
"sync"
@@ -215,7 +214,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
id: sbs.ID,
controller: sbs.c,
containerID: sbs.Cid,
endpoints: epHeap{},
endpoints: []*endpoint{},
populatedEndpoints: map[string]struct{}{},
dbIndex: sbs.dbIndex,
isStub: true,
@@ -242,7 +241,6 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
sb.processOptions(opts...)
sb.restorePath()
create = !sb.config.useDefaultSandBox
heap.Init(&sb.endpoints)
}
sb.osSbox, err = osl.NewSandbox(sb.Key(), create, isRestore)
if err != nil {
@@ -272,7 +270,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
logrus.Errorf("failed to restore endpoint %s in %s for container %s due to %v", eps.Eid, eps.Nid, sb.ContainerID(), err)
continue
}
heap.Push(&sb.endpoints, ep)
sb.addEndpoint(ep)
}
if _, ok := activeSandboxes[sb.ID()]; !ok {

0 comments on commit d047825

Please sign in to comment.