Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions pkg/stringset/stringset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
Copyright The CloudNativePG Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package stringset implements a basic set of strings
package stringset

import (
"slices"
)

// Data represent a set of strings
type Data struct {
innerMap map[string]struct{}
}

// New create a new empty set of strings
func New() *Data {
return &Data{
innerMap: make(map[string]struct{}),
}
}

// From create a empty set of strings given
// a slice of strings
func From(strings []string) *Data {
result := New()
for _, value := range strings {
result.Put(value)
}
return result
}

// FromKeys create a string set from the
// keys of a map
func FromKeys[T any](v map[string]T) *Data {
result := New()
for key := range v {
result.Put(key)
}
return result
}

// Put a string in the set
func (set *Data) Put(key string) {
set.innerMap[key] = struct{}{}
}

// Delete deletes a string from the set. If the string doesn't exist
// this is a no-op
func (set *Data) Delete(key string) {
delete(set.innerMap, key)
}

// Has checks if a string is in the set or not
func (set *Data) Has(key string) bool {
_, ok := set.innerMap[key]
return ok
}

// Len returns the map of the set
func (set *Data) Len() int {
return len(set.innerMap)
}

// ToList returns the strings contained in this set as
// a string slice
func (set *Data) ToList() (result []string) {
result = make([]string, 0, len(set.innerMap))
for key := range set.innerMap {
result = append(result, key)
}
return
}

// ToSortedList returns the string container in this set
// as a sorted string slice
func (set *Data) ToSortedList() []string {
result := set.ToList()
slices.Sort(result)
return result
}

// Eq compares two string sets for equality
func (set *Data) Eq(other *Data) bool {
if set == nil || other == nil {
return false
}

if set.Len() != other.Len() {
return false
}

for key := range set.innerMap {
if !other.Has(key) {
return false
}
}

return true
}
76 changes: 76 additions & 0 deletions pkg/stringset/stringset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright The CloudNativePG Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package stringset

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("String set", func() {
It("starts as an empty set", func() {
Expect(New().Len()).To(Equal(0))
})

It("starts with a list of strings", func() {
Expect(From([]string{"one", "two"}).Len()).To(Equal(2))
Expect(From([]string{"one", "two", "two"}).Len()).To(Equal(2))
})

It("store string keys", func() {
set := New()
Expect(set.Has("test")).To(BeFalse())
Expect(set.Has("test2")).To(BeFalse())

set.Put("test")
Expect(set.Has("test")).To(BeTrue())
Expect(set.Has("test2")).To(BeFalse())
})

It("removes string keys", func() {
set := From([]string{"one", "two"})
set.Delete("one")
Expect(set.ToList()).To(Equal([]string{"two"}))
})

It("constructs a string slice given a set", func() {
Expect(From([]string{"one", "two"}).ToList()).To(ContainElements("one", "two"))
})

It("compares two string set for equality", func() {
Expect(From([]string{"one", "two"}).Eq(From([]string{"one", "two"}))).To(BeTrue())
Expect(From([]string{"one", "two"}).Eq(From([]string{"two", "three"}))).To(BeFalse())
Expect(From([]string{"one", "two"}).Eq(From([]string{"one", "two", "three"}))).To(BeFalse())
Expect(From([]string{"one", "two", "three"}).Eq(From([]string{"one", "two"}))).To(BeFalse())
})

It("constructs a sorted string slice given a set", func() {
Expect(From([]string{"one", "two", "three", "four"}).ToSortedList()).To(
HaveExactElements("four", "one", "three", "two"))
Expect(New().ToList()).To(BeEmpty())
})

It("constructs a string set from a map having string as keys", func() {
Expect(FromKeys(map[string]int{
"one": 1,
"two": 2,
"three": 3,
}).ToSortedList()).To(
HaveExactElements("one", "three", "two"),
)
})
})
33 changes: 33 additions & 0 deletions pkg/stringset/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright The CloudNativePG Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package stringset

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.

func TestConfigFile(t *testing.T) {
RegisterFailHandler(Fail)

RunSpecs(t, "Configuration File Parsing Suite")
}