mirror of
https://github.com/golang/go
synced 2024-11-12 06:30:21 -07:00
reflect: use visit structure for map key in DeepEqual
R=golang-dev, bradfitz, jonathan, r CC=golang-dev https://golang.org/cl/8730044
This commit is contained in:
parent
c6293d2106
commit
f7b5a01999
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user