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
103 changes: 46 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,48 @@
The `go-set` repository provides a `set` package containing a few
generic [Set](https://en.wikipedia.org/wiki/Set) implementations for Go.

---

**PSA** October 2023 - The v2 version of this package has been published, starting at
tag version `v2.0.0`. A description of the changes including backwards incompatibilities
can be found in https://github.com/hashicorp/go-set/issues/73

---

Each implementation is optimal for a particular use case.

`Set` is ideal for `comparable` types.
**Set[T]** is ideal for `comparable` types.
- backed by `map` builtin
- commonly used with `string`, `int`, simple `struct` types, etc.

`HashSet` is useful for types that implement a `Hash()` function.
**HashSet[T]** is useful for types that implement a `Hash()` function.
- backed by `map` builtin
- commonly used with complex structs
- also works with custom `HashFunc[T]` implementations

`TreeSet` is useful for comparable data (via `Compare[T]`)
**TreeSet[T]** is useful for comparable data (via `CompareFunc[T]`)
- backed by Red-Black Binary Search Tree
- commonly used with complex structs with extrinsic order
- efficient iteration in sort order
- additional methods `Min` / `Max` / `TopK` / `BottomK`

This package is not thread-safe.

---

# Documentation

The full documentation is available on [pkg.go.dev](https://pkg.go.dev/github.com/hashicorp/go-set).
The full `go-set` package reference is available on [pkg.go.dev](https://pkg.go.dev/github.com/hashicorp/go-set).

# Install

```shell
go get github.com/hashicorp/go-set/v2@latest
```

```shell
import "github.com/hashicorp/go-set/v2"
```

# Motivation

Expand Down Expand Up @@ -78,63 +99,31 @@ implement an efficient hash function using a hash code based on prime multiples.

The `go-set` package includes `TreeSet` for creating sorted sets. A `TreeSet` may
be used with any type `T` as the comparison between elements is provided by implementing
`Compare[T]`. The `Cmp[builtin]` helper provides a convenient implementation of
`Compare` for `builtin` types like `string` or `int`. A `TreeSet` is backed by
`CompareFunc[T]`. The `Compare[GoType]` helper provides a convenient implementation of
`CompareFunc` for `builtin` types like `string` or `int`. A `TreeSet` is backed by
an underlying balanced binary search tree, making operations like in-order traversal
efficient, in addition to enabling functions like `Min()`, `Max()`, `TopK()`, and
`BottomK()`.

# Collection[T]

### Methods

Implements the following set operations

- Insert
- InsertSlice
- InsertSet
- Remove
- RemoveSlice
- RemoveSet
- RemoveFunc
- Contains
- ContainsAll
- ContainsSlice
- Subset
- Size
- Empty
- Union
- Difference
- Intersect

Provides helper methods

- Equal
- Copy
- Slice
- String

TreeSet helper methods
- Min
- Max
- TopK
- BottomK
- FirstAbove
- FirstAboveEqual
- Above
- AboveEqual
- FirstBelow
- FirstBelowEqual
- Below
- BelowEqual
The `Collection[T]` interface is implemented by each of `Set`, `HashSet`, and `TreeSet`.

# Install
It serves as a useful abstraction over the common methods implemented by each set type.

```
go get github.com/hashicorp/go-set@latest
```
### Iteration

```
import "github.com/hashicorp/go-set"
Go still has no support for using `range` over user defined types. Until that becomes
possible, each of `Set`, `HashSet`, and `TreeSet` implements a `ForEach` method for
iterating each element in a set. The argument is a function that accepts an item from
the set and returns a boolean, indicating whether iteration should be halted.

```go
// e.g. print each item in the set
s.ForEach(func(item T) bool {
fmt.Println(item)
return true
})
```

# Set Examples
Expand Down Expand Up @@ -204,14 +193,14 @@ s.Insert(e1)

Below are simple example usages of `TreeSet`

(using `Cmp` as `Compare`)
(using the `Compare` helper to compare a built in `GoType`)

```go
ts := NewTreeSet[int, Compare[int]](Cmp[int])
ts := NewTreeSet[int](Compare[int])
ts.Insert(5)
```

(using custom `Compare`)
(using a custom `CompareFunc`)

```go
type waypoint struct {
Expand All @@ -223,7 +212,7 @@ cmp := func(w1, w2 *waypoint) int {
return w1.distance - w2.distance
}

ts := NewTreeSet[*waypoint, Compare[*waypoint]](cmp)
ts := NewTreeSet[*waypoint](cmp)
ts.Insert(&waypoint{distance: 42, name: "tango"})
ts.Insert(&waypoint{distance: 13, name: "alpha"})
ts.Insert(&waypoint{distance: 71, name: "xray"})
Expand Down
6 changes: 3 additions & 3 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func BenchmarkHashSet_Insert(b *testing.B) {

func BenchmarkTreeSet_Insert(b *testing.B) {
for _, tc := range cases {
ts := TreeSetFrom[int, Compare[int]](random[int](tc.size), Cmp[int])
ts := TreeSetFrom[int](random[int](tc.size), Compare[int])
b.Run(tc.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
ts.Insert(i)
Expand Down Expand Up @@ -125,7 +125,7 @@ func BenchmarkHashSet_Minimum(b *testing.B) {

func BenchmarkTreeSet_Minimum(b *testing.B) {
for _, tc := range cases {
ts := TreeSetFrom[int, Compare[int]](random[int](tc.size), Cmp[int])
ts := TreeSetFrom[int](random[int](tc.size), Compare[int])
b.Run(tc.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = ts.Min()
Expand Down Expand Up @@ -178,7 +178,7 @@ func BenchmarkHashSet_Contains(b *testing.B) {

func BenchmarkTreeSet_Contains(b *testing.B) {
for _, tc := range cases {
ts := TreeSetFrom[int, Compare[int]](random[int](tc.size), Cmp[int])
ts := TreeSetFrom[int](random[int](tc.size), Compare[int])
b.Run(tc.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = ts.Contains(i)
Expand Down
Loading