Skip to content

Commit

Permalink
Dev client interface for hash and equal (#34)
Browse files Browse the repository at this point in the history
* add HashSetC constructor

* add HashMapC constructor

* add MultiMapC constructor
  • Loading branch information
Cause Chung authored Dec 8, 2022
1 parent 880ff2d commit b4797e9
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ hashMap := collections.NewHashMapOfStrKey[int](EntryOf("Earth", 3), EntryOf("Mar
cache := collections.NewLRUCacheOfStrKey[int](40, collections.PutOrder + collections.GetOrder) // LRU cache[string, int] of size limit 40
// more...
```
Client implementation of [constraint interfaces](types/interfaces.go) to simplify collection creation:
```go
type myStruct struct {...}
func (s *myStruct) Hash() uint {...}
func (s *myStruct) Equal(other *myStruct) bool {...}
hashSet := collections.NewHashSetC[*myStruct]()
```

### Functional Transformation

Expand Down
8 changes: 8 additions & 0 deletions collections/defs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ type intStruct struct {

var compInt = funcs.ValueCompare[int]
var eqInt = funcs.ValueEqual[int]

func (s *intStruct) Hash() uint {
return funcs.NumHash(s.v)
}

func (s *intStruct) Equal(other *intStruct) bool {
return s.v == other.v
}
7 changes: 7 additions & 0 deletions collections/maps.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ func NewTreeMapOfComp[K any, V any](comp types.Compare[K], entries ...types.Entr
return m
}

// NewHashMapC creates a hash map with a constrained key type that implements custom Hash and Equal
func NewHashMapC[K types.HashAndEqual[K], V any]() types.Map[K, V] {
hs := func(key K) uint { return key.Hash() }
eq := func(a, b K) bool { return a.Equal(b) }
return newHashMap[K, V](hs, eq)
}

// NewHashMapOf creates a hash map with custom Hash and Equal functions, and init values.
func NewHashMapOf[K any, V any](hs types.Hash[K], eq types.Equal[K], entries ...types.Entry[K, V]) types.Map[K, V] {
m := newHashMap[K, V](hs, eq)
Expand Down
9 changes: 9 additions & 0 deletions collections/maps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,12 @@ func TestLRUCacheOfStrKey_Properties(t *testing.T) {
})
}
}

func TestHashMapConstraintInterface(t *testing.T) {
m := NewHashMapC[*intStruct, int]()
k1 := &intStruct{3}
m.Put(k1, 2)
assert.Equal(t, 1, m.Size())
k2 := &intStruct{3}
assert.True(t, m.ContainsKey(k2))
}
23 changes: 23 additions & 0 deletions collections/multimaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import (
"golang.org/x/exp/constraints"
)

// NewArrayListMultiMapC creates a hash multimap with a constrained key type that implements custom Hash and Equal
func NewArrayListMultiMapC[K types.HashAndEqual[K], V any]() types.MultiMap[K, V] {
hs := func(key K) uint { return key.Hash() }
eq := func(a, b K) bool { return a.Equal(b) }
return newArrayListMultiMap[K, V](hs, eq)
}

// NewArrayListMultiMapOf creates a hash multimap with custom Hash and Equal functions, and init values.
func NewArrayListMultiMapOf[K any, V any](hs types.Hash[K], eq types.Equal[K], entries ...types.Entry[K, types.Collection[V]]) types.MultiMap[K, V] {
mm := newArrayListMultiMap[K, V](hs, eq)
Expand All @@ -28,6 +35,22 @@ func NewArrayListMultiMapOfNumKey[K constraints.Integer | constraints.Float, V a
return mm
}

// NewHashSetMultiMapC creates a hash multimap with a constrained key type that implements custom Hash and Equal
func NewHashSetMultiMapC[K types.HashAndEqual[K], V any](vhs types.Hash[V], veq types.Equal[V]) types.MultiMap[K, V] {
khs := func(key K) uint { return key.Hash() }
keq := func(a, b K) bool { return a.Equal(b) }
return newHashSetMultiMap[K, V](khs, keq, vhs, veq)
}

// NewHashSetMultiMapCC creates a hash multimap with constrained key and value types that implements custom Hash and Equal
func NewHashSetMultiMapCC[K types.HashAndEqual[K], V types.HashAndEqual[V]]() types.MultiMap[K, V] {
khs := func(key K) uint { return key.Hash() }
keq := func(a, b K) bool { return a.Equal(b) }
vhs := func(v V) uint { return v.Hash() }
veq := func(a, b V) bool { return a.Equal(b) }
return newHashSetMultiMap[K, V](khs, keq, vhs, veq)
}

// NewHashSetMultiMapOf creates a hash multimap with custom Hash and Equal functions, and init values.
func NewHashSetMultiMapOf[K any, V any](khs types.Hash[K], keq types.Equal[K], vhs types.Hash[V], veq types.Equal[V],
entries ...types.Entry[K, types.Collection[V]]) types.MultiMap[K, V] {
Expand Down
23 changes: 23 additions & 0 deletions collections/multimaps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,26 @@ func TestNewHashSetMultiMapOfStrKey_Properties(t *testing.T) {
assert.True(t, found)
assert.ElementsMatch(t, []int{1, 2}, utils.SliceFrom[int](l))
}

func TestArrayListMultiMapConstraintInterface(t *testing.T) {
m := NewArrayListMultiMapC[*intStruct, int]()
k1 := &intStruct{3}
m.PutSingle(k1, 2)
assert.Equal(t, 1, m.Size())
k2 := &intStruct{3}
assert.True(t, m.ContainsKey(k2))
}

func TestHashSetMultiMapConstraintInterface(t *testing.T) {
m := NewHashSetMultiMapC[*intStruct, int](funcs.NumHash[int], funcs.ValueEqual[int])
k1 := &intStruct{3}
m.PutSingle(k1, 2)
assert.Equal(t, 1, m.Size())
k2 := &intStruct{3}
assert.True(t, m.ContainsKey(k2))

m2 := NewHashSetMultiMapCC[*intStruct, *intStruct]()
m2.PutSingle(k1, &intStruct{33})
m2.PutSingle(k1, &intStruct{33})
assert.Equal(t, 1, m2.Size())
}
7 changes: 7 additions & 0 deletions collections/sets.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ func NewHashSet[T any](hs types.Hash[T], eq types.Equal[T]) types.Set[T] {
return newHashTable[T](hs, eq)
}

// NewHashSetC creates a hash table with a constrained type that implements custom Hash and Equal
func NewHashSetC[T types.HashAndEqual[T]]() types.Set[T] {
hs := func(elem T) uint { return elem.Hash() }
eq := func(a, b T) bool { return a.Equal(b) }
return newHashTable[T](hs, eq)
}

// NewHashSetOfNum creates a hash table backed set with values, see funcs.NumHash
func NewHashSetOfNum[T constraints.Integer | constraints.Float](values ...T) types.Set[T] {
h := newHashTable[T](funcs.NumHash[T], funcs.ValueEqual[T])
Expand Down
9 changes: 9 additions & 0 deletions collections/sets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,12 @@ func TestSetOfStrProperties(t *testing.T) {
}

}

func TestHashSetConstraintInterface(t *testing.T) {
set := NewHashSetC[*intStruct]()
s1 := &intStruct{3}
set.Add(s1)
assert.Equal(t, 1, set.Size())
s2 := &intStruct{3}
assert.True(t, set.Contains(s2))
}
6 changes: 6 additions & 0 deletions types/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package types

type HashAndEqual[T any] interface {
Hash() uint
Equal(other T) bool
}

0 comments on commit b4797e9

Please sign in to comment.