From bc13a475f858d274af99d0741b6d66fede16f078 Mon Sep 17 00:00:00 2001 From: unclejack Date: Wed, 14 May 2014 17:55:06 +0300 Subject: [PATCH 1/2] add UpdateSuffixarray and refactor TruncIndex This commit refactors TruncIndex to make it possible to add container ids to the TruncIndex without updating the Suffixarray. This is useful during the Docker daemon's startup when we don't want to update the Suffixarray for every container we add. Add continues to function like before. Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) Upstream-commit: 219b7ae8b526bb5e6d0e27176308db71438a002f Component: engine --- components/engine/utils/utils.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index 7ffcc06b93..7788b20d54 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -493,9 +493,7 @@ func NewTruncIndex(ids []string) (idx *TruncIndex) { return } -func (idx *TruncIndex) Add(id string) error { - idx.Lock() - defer idx.Unlock() +func (idx *TruncIndex) addId(id string) error { if strings.Contains(id, " ") { return fmt.Errorf("Illegal character: ' '") } @@ -504,10 +502,31 @@ func (idx *TruncIndex) Add(id string) error { } idx.ids[id] = true idx.bytes = append(idx.bytes, []byte(id+" ")...) + return nil +} + +func (idx *TruncIndex) Add(id string) error { + idx.Lock() + defer idx.Unlock() + if err := idx.addId(id); err != nil { + return err + } idx.index = suffixarray.New(idx.bytes) return nil } +func (idx *TruncIndex) AddWithoutSuffixarrayUpdate(id string) error { + idx.Lock() + defer idx.Unlock() + return idx.addId(id) +} + +func (idx *TruncIndex) UpdateSuffixarray() { + idx.Lock() + defer idx.Unlock() + idx.index = suffixarray.New(idx.bytes) +} + func (idx *TruncIndex) Delete(id string) error { idx.Lock() defer idx.Unlock() From 36853439a848e987888b2f52f4f334662559727e Mon Sep 17 00:00:00 2001 From: unclejack Date: Wed, 14 May 2014 17:58:37 +0300 Subject: [PATCH 2/2] update Suffixarray only once during daemon startup This commit makes the Docker daemon call UpdateSuffixarray only after it finishes registering all containers. This lowers the amount of time required for the Docker daemon to start up. Docker-DCO-1.1-Signed-off-by: Cristian Staretu (github: unclejack) Upstream-commit: 5d5c89398c39e2f38459aae42189c9ca1125c1d3 Component: engine --- components/engine/daemon/daemon.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go index 38a107bba3..143683001d 100644 --- a/components/engine/daemon/daemon.go +++ b/components/engine/daemon/daemon.go @@ -141,7 +141,13 @@ func (daemon *Daemon) load(id string) (*Container, error) { } // Register makes a container object usable by the daemon as +// This is a wrapper for register func (daemon *Daemon) Register(container *Container) error { + return daemon.register(container, true) +} + +// register makes a container object usable by the daemon as +func (daemon *Daemon) register(container *Container, updateSuffixarray bool) error { if container.daemon != nil || daemon.Exists(container.ID) { return fmt.Errorf("Container is already loaded") } @@ -165,7 +171,14 @@ func (daemon *Daemon) Register(container *Container) error { } // done daemon.containers.PushBack(container) - daemon.idIndex.Add(container.ID) + + // don't update the Suffixarray if we're starting up + // we'll waste time if we update it for every container + if updateSuffixarray { + daemon.idIndex.Add(container.ID) + } else { + daemon.idIndex.AddWithoutSuffixarrayUpdate(container.ID) + } // FIXME: if the container is supposed to be running but is not, auto restart it? // if so, then we need to restart monitor and init a new lock @@ -329,8 +342,8 @@ func (daemon *Daemon) restore() error { } } - register := func(container *Container) { - if err := daemon.Register(container); err != nil { + registerContainer := func(container *Container) { + if err := daemon.register(container, false); err != nil { utils.Debugf("Failed to register container %s: %s", container.ID, err) } } @@ -342,7 +355,7 @@ func (daemon *Daemon) restore() error { } e := entities[p] if container, ok := containers[e.ID()]; ok { - register(container) + registerContainer(container) delete(containers, e.ID()) } } @@ -359,9 +372,10 @@ func (daemon *Daemon) restore() error { if _, err := daemon.containerGraph.Set(container.Name, container.ID); err != nil { utils.Debugf("Setting default id - %s", err) } - register(container) + registerContainer(container) } + daemon.idIndex.UpdateSuffixarray() if os.Getenv("DEBUG") == "" && os.Getenv("TEST") == "" { fmt.Printf(": done.\n") }