]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: use visit structure for map key in DeepEqual
authorRobert Hencke <robert.hencke@gmail.com>
Wed, 15 May 2013 21:50:57 +0000 (14:50 -0700)
committerRob Pike <r@golang.org>
Wed, 15 May 2013 21:50:57 +0000 (14:50 -0700)
R=golang-dev, bradfitz, jonathan, r
CC=golang-dev
https://golang.org/cl/8730044

src/pkg/reflect/deepequal.go

index 915afed4cda1281d893fab0eff988c8507255bfe..cc6ce056168532618a8bdbffcbbd04bcd5d4501b 100644 (file)
@@ -9,18 +9,17 @@ package reflect
 // During deepValueEqual, must keep track of checks that are
 // in progress.  The comparison algorithm assumes that all
 // checks in progress are true when it reencounters them.
-// Visited are stored in a map indexed by 17 * a1 + a2;
+// Visited comparisons are stored in a map indexed by visit.
 type visit struct {
-       a1   uintptr
-       a2   uintptr
-       typ  Type
-       next *visit
+       a1  uintptr
+       a2  uintptr
+       typ Type
 }
 
 // Tests for deep equality using reflected types. The map argument tracks
 // comparisons that have already been seen, which allows short circuiting on
 // recursive types.
-func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool) {
+func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {
        if !v1.IsValid() || !v2.IsValid() {
                return v1.IsValid() == v2.IsValid()
        }
@@ -44,17 +43,14 @@ func deepValueEqual(v1, v2 Value, visited map[uintptr]*visit, depth int) (b bool
                }
 
                // ... or already seen
-               h := 17*addr1 + addr2
-               seen := visited[h]
                typ := v1.Type()
-               for p := seen; p != nil; p = p.next {
-                       if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
-                               return true
-                       }
+               v := visit{addr1, addr2, typ}
+               if visited[v] {
+                       return true
                }
 
                // Remember for later.
-               visited[h] = &visit{addr1, addr2, typ, seen}
+               visited[v] = true
        }
 
        switch v1.Kind() {
@@ -135,5 +131,5 @@ func DeepEqual(a1, a2 interface{}) bool {
        if v1.Type() != v2.Type() {
                return false
        }
-       return deepValueEqual(v1, v2, make(map[uintptr]*visit), 0)
+       return deepValueEqual(v1, v2, make(map[visit]bool), 0)
 }