Skip to content

Commit 92be7cb

Browse files
authored
Merge pull request #34 from laher/sets
Set + SortedSet with tests
2 parents ec8f139 + 6d484e5 commit 92be7cb

2 files changed

Lines changed: 272 additions & 0 deletions

File tree

sets.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package immutable
2+
3+
type Set[T comparable] struct {
4+
m *Map[T, struct{}]
5+
}
6+
7+
func NewSet[T comparable](hasher Hasher[T]) Set[T] {
8+
return Set[T]{
9+
m: NewMap[T, struct{}](hasher),
10+
}
11+
}
12+
13+
func (s Set[T]) Set(val T) Set[T] {
14+
return Set[T]{
15+
m: s.m.Set(val, struct{}{}),
16+
}
17+
}
18+
19+
func (s Set[T]) Delete(val T) Set[T] {
20+
return Set[T]{
21+
m: s.m.Delete(val),
22+
}
23+
}
24+
25+
func (s Set[T]) Has(val T) bool {
26+
_, ok := s.m.Get(val)
27+
return ok
28+
}
29+
30+
func (s Set[K]) Len() int {
31+
return s.m.Len()
32+
}
33+
34+
func (s Set[T]) Iterator() *SetIterator[T] {
35+
itr := &SetIterator[T]{mi: s.m.Iterator()}
36+
itr.mi.First()
37+
return itr
38+
}
39+
40+
type SetIterator[T comparable] struct {
41+
mi *MapIterator[T, struct{}]
42+
}
43+
44+
func (itr *SetIterator[T]) Done() bool {
45+
return itr.mi.Done()
46+
}
47+
48+
func (itr *SetIterator[T]) First() {
49+
itr.mi.First()
50+
}
51+
52+
func (itr *SetIterator[T]) Next() (val T, ok bool) {
53+
val, _, ok = itr.mi.Next()
54+
return
55+
}
56+
57+
type SetBuilder[T comparable] struct {
58+
s Set[T]
59+
}
60+
61+
func NewSetBuilder[T comparable](hasher Hasher[T]) *SetBuilder[T] {
62+
return &SetBuilder[T]{s: NewSet(hasher)}
63+
}
64+
65+
func (s SetBuilder[T]) Set(val T) {
66+
s.s.m = s.s.m.set(val, struct{}{}, true)
67+
}
68+
69+
func (s SetBuilder[T]) Delete(val T) {
70+
s.s.m = s.s.m.delete(val, true)
71+
}
72+
73+
func (s SetBuilder[T]) Has(val T) bool {
74+
return s.s.Has(val)
75+
}
76+
77+
func (s SetBuilder[T]) Len() int {
78+
return s.s.Len()
79+
}
80+
81+
type SortedSet[T comparable] struct {
82+
m *SortedMap[T, struct{}]
83+
}
84+
85+
func NewSortedSet[T comparable](comparer Comparer[T]) SortedSet[T] {
86+
return SortedSet[T]{
87+
m: NewSortedMap[T, struct{}](comparer),
88+
}
89+
}
90+
91+
func (s SortedSet[T]) Put(val T) SortedSet[T] {
92+
return SortedSet[T]{
93+
m: s.m.Set(val, struct{}{}),
94+
}
95+
}
96+
97+
func (s SortedSet[T]) Delete(val T) SortedSet[T] {
98+
return SortedSet[T]{
99+
m: s.m.Delete(val),
100+
}
101+
}
102+
103+
func (s SortedSet[T]) Has(val T) bool {
104+
_, ok := s.m.Get(val)
105+
return ok
106+
}
107+
108+
func (s SortedSet[K]) Len() int {
109+
return s.m.Len()
110+
}
111+
112+
func (s SortedSet[T]) Iterator() *SortedSetIterator[T] {
113+
itr := &SortedSetIterator[T]{mi: s.m.Iterator()}
114+
itr.mi.First()
115+
return itr
116+
}
117+
118+
type SortedSetIterator[T comparable] struct {
119+
mi *SortedMapIterator[T, struct{}]
120+
}
121+
122+
func (itr *SortedSetIterator[T]) Done() bool {
123+
return itr.mi.Done()
124+
}
125+
126+
func (itr *SortedSetIterator[T]) First() {
127+
itr.mi.First()
128+
}
129+
130+
func (itr *SortedSetIterator[T]) Last() {
131+
itr.mi.Last()
132+
}
133+
134+
func (itr *SortedSetIterator[T]) Next() (val T, ok bool) {
135+
val, _, ok = itr.mi.Next()
136+
return
137+
}
138+
139+
func (itr *SortedSetIterator[T]) Prev() (val T, ok bool) {
140+
val, _, ok = itr.mi.Prev()
141+
return
142+
}
143+
144+
func (itr *SortedSetIterator[T]) Seek(val T) {
145+
itr.mi.Seek(val)
146+
}
147+
148+
type SortedSetBuilder[T comparable] struct {
149+
s SortedSet[T]
150+
}
151+
152+
func NewSortedSetBuilder[T comparable](comparer Comparer[T]) *SortedSetBuilder[T] {
153+
return &SortedSetBuilder[T]{s: NewSortedSet(comparer)}
154+
}
155+
156+
func (s SortedSetBuilder[T]) Set(val T) {
157+
s.s.m = s.s.m.set(val, struct{}{}, true)
158+
}
159+
160+
func (s SortedSetBuilder[T]) Delete(val T) {
161+
s.s.m = s.s.m.delete(val, true)
162+
}
163+
164+
func (s SortedSetBuilder[T]) Has(val T) bool {
165+
return s.s.Has(val)
166+
}
167+
168+
func (s SortedSetBuilder[T]) Len() int {
169+
return s.s.Len()
170+
}

