Browse code

Use imageStore.Children instead of whole the Map

daemon cache was getting the whole image map and then iterating through
it to find children. This information is already stored in the image
store.

Prior to this change building the docker repo with a full cache took 30
seconds.
After it takes between 15 seconds or less (As low as 9 seconds).
This is an improvement on docker 1.9.1 which hovered around 17 seconds.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2016/01/26 13:37:18
Showing 1 changed files
... ...
@@ -1294,35 +1294,45 @@ func (daemon *Daemon) GetRemappedUIDGID() (int, int) {
1294 1294
 	return uid, gid
1295 1295
 }
1296 1296
 
1297
-// ImageGetCached returns the earliest created image that is a child
1297
+// ImageGetCached returns the most recent created image that is a child
1298 1298
 // of the image with imgID, that had the same config when it was
1299 1299
 // created. nil is returned if a child cannot be found. An error is
1300 1300
 // returned if the parent image cannot be found.
1301 1301
 func (daemon *Daemon) ImageGetCached(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
1302
-	// Retrieve all images
1303
-	imgs := daemon.Map()
1302
+	// Loop on the children of the given image and check the config
1303
+	getMatch := func(siblings []image.ID) (*image.Image, error) {
1304
+		var match *image.Image
1305
+		for _, id := range siblings {
1306
+			img, err := daemon.imageStore.Get(id)
1307
+			if err != nil {
1308
+				return nil, fmt.Errorf("unable to find image %q", id)
1309
+			}
1304 1310
 
1305
-	var siblings []image.ID
1306
-	for id, img := range imgs {
1307
-		if img.Parent == imgID {
1308
-			siblings = append(siblings, id)
1311
+			if runconfig.Compare(&img.ContainerConfig, config) {
1312
+				// check for the most up to date match
1313
+				if match == nil || match.Created.Before(img.Created) {
1314
+					match = img
1315
+				}
1316
+			}
1309 1317
 		}
1318
+		return match, nil
1310 1319
 	}
1311 1320
 
1312
-	// Loop on the children of the given image and check the config
1313
-	var match *image.Image
1314
-	for _, id := range siblings {
1315
-		img, ok := imgs[id]
1316
-		if !ok {
1317
-			return nil, fmt.Errorf("unable to find image %q", id)
1318
-		}
1319
-		if runconfig.Compare(&img.ContainerConfig, config) {
1320
-			if match == nil || match.Created.Before(img.Created) {
1321
-				match = img
1321
+	// In this case, this is `FROM scratch`, which isn't an actual image.
1322
+	if imgID == "" {
1323
+		images := daemon.imageStore.Map()
1324
+		var siblings []image.ID
1325
+		for id, img := range images {
1326
+			if img.Parent == imgID {
1327
+				siblings = append(siblings, id)
1322 1328
 			}
1323 1329
 		}
1330
+		return getMatch(siblings)
1324 1331
 	}
1325
-	return match, nil
1332
+
1333
+	// find match from child images
1334
+	siblings := daemon.imageStore.Children(imgID)
1335
+	return getMatch(siblings)
1326 1336
 }
1327 1337
 
1328 1338
 // tempDir returns the default directory to use for temporary files.