[VOL-5490] create device optimization

Change-Id: I11251af7d4b6bbc8e0d1114c7e1d197e05287fc8
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/VERSION b/VERSION
index 897e56b..d2577d9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.7.6
+3.7.7
diff --git a/db/model/proxy.go b/db/model/proxy.go
index a1c96b6..c516876 100644
--- a/db/model/proxy.go
+++ b/db/model/proxy.go
@@ -67,6 +67,22 @@
 
 // List will retrieve information from the data model at the proxy's path location, and write it to the target slice
 // target must be a type of the form *[]<proto.Message Type>  For example: *[]*voltha.Device
+func (p *Proxy) KeyExists(ctx context.Context, id string) (bool, error) {
+	completePath := p.path + id
+
+	logger.Debugw(ctx, "proxy-key-exists", log.Fields{
+		"path": completePath,
+	})
+
+	keyExists, err := p.kvStore.KeyExists(ctx, completePath)
+	if err != nil {
+		return false, fmt.Errorf("failed to retrieve %s from kvstore: %s", p.path, err)
+	}
+	return keyExists, nil
+}
+
+// List will retrieve information from the data model at the proxy's path location, and write it to the target slice
+// target must be a type of the form *[]<proto.Message Type>  For example: *[]*voltha.Device
 func (p *Proxy) List(ctx context.Context, target interface{}) error {
 	logger.Debugw(ctx, "proxy-list", log.Fields{
 		"path": p.path,
diff --git a/rw_core/core/device/manager.go b/rw_core/core/device/manager.go
index 6466744..d5657eb 100755
--- a/rw_core/core/device/manager.go
+++ b/rw_core/core/device/manager.go
@@ -233,25 +233,34 @@
 
 // isParentDeviceExist checks whether device is already preprovisioned.
 func (dMgr *Manager) isParentDeviceExist(ctx context.Context, newDevice *voltha.Device) (bool, error) {
-	hostPort := newDevice.GetHostAndPort()
-	var devices []*voltha.Device
-	if err := dMgr.dProxy.List(ctx, &devices); err != nil {
-		logger.Errorw(ctx, "failed-to-list-devices-from-cluster-data-proxy", log.Fields{"error": err})
-		return false, err
+	if newDevice.Id != "" {
+		var keyExists bool
+		var err error
+		if keyExists, err = dMgr.dProxy.KeyExists(ctx, newDevice.Id); err != nil {
+			logger.Errorw(ctx, "failed-to-check-device-exists-from-cluster-data-proxy", log.Fields{"error": err, "device-id": newDevice.Id})
+			return false, err
+		}
+		return keyExists, nil
+	} else {
+		hostPort := newDevice.GetHostAndPort()
+		var devices []*voltha.Device
+		if err := dMgr.dProxy.List(ctx, &devices); err != nil {
+			logger.Errorw(ctx, "failed-to-list-devices-from-cluster-data-proxy", log.Fields{"error": err})
+			return false, err
+		}
+		for _, device := range devices {
+			if !device.Root {
+				continue
+			}
+			if hostPort != "" && hostPort == device.GetHostAndPort() {
+				return true, nil
+			}
+			if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress {
+				return true, nil
+			}
+		}
+		return false, nil
 	}
-	for _, device := range devices {
-		if !device.Root {
-			continue
-		}
-
-		if hostPort != "" && hostPort == device.GetHostAndPort() {
-			return true, nil
-		}
-		if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress {
-			return true, nil
-		}
-	}
-	return false, nil
 }
 
 // getDeviceFromModelretrieves the device data from the model.