The deriveUnique function is useful for returning a list of unique items, when these items are not basic enough to be map keys.
Given the following input:
package unique
type Visitor struct {
UserName *string
RemoteAddr string
}
func uniqueVisitors(vs []*Visitor) int {
return len(deriveUnique(vs))
}
goderive will generate the following code:
// Code generated by goderive DO NOT EDIT.
package unique
// deriveUnique returns a list containing only the unique items from the input list.
// It does this by reusing the input list.
func deriveUnique(list []*Visitor) []*Visitor {
if len(list) == 0 {
return nil
}
table := make(map[uint64][]int)
u := 0
for i := 0; i < len(list); i++ {
contains := false
hash := deriveHash(list[i])
indexes := table[hash]
for _, index := range indexes {
if deriveEqual(list[index], list[i]) {
contains = true
break
}
}
if contains {
continue
}
if i != u {
list[u] = list[i]
}
table[hash] = append(table[hash], u)
u++
}
return list[:u]
}
// deriveEqual returns whether this and that are equal.
func deriveEqual(this, that *Visitor) bool {
return (this == nil && that == nil) ||
this != nil && that != nil &&
((this.UserName == nil && that.UserName == nil) || (this.UserName != nil && that.UserName != nil && *(this.UserName) == *(that.UserName))) &&
this.RemoteAddr == that.RemoteAddr
}
// deriveHash returns the hash of the object.
func deriveHash(object *Visitor) uint64 {
if object == nil {
return 0
}
h := uint64(17)
h = 31*h + deriveHash_(object.UserName)
h = 31*h + deriveHash_s(object.RemoteAddr)
return h
}
// deriveHash_ returns the hash of the object.
func deriveHash_(object *string) uint64 {
if object == nil {
return 0
}
return (31 * 17) + deriveHash_s(*object)
}
// deriveHash_s returns the hash of the object.
func deriveHash_s(object string) uint64 {
var h uint64
for _, c := range object {
h = 31*h + uint64(c)
}
return h
}