Browse Source

Merge pull request #5798 from unclejack/fix_startup_speed

don't update Suffixarray for every Register during startup
Michael Crosby 11 năm trước cách đây
mục cha
commit
de406b69f3
2 tập tin đã thay đổi với 41 bổ sung8 xóa
  1. 19 5
      daemon/daemon.go
  2. 22 3
      utils/utils.go

+ 19 - 5
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 <container.ID>
+// 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 <container.ID>
+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")
 	}

+ 22 - 3
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()