瀏覽代碼

Merge pull request #1632 from mavenugo/ml

replace individual endpoint_cnt read from store with 1 bulk read
Alessandro Boch 8 年之前
父節點
當前提交
2a1d54d42d
共有 3 個文件被更改,包括 52 次插入15 次删除
  1. 36 6
      libnetwork/datastore/datastore.go
  2. 3 0
      libnetwork/endpoint_info.go
  3. 13 9
      libnetwork/store.go

+ 36 - 6
libnetwork/datastore/datastore.go

@@ -40,6 +40,8 @@ type DataStore interface {
 	// key. The caller must pass a KVObject of the same type as
 	// key. The caller must pass a KVObject of the same type as
 	// the objects that need to be listed
 	// the objects that need to be listed
 	List(string, KVObject) ([]KVObject, error)
 	List(string, KVObject) ([]KVObject, error)
+	// Map returns a Map of KVObjects
+	Map(key string, kvObject KVObject) (map[string]KVObject, error)
 	// Scope returns the scope of the store
 	// Scope returns the scope of the store
 	Scope() string
 	Scope() string
 	// KVStore returns access to the KV Store
 	// KVStore returns access to the KV Store
@@ -512,23 +514,34 @@ func (ds *datastore) List(key string, kvObject KVObject) ([]KVObject, error) {
 		return ds.cache.list(kvObject)
 		return ds.cache.list(kvObject)
 	}
 	}
 
 
+	var kvol []KVObject
+	cb := func(key string, val KVObject) {
+		kvol = append(kvol, val)
+	}
+	err := ds.iterateKVPairsFromStore(key, kvObject, cb)
+	if err != nil {
+		return nil, err
+	}
+	return kvol, nil
+}
+
+func (ds *datastore) iterateKVPairsFromStore(key string, kvObject KVObject, callback func(string, KVObject)) error {
 	// Bail out right away if the kvObject does not implement KVConstructor
 	// Bail out right away if the kvObject does not implement KVConstructor
 	ctor, ok := kvObject.(KVConstructor)
 	ctor, ok := kvObject.(KVConstructor)
 	if !ok {
 	if !ok {
-		return nil, fmt.Errorf("error listing objects, object does not implement KVConstructor interface")
+		return fmt.Errorf("error listing objects, object does not implement KVConstructor interface")
 	}
 	}
 
 
 	// Make sure the parent key exists
 	// Make sure the parent key exists
 	if err := ds.ensureParent(key); err != nil {
 	if err := ds.ensureParent(key); err != nil {
-		return nil, err
+		return err
 	}
 	}
 
 
 	kvList, err := ds.store.List(key)
 	kvList, err := ds.store.List(key)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return err
 	}
 	}
 
 
-	var kvol []KVObject
 	for _, kvPair := range kvList {
 	for _, kvPair := range kvList {
 		if len(kvPair.Value) == 0 {
 		if len(kvPair.Value) == 0 {
 			continue
 			continue
@@ -536,16 +549,33 @@ func (ds *datastore) List(key string, kvObject KVObject) ([]KVObject, error) {
 
 
 		dstO := ctor.New()
 		dstO := ctor.New()
 		if err := dstO.SetValue(kvPair.Value); err != nil {
 		if err := dstO.SetValue(kvPair.Value); err != nil {
-			return nil, err
+			return err
 		}
 		}
 
 
 		// Make sure the object has a correct view of the DB index in
 		// Make sure the object has a correct view of the DB index in
 		// case we need to modify it and update the DB.
 		// case we need to modify it and update the DB.
 		dstO.SetIndex(kvPair.LastIndex)
 		dstO.SetIndex(kvPair.LastIndex)
+		callback(kvPair.Key, dstO)
+	}
+
+	return nil
+}
 
 
-		kvol = append(kvol, dstO)
+func (ds *datastore) Map(key string, kvObject KVObject) (map[string]KVObject, error) {
+	if ds.sequential {
+		ds.Lock()
+		defer ds.Unlock()
 	}
 	}
 
 
+	kvol := make(map[string]KVObject)
+	cb := func(key string, val KVObject) {
+		// Trim the leading & trailing "/" to make it consistent across all stores
+		kvol[strings.Trim(key, "/")] = val
+	}
+	err := ds.iterateKVPairsFromStore(key, kvObject, cb)
+	if err != nil {
+		return nil, err
+	}
 	return kvol, nil
 	return kvol, nil
 }
 }
 
 

+ 3 - 0
libnetwork/endpoint_info.go

@@ -181,6 +181,9 @@ type tableEntry struct {
 }
 }
 
 
 func (ep *endpoint) Info() EndpointInfo {
 func (ep *endpoint) Info() EndpointInfo {
+	if ep.sandboxID != "" {
+		return ep
+	}
 	n, err := ep.getNetworkFromStore()
 	n, err := ep.getNetworkFromStore()
 	if err != nil {
 	if err != nil {
 		return nil
 		return nil

+ 13 - 9
libnetwork/store.go

@@ -2,6 +2,7 @@ package libnetwork
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"strings"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libkv/store/boltdb"
@@ -152,21 +153,24 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
 			continue
 			continue
 		}
 		}
 
 
+		kvep, err := store.Map(datastore.Key(epCntKeyPrefix), &endpointCnt{})
+		if err != nil {
+			if err != datastore.ErrKeyNotFound {
+				logrus.Warnf("failed to get endpoint_count map for scope %s: %v", store.Scope(), err)
+			}
+		}
+
 		for _, kvo := range kvol {
 		for _, kvo := range kvol {
 			n := kvo.(*network)
 			n := kvo.(*network)
 			n.Lock()
 			n.Lock()
 			n.ctrlr = c
 			n.ctrlr = c
-			n.Unlock()
-
 			ec := &endpointCnt{n: n}
 			ec := &endpointCnt{n: n}
-			err = store.GetObject(datastore.Key(ec.Key()...), ec)
-			if err != nil && !n.inDelete {
-				logrus.Warnf("could not find endpoint count key %s for network %s while listing: %v", datastore.Key(ec.Key()...), n.Name(), err)
-				continue
+			// Trim the leading & trailing "/" to make it consistent across all stores
+			if val, ok := kvep[strings.Trim(datastore.Key(ec.Key()...), "/")]; ok {
+				ec = val.(*endpointCnt)
+				ec.n = n
+				n.epCnt = ec
 			}
 			}
-
-			n.Lock()
-			n.epCnt = ec
 			n.scope = store.Scope()
 			n.scope = store.Scope()
 			n.Unlock()
 			n.Unlock()
 			nl = append(nl, n)
 			nl = append(nl, n)