From 4ede9226bb971ae42cc203560ed0029897aec2c9 Mon Sep 17 00:00:00 2001
From: Lang Martin <lang@hashicorp.com>
Date: Wed, 27 Mar 2019 12:01:47 -0400
Subject: [PATCH] refactor structs.Resource.Devices to have its own Equals

---
 nomad/structs/structs.go | 44 ++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go
index af5421a47b..fbbaa83425 100644
--- a/nomad/structs/structs.go
+++ b/nomad/structs/structs.go
@@ -1715,7 +1715,7 @@ type Resources struct {
 	DiskMB   int
 	IOPS     int // COMPAT(0.10): Only being used to issue warnings
 	Networks Networks
-	Devices  []*RequestedDevice
+	Devices  ResourceDevices
 }
 
 const (
@@ -1790,7 +1790,6 @@ func (r *Resources) Merge(other *Resources) {
 	}
 }
 
-// Equals deeply equates the value of this resource with another
 // COMPAT(0.10): Remove in 0.10
 func (r *Resources) Equals(o *Resources) bool {
 	if r == nil && o == nil {
@@ -1802,20 +1801,39 @@ func (r *Resources) Equals(o *Resources) bool {
 	if r.CPU == o.CPU &&
 		r.MemoryMB == o.MemoryMB &&
 		r.DiskMB == o.DiskMB &&
-		r.IOPS == o.IOPS {
-		for i, n := range r.Networks {
-			if !n.Equals(o.Networks[i]) {
-				return false
-			}
-		}
-		if !DevicesEquals(r.Devices, o.Devices) {
-			return false
-		}
+		r.IOPS == o.IOPS &&
+		r.Networks.Equals(o.Networks) &&
+		r.Devices.Equals(&o.Devices) {
 		return true
 	}
 	return false
 }
 
+// Equals ResourceDevices as set on Name
+// COMPAT(0.10): Remove in 0.10
+func (d *ResourceDevices) Equals(o *ResourceDevices) bool {
+	if d == nil && o == nil {
+		return true
+	}
+	if d == nil || o == nil {
+		return false
+	}
+	if len(*d) != len(*o) {
+		return false
+	}
+	m := make(map[string]*RequestedDevice, len(*d))
+	for _, e := range *d {
+		m[e.Name] = e
+	}
+	for _, oe := range *o {
+		de, ok := m[oe.Name]
+		if !ok || !de.Equals(oe) {
+			return false
+		}
+	}
+	return true
+}
+
 // COMPAT(0.10): Remove in 0.10
 func (r *Resources) Canonicalize() {
 	// Ensure that an empty and nil slices are treated the same to avoid scheduling
@@ -2063,6 +2081,10 @@ func (n *NetworkResource) PortLabels() map[string]int {
 // Networks defined for a task on the Resources struct.
 type Networks []*NetworkResource
 
+// COMPAT(0.10): Remove in 0.10
+// ResourceDevices are part of Resources
+type ResourceDevices []*RequestedDevice
+
 // Port assignment and IP for the given label or empty values.
 func (ns Networks) Port(label string) (string, int) {
 	for _, n := range ns {
-- 
GitLab