瀏覽代碼

Speedup container list

Remove all unneeded disk operations (reload TagStore, umarshal image)
for checking if image still points to same ID. Now slowest part is
queries to sqlite which hopefuly will be removed soon.

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
Alexander Morozov 9 年之前
父節點
當前提交
f256d8ad2d
共有 2 個文件被更改,包括 45 次插入8 次删除
  1. 22 8
      daemon/list.go
  2. 23 0
      graph/tags.go

+ 22 - 8
daemon/list.go

@@ -9,6 +9,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	derr "github.com/docker/docker/errors"
+	"github.com/docker/docker/graph"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/graphdb"
 	"github.com/docker/docker/pkg/nat"
@@ -285,6 +286,24 @@ func includeContainerInList(container *Container, ctx *listContext) iterationAct
 	return includeContainer
 }
 
+func getImage(s *graph.TagStore, img, imgID string) (string, error) {
+	// both Image and ImageID is actually ids, nothing to guess
+	if strings.HasPrefix(imgID, img) {
+		return img, nil
+	}
+	id, err := s.GetID(img)
+	if err != nil {
+		if err == graph.ErrNameIsNotExist {
+			return imgID, nil
+		}
+		return "", err
+	}
+	if id != imgID {
+		return imgID, nil
+	}
+	return img, nil
+}
+
 // transformContainer generates the container type expected by the docker ps command.
 func (daemon *Daemon) transformContainer(container *Container, ctx *listContext) (*types.Container, error) {
 	newC := &types.Container{
@@ -297,16 +316,11 @@ func (daemon *Daemon) transformContainer(container *Container, ctx *listContext)
 		newC.Names = []string{}
 	}
 
-	img, err := daemon.repositories.LookupImage(container.Config.Image)
+	showImg, err := getImage(daemon.repositories, container.Config.Image, container.ImageID)
 	if err != nil {
-		// If the image can no longer be found by its original reference,
-		// it makes sense to show the ID instead of a stale reference.
-		newC.Image = container.ImageID
-	} else if container.ImageID == img.ID {
-		newC.Image = container.Config.Image
-	} else {
-		newC.Image = container.ImageID
+		return nil, err
 	}
+	newC.Image = showImg
 
 	if len(container.Args) > 0 {
 		args := []string{}

+ 23 - 0
graph/tags.go

@@ -24,6 +24,9 @@ import (
 	"github.com/docker/libtrust"
 )
 
+// ErrNameIsNotExist returned when there is no image with requested name.
+var ErrNameIsNotExist = errors.New("image with specified name does not exist")
+
 // TagStore manages repositories. It encompasses the Graph used for versioned
 // storage, as well as various services involved in pushing and pulling
 // repositories.
@@ -164,6 +167,26 @@ func (store *TagStore) LookupImage(name string) (*image.Image, error) {
 	return img, nil
 }
 
+// GetID returns ID for image name.
+func (store *TagStore) GetID(name string) (string, error) {
+	repoName, ref := parsers.ParseRepositoryTag(name)
+	if ref == "" {
+		ref = tags.DefaultTag
+	}
+	store.Lock()
+	defer store.Unlock()
+	repoName = registry.NormalizeLocalName(repoName)
+	repo, ok := store.Repositories[repoName]
+	if !ok {
+		return "", ErrNameIsNotExist
+	}
+	id, ok := repo[ref]
+	if !ok {
+		return "", ErrNameIsNotExist
+	}
+	return id, nil
+}
+
 // ByID returns a reverse-lookup table of all the names which refer to each
 // image - e.g. {"43b5f19b10584": {"base:latest", "base:v1"}}
 func (store *TagStore) ByID() map[string][]string {