Skip to content

Commit

Permalink
Data structures for tag manipulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Haeusler committed Feb 24, 2019
1 parent 4141da1 commit 10b51e2
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ build: $(binary_name)
$(binary_name): $(wildcard **/*.go)
go build

.PHONY: protobuf
protobuf: tag/internal/bilocation.pb.go

tag/internal/bilocation.pb.go: bilocation.proto
mkdir -p $(@D)
protoc --go_out=$(@D) $<

.PHONY: clean
clean:
rm -rf $(binary_name) $(cover_file)
12 changes: 12 additions & 0 deletions bilocation.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
syntax = "proto3";

package internal;

message Set {
repeated Tag tags = 1;
}

message Tag {
string name = 1;
repeated string classifiers = 2;
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ require (
github.com/bketelsen/logr v0.0.0-20170116012416-f3d070bdd1c5
github.com/corvus-ch/logr v0.0.0-20180917163152-45217966b77e
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.2.0
github.com/sebdah/goldie v0.0.0-20180424091453-8784dd1ab561
github.com/stretchr/testify v1.3.0
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sebdah/goldie v0.0.0-20180424091453-8784dd1ab561 h1:IY+sDBJR/wRtsxq+626xJnt4Tw7/ROA9cDIR8MMhWyg=
github.com/sebdah/goldie v0.0.0-20180424091453-8784dd1ab561/go.mod h1:lvjGftC8oe7XPtyrOidaMi0rp5B9+XY/ZRUynGnuaxQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
Empty file added tag/fixtures/empty.golden
Empty file.
3 changes: 3 additions & 0 deletions tag/fixtures/name.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


test name
3 changes: 3 additions & 0 deletions tag/fixtures/name_classifier.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@


test namefirst classifier
3 changes: 3 additions & 0 deletions tag/fixtures/name_classifiers.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

0
test namefirst classifiersecond classifier
123 changes: 123 additions & 0 deletions tag/internal/bilocation.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions tag/set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package tag

import (
"github.com/corvus-ch/bilocation/tag/internal"
"github.com/golang/protobuf/proto"
)

// Set implements a set data structure for file tags.
// Inspired by https://gist.github.com/bgadrian/cb8b9344d9c66571ef331a14eb7a2e80.
type Set map[string]map[string]struct{}

// NewTagSet returns a new tag set populated with the data read from the protocol buffer wire format data.
func NewTagSet(data []byte) (Set, error) {
tags := &internal.Set{}
err := proto.Unmarshal(data, tags)
if err != nil {
return nil, err
}

s := Set{}

for _, tag := range tags.Tags {
s.Add(tag.Name, tag.Classifiers...)
}

return s, nil
}

// Has checks if name is present in the set.
func (s Set) Has(name string) bool {
_, ok := s[name]
return ok
}

// HasClassifier checks if the name and classifier pair is present in the set.
func (s Set) HasClassifier(name, classifier string) bool {
_, ok := s[name][classifier]
return ok
}

// Read returns the list of classifiers for name.
func (s Set) Get(name string) []string {
t, ok := s[name]
if !ok {
return make([]string, 0)
}

r := make([]string, 0, len(t))

for c, _ := range t {
r = append(r, c)
}

return r
}

// Add adds name with an optional list of classifiers to the set.
func (s Set) Add(name string, classifiers ...string) {
if _, ok := s[name]; !ok {
s[name] = make(map[string]struct{}, len(classifiers))
}

for _, classifier := range classifiers {
if _, ok := s[name][classifier]; !ok {
s[name][classifier] = struct{}{}
}
}
}

// Del deletes name with all its classifiers.
func (s Set) Del(name string) {
delete(s, name)
}

// DelClassifier removes the classifier from name.
func (s Set) DelClassifier(name, classifier string) {
if data, ok := s[name]; ok {
delete(data, classifier)
if len(data) == 0 {
delete(s, name)
}
}
}

// Size returns the number of tags in the set.
func (s Set) Size() int {
return len(s)
}

// Bytes returns the set in the protocol buffer wire format.
func (s Set) Bytes() ([]byte, error) {
set := &internal.Set{}
set.Tags = make([]*internal.Tag, 0, s.Size())

for name, classifiers := range s {
tag := &internal.Tag{Name: name}
tag.Classifiers = make([]string, 0, len(classifiers))
for classifier, _ := range classifiers {
if len(classifier) > 0 {
tag.Classifiers = append(tag.Classifiers, classifier)
}
}
set.Tags = append(set.Tags, tag)
}
return proto.Marshal(set)
}
Loading

0 comments on commit 10b51e2

Please sign in to comment.