diff --git a/daemon/daemon.go b/daemon/daemon.go index 33ddb87ae4..fc9f07052e 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -142,7 +142,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") } @@ -166,7 +172,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 @@ -330,8 +343,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) } } @@ -343,7 +356,7 @@ func (daemon *Daemon) restore() error { } e := entities[p] if container, ok := containers[e.ID()]; ok { - register(container) + registerContainer(container) delete(containers, e.ID()) } } @@ -360,9 +373,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") } diff --git a/utils/utils.go b/utils/utils.go index 7ffcc06b93..7788b20d54 100644 --- a/utils/utils.go +++ b/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()