cleanup: example refactoring out map[string]struct{} using set.Set
This PR is a little demo of using github.com/hashicorp/go-set to replace the use of map[T]struct{} as a make-shift set.
This commit is contained in:
parent
ea38582b40
commit
93cfeb177b
1
go.mod
1
go.mod
|
@ -65,6 +65,7 @@ require (
|
|||
github.com/hashicorp/go-plugin v1.4.3
|
||||
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.4
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2
|
||||
github.com/hashicorp/go-set v0.1.2
|
||||
github.com/hashicorp/go-sockaddr v1.0.2
|
||||
github.com/hashicorp/go-syslog v1.0.0
|
||||
github.com/hashicorp/go-uuid v1.0.2
|
||||
|
|
2
go.sum
2
go.sum
|
@ -755,6 +755,8 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
|
|||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8=
|
||||
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs=
|
||||
github.com/hashicorp/go-set v0.1.2 h1:WqFkeT32zKiD/l7zwO1RLF4YwctJwp6IByML0LLa0os=
|
||||
github.com/hashicorp/go-set v0.1.2/go.mod h1:0jTQeDo6GKX0WMFUV4IicFkxXo9DuoRnUODngpsoYCk=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/armon/go-metrics"
|
||||
"github.com/hashicorp/go-memdb"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-set"
|
||||
"github.com/hashicorp/nomad/acl"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/nomad/state"
|
||||
|
@ -153,6 +154,27 @@ func (s *ServiceRegistration) DeleteByID(
|
|||
return nil
|
||||
}
|
||||
|
||||
// ServiceTagSet maps from a service name to a union of tags associated with that service.
|
||||
type ServiceTagSet map[string]*set.Set[string]
|
||||
|
||||
func (s ServiceTagSet) add(service string, tags []string) {
|
||||
if _, exists := s[service]; !exists {
|
||||
s[service] = set.From[string](tags)
|
||||
} else {
|
||||
s[service].InsertAll(tags)
|
||||
}
|
||||
}
|
||||
|
||||
// NamespaceServiceTagSet maps from a namespace to a ServiceTagSet
|
||||
type NamespaceServiceTagSet map[string]ServiceTagSet
|
||||
|
||||
func (s NamespaceServiceTagSet) add(namespace, service string, tags []string) {
|
||||
if _, exists := s[namespace]; !exists {
|
||||
s[namespace] = make(ServiceTagSet)
|
||||
}
|
||||
s[namespace].add(service, tags)
|
||||
}
|
||||
|
||||
// List is used to list service registration held within state. It supports
|
||||
// single and wildcard namespace listings.
|
||||
func (s *ServiceRegistration) List(
|
||||
|
@ -187,43 +209,21 @@ func (s *ServiceRegistration) List(
|
|||
return err
|
||||
}
|
||||
|
||||
// Track the unique tags found per service registration name.
|
||||
serviceTags := make(map[string]map[string]struct{})
|
||||
// Accumulate the set of tags associated with a particular service name.
|
||||
tagSet := make(ServiceTagSet)
|
||||
|
||||
for raw := iter.Next(); raw != nil; raw = iter.Next() {
|
||||
|
||||
serviceReg := raw.(*structs.ServiceRegistration)
|
||||
|
||||
// Identify and add any tags for the current service being
|
||||
// iterated into the map. If the tag has already been seen for
|
||||
// the same service, it will be overwritten ensuring no
|
||||
// duplicates.
|
||||
tags, ok := serviceTags[serviceReg.ServiceName]
|
||||
if !ok {
|
||||
serviceTags[serviceReg.ServiceName] = make(map[string]struct{})
|
||||
tags = serviceTags[serviceReg.ServiceName]
|
||||
}
|
||||
for _, tag := range serviceReg.Tags {
|
||||
tags[tag] = struct{}{}
|
||||
}
|
||||
tagSet.add(serviceReg.ServiceName, serviceReg.Tags)
|
||||
}
|
||||
|
||||
// Set the output result with the accumulated set of tags for each service.
|
||||
var serviceList []*structs.ServiceRegistrationStub
|
||||
|
||||
// Iterate the serviceTags map and populate our output result. This
|
||||
// endpoint handles a single namespace, so we do not need to
|
||||
// account for multiple.
|
||||
for service, tags := range serviceTags {
|
||||
|
||||
serviceStub := structs.ServiceRegistrationStub{
|
||||
for service, tags := range tagSet {
|
||||
serviceList = append(serviceList, &structs.ServiceRegistrationStub{
|
||||
ServiceName: service,
|
||||
Tags: make([]string, 0, len(tags)),
|
||||
}
|
||||
for tag := range tags {
|
||||
serviceStub.Tags = append(serviceStub.Tags, tag)
|
||||
}
|
||||
|
||||
serviceList = append(serviceList, &serviceStub)
|
||||
Tags: tags.List(),
|
||||
})
|
||||
}
|
||||
|
||||
// Correctly handle situations where a namespace was passed that
|
||||
|
@ -292,15 +292,11 @@ func (s *ServiceRegistration) listAllServiceRegistrations(
|
|||
return err
|
||||
}
|
||||
|
||||
// Track the unique tags found per namespace per service
|
||||
// registration name.
|
||||
namespacedServiceTags := make(map[string]map[string]map[string]struct{})
|
||||
// Accumulate the union of tags per service in each namespace.
|
||||
nsSvcTagSet := make(NamespaceServiceTagSet)
|
||||
|
||||
// Iterate all service registrations.
|
||||
for raw := iter.Next(); raw != nil; raw = iter.Next() {
|
||||
|
||||
// We need to assert the type here in order to check the
|
||||
// namespace.
|
||||
serviceReg := raw.(*structs.ServiceRegistration)
|
||||
|
||||
// Check whether the service registration is within a namespace
|
||||
|
@ -310,55 +306,30 @@ func (s *ServiceRegistration) listAllServiceRegistrations(
|
|||
continue
|
||||
}
|
||||
|
||||
// Identify and add any tags for the current namespaced service
|
||||
// being iterated into the map. If the tag has already been
|
||||
// seen for the same service, it will be overwritten ensuring
|
||||
// no duplicates.
|
||||
namespace, ok := namespacedServiceTags[serviceReg.Namespace]
|
||||
if !ok {
|
||||
namespacedServiceTags[serviceReg.Namespace] = make(map[string]map[string]struct{})
|
||||
namespace = namespacedServiceTags[serviceReg.Namespace]
|
||||
}
|
||||
tags, ok := namespace[serviceReg.ServiceName]
|
||||
if !ok {
|
||||
namespace[serviceReg.ServiceName] = make(map[string]struct{})
|
||||
tags = namespace[serviceReg.ServiceName]
|
||||
}
|
||||
for _, tag := range serviceReg.Tags {
|
||||
tags[tag] = struct{}{}
|
||||
}
|
||||
// Accumulate the set of tags associated with a particular service name in a particular namespace
|
||||
namespace, service, tags := serviceReg.Namespace, serviceReg.ServiceName, serviceReg.Tags
|
||||
nsSvcTagSet.add(namespace, service, tags)
|
||||
}
|
||||
|
||||
// Set up our output object. Start with zero size but allocate the
|
||||
// know length as we wil need to append whilst avoid slice growing.
|
||||
servicesOutput := make([]*structs.ServiceRegistrationListStub, 0, len(namespacedServiceTags))
|
||||
|
||||
for ns, serviceTags := range namespacedServiceTags {
|
||||
|
||||
var serviceList []*structs.ServiceRegistrationStub
|
||||
|
||||
// Iterate the serviceTags map and populate our output result.
|
||||
for service, tags := range serviceTags {
|
||||
|
||||
serviceStub := structs.ServiceRegistrationStub{
|
||||
// Create the service stubs, one per namespace, containing each service
|
||||
// in that namespace, and append that to the final tally of registrations.
|
||||
var registrations []*structs.ServiceRegistrationListStub
|
||||
for namespace, tagSet := range nsSvcTagSet {
|
||||
var stubs []*structs.ServiceRegistrationStub
|
||||
for service, tags := range tagSet {
|
||||
stubs = append(stubs, &structs.ServiceRegistrationStub{
|
||||
ServiceName: service,
|
||||
Tags: make([]string, 0, len(tags)),
|
||||
}
|
||||
for tag := range tags {
|
||||
serviceStub.Tags = append(serviceStub.Tags, tag)
|
||||
}
|
||||
|
||||
serviceList = append(serviceList, &serviceStub)
|
||||
Tags: tags.List(),
|
||||
})
|
||||
}
|
||||
|
||||
servicesOutput = append(servicesOutput, &structs.ServiceRegistrationListStub{
|
||||
Namespace: ns,
|
||||
Services: serviceList,
|
||||
registrations = append(registrations, &structs.ServiceRegistrationListStub{
|
||||
Namespace: namespace,
|
||||
Services: stubs,
|
||||
})
|
||||
}
|
||||
|
||||
// Add the output to the reply object.
|
||||
reply.Services = servicesOutput
|
||||
// Set the output on the reply object.
|
||||
reply.Services = registrations
|
||||
|
||||
// Use the index table to populate the query meta as we have no way
|
||||
// of tracking the max index on deletes.
|
||||
|
|
Loading…
Reference in New Issue