sets_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package immutable
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestSetsPut(t *testing.T) {
8+
s := NewSet[string](nil)
9+
s2 := s.Set("1").Set("1")
10+
if s.Len() != 0 {
11+
t.Fatalf("Unexpected mutation of set")
12+
}
13+
if s.Has("1") {
14+
t.Fatalf("Unexpected set element")
15+
}
16+
if s2.Len() != 1 {
17+
t.Fatalf("Unexpected non-mutation of set")
18+
}
19+
if !s2.Has("1") {
20+
t.Fatalf("Set element missing")
21+
}
22+
itr := s2.Iterator()
23+
counter := 0
24+
for !itr.Done() {
25+
i, v := itr.Next()
26+
t.Log(i, v)
27+
counter++
28+
}
29+
if counter != 1 {
30+
t.Fatalf("iterator wrong length")
31+
}
32+
}
33+
34+
func TestSetsDelete(t *testing.T) {
35+
s := NewSet[string](nil)
36+
s2 := s.Set("1")
37+
s3 := s.Delete("1")
38+
if s2.Len() != 1 {
39+
t.Fatalf("Unexpected non-mutation of set")
40+
}
41+
if !s2.Has("1") {
42+
t.Fatalf("Set element missing")
43+
}
44+
if s3.Len() != 0 {
45+
t.Fatalf("Unexpected set length after delete")
46+
}
47+
if s3.Has("1") {
48+
t.Fatalf("Unexpected set element after delete")
49+
}
50+
}
51+
52+
func TestSortedSetsPut(t *testing.T) {
53+
s := NewSortedSet[string](nil)
54+
s2 := s.Put("1").Put("1").Put("0")
55+
if s.Len() != 0 {
56+
t.Fatalf("Unexpected mutation of set")
57+
}
58+
if s.Has("1") {
59+
t.Fatalf("Unexpected set element")
60+
}
61+
if s2.Len() != 2 {
62+
t.Fatalf("Unexpected non-mutation of set")
63+
}
64+
if !s2.Has("1") {
65+
t.Fatalf("Set element missing")
66+
}
67+
68+
itr := s2.Iterator()
69+
counter := 0
70+
for !itr.Done() {
71+
i, v := itr.Next()
72+
t.Log(i, v)
73+
if counter == 0 && i != "0" {
74+
t.Fatalf("sort did not work for first el")
75+
}
76+
if counter == 1 && i != "1" {
77+
t.Fatalf("sort did not work for second el")
78+
}
79+
counter++
80+
}
81+
if counter != 2 {
82+
t.Fatalf("iterator wrong length")
83+
}
84+
}
85+
86+
func TestSortedSetsDelete(t *testing.T) {
87+
s := NewSortedSet[string](nil)
88+
s2 := s.Put("1")
89+
s3 := s.Delete("1")
90+
if s2.Len() != 1 {
91+
t.Fatalf("Unexpected non-mutation of set")
92+
}
93+
if !s2.Has("1") {
94+
t.Fatalf("Set element missing")
95+
}
96+
if s3.Len() != 0 {
97+
t.Fatalf("Unexpected set length after delete")
98+
}
99+
if s3.Has("1") {
100+
t.Fatalf("Unexpected set element after delete")
101+
}
102+
}

0 commit comments

Comments
 (0)