From b47aa1446bc638d70a9aea90b10db6c403e55dc4 Mon Sep 17 00:00:00 2001 From: kortschak Date: Fri, 16 Jun 2017 11:01:45 +0930 Subject: [PATCH] graph/internal/...: update for int64 IDs --- graph/internal/ordered/sort.go | 12 +++++-- graph/internal/set/same.go | 9 +++++ graph/internal/set/same_appengine.go | 9 +++++ graph/internal/set/set.go | 51 ++++++++++++++++++++++++++-- graph/internal/set/set_test.go | 4 +-- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/graph/internal/ordered/sort.go b/graph/internal/ordered/sort.go index 742d67ec..e0cce8ef 100644 --- a/graph/internal/ordered/sort.go +++ b/graph/internal/ordered/sort.go @@ -16,8 +16,8 @@ func (n ByID) Less(i, j int) bool { return n[i].ID() < n[j].ID() } func (n ByID) Swap(i, j int) { n[i], n[j] = n[j], n[i] } // BySliceValues implements the sort.Interface sorting a slice of -// []int lexically by the values of the []int. -type BySliceValues [][]int +// []int64 lexically by the values of the []int64. +type BySliceValues [][]int64 func (c BySliceValues) Len() int { return len(c) } func (c BySliceValues) Less(i, j int) bool { @@ -60,3 +60,11 @@ func (c BySliceIDs) Less(i, j int) bool { return len(a) < len(b) } func (c BySliceIDs) Swap(i, j int) { c[i], c[j] = c[j], c[i] } + +// Int64s implements the sort.Interface sorting a slice of +// int64. +type Int64s []int64 + +func (s Int64s) Len() int { return len(s) } +func (s Int64s) Less(i, j int) bool { return s[i] < s[j] } +func (s Int64s) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/graph/internal/set/same.go b/graph/internal/set/same.go index 446e0ac3..c776dc32 100644 --- a/graph/internal/set/same.go +++ b/graph/internal/set/same.go @@ -25,3 +25,12 @@ func same(a, b Nodes) bool { func intsSame(a, b Ints) bool { return *(*uintptr)(unsafe.Pointer(&a)) == *(*uintptr)(unsafe.Pointer(&b)) } + +// int64sSame determines whether two sets are backed by the same store. In the +// current implementation using hash maps it makes use of the fact that +// hash maps are passed as a pointer to a runtime Hmap struct. A map is +// not seen by the runtime as a pointer though, so we use unsafe to get +// the maps' pointer values to compare. +func int64sSame(a, b Int64s) bool { + return *(*uintptr)(unsafe.Pointer(&a)) == *(*uintptr)(unsafe.Pointer(&b)) +} diff --git a/graph/internal/set/same_appengine.go b/graph/internal/set/same_appengine.go index 00d095a0..082ed265 100644 --- a/graph/internal/set/same_appengine.go +++ b/graph/internal/set/same_appengine.go @@ -25,3 +25,12 @@ func same(a, b Nodes) bool { func intsSame(a, b Ints) bool { return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer() } + +// int64sSame determines whether two sets are backed by the same store. In the +// current implementation using hash maps it makes use of the fact that +// hash maps are passed as a pointer to a runtime Hmap struct. A map is +// not seen by the runtime as a pointer though, so we use reflect to get +// the maps' pointer values to compare. +func int64sSame(a, b Int64s) bool { + return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer() +} diff --git a/graph/internal/set/set.go b/graph/internal/set/set.go index b9587776..1397dabb 100644 --- a/graph/internal/set/set.go +++ b/graph/internal/set/set.go @@ -7,7 +7,7 @@ package set // import "gonum.org/v1/gonum/graph/internal/set" import "gonum.org/v1/gonum/graph" -// Ints is a set of integer identifiers. +// Ints is a set of int identifiers. type Ints map[int]struct{} // The simple accessor methods for Ints are provided to allow ease of @@ -54,8 +54,55 @@ func IntsEqual(a, b Ints) bool { return true } +// Int64s is a set of int64 identifiers. +type Int64s map[int64]struct{} + +// The simple accessor methods for Ints are provided to allow ease of +// implementation change should the need arise. + +// Add inserts an element into the set. +func (s Int64s) Add(e int64) { + s[e] = struct{}{} +} + +// Has reports the existence of the element in the set. +func (s Int64s) Has(e int64) bool { + _, ok := s[e] + return ok +} + +// Remove deletes the specified element from the set. +func (s Int64s) Remove(e int64) { + delete(s, e) +} + +// Count reports the number of elements stored in the set. +func (s Int64s) Count() int { + return len(s) +} + +// Int64sEqual reports set equality between the parameters. Sets are equal if +// and only if they have the same elements. +func Int64sEqual(a, b Int64s) bool { + if int64sSame(a, b) { + return true + } + + if len(a) != len(b) { + return false + } + + for e := range a { + if _, ok := b[e]; !ok { + return false + } + } + + return true +} + // Nodes is a set of nodes keyed in their integer identifiers. -type Nodes map[int]graph.Node +type Nodes map[int64]graph.Node // The simple accessor methods for Nodes are provided to allow ease of // implementation change should the need arise. diff --git a/graph/internal/set/set_test.go b/graph/internal/set/set_test.go index 13984e14..f665b398 100644 --- a/graph/internal/set/set_test.go +++ b/graph/internal/set/set_test.go @@ -6,9 +6,9 @@ package set import "testing" -type node int +type node int64 -func (n node) ID() int { return int(n) } +func (n node) ID() int64 { return int64(n) } // count reports the number of elements stored in the node set. func (s Nodes) count() int {