aboutsummaryrefslogtreecommitdiff
path: root/stmutil/containers.go
diff options
context:
space:
mode:
authorMatt Joiner <anacrolix@gmail.com>2019-11-01 12:23:59 +1100
committerMatt Joiner <anacrolix@gmail.com>2019-11-01 12:23:59 +1100
commit52e150e44234b631f8a9b2de11862434046b4992 (patch)
treeb57bdf74630b62e2c2dfebe45569cc7da94838be /stmutil/containers.go
parentOptimize a bunch of stuff (diff)
downloadstm-52e150e44234b631f8a9b2de11862434046b4992.tar.gz
stm-52e150e44234b631f8a9b2de11862434046b4992.tar.xz
Add stmutil containers and ContextDoneVar
Diffstat (limited to 'stmutil/containers.go')
-rw-r--r--stmutil/containers.go180
1 files changed, 180 insertions, 0 deletions
diff --git a/stmutil/containers.go b/stmutil/containers.go
new file mode 100644
index 0000000..89f7b05
--- /dev/null
+++ b/stmutil/containers.go
@@ -0,0 +1,180 @@
+package stmutil
+
+import (
+ "unsafe"
+
+ "github.com/benbjohnson/immutable"
+
+ "github.com/anacrolix/missinggo/v2/iter"
+)
+
+type Settish interface {
+ Add(interface{}) Settish
+ Delete(interface{}) Settish
+ Contains(interface{}) bool
+ Range(func(interface{}) bool)
+ iter.Iterable
+ Len() int
+}
+
+type mapToSet struct {
+ m Mappish
+}
+
+type interhash struct{}
+
+func (interhash) Hash(x interface{}) uint32 {
+ return uint32(nilinterhash(unsafe.Pointer(&x), 0))
+}
+
+func (interhash) Equal(i, j interface{}) bool {
+ return i == j
+}
+
+func NewSet() Settish {
+ return mapToSet{NewMap()}
+}
+
+func NewSortedSet(lesser lessFunc) Settish {
+ return mapToSet{NewSortedMap(lesser)}
+}
+
+func (s mapToSet) Add(x interface{}) Settish {
+ s.m = s.m.Set(x, nil)
+ return s
+}
+
+func (s mapToSet) Delete(x interface{}) Settish {
+ s.m = s.m.Delete(x)
+ return s
+}
+
+func (s mapToSet) Len() int {
+ return s.m.Len()
+}
+
+func (s mapToSet) Contains(x interface{}) bool {
+ _, ok := s.m.Get(x)
+ return ok
+}
+
+func (s mapToSet) Range(f func(interface{}) bool) {
+ s.m.Range(func(k, _ interface{}) bool {
+ return f(k)
+ })
+}
+
+func (s mapToSet) Iter(cb iter.Callback) {
+ s.Range(cb)
+}
+
+type Map struct {
+ *immutable.Map
+}
+
+func NewMap() Mappish {
+ return Map{immutable.NewMap(interhash{})}
+}
+
+var _ Mappish = Map{}
+
+func (m Map) Delete(x interface{}) Mappish {
+ m.Map = m.Map.Delete(x)
+ return m
+}
+
+func (m Map) Set(key, value interface{}) Mappish {
+ m.Map = m.Map.Set(key, value)
+ return m
+}
+
+func (sm Map) Range(f func(key, value interface{}) bool) {
+ iter := sm.Map.Iterator()
+ for !iter.Done() {
+ if !f(iter.Next()) {
+ return
+ }
+ }
+}
+
+func (sm Map) Iter(cb iter.Callback) {
+ sm.Range(func(key, _ interface{}) bool {
+ return cb(key)
+ })
+}
+
+type SortedMap struct {
+ *immutable.SortedMap
+}
+
+func (sm SortedMap) Set(key, value interface{}) Mappish {
+ sm.SortedMap = sm.SortedMap.Set(key, value)
+ return sm
+}
+
+func (sm SortedMap) Delete(key interface{}) Mappish {
+ sm.SortedMap = sm.SortedMap.Delete(key)
+ return sm
+}
+
+func (sm SortedMap) Range(f func(key, value interface{}) bool) {
+ iter := sm.SortedMap.Iterator()
+ for !iter.Done() {
+ if !f(iter.Next()) {
+ return
+ }
+ }
+}
+
+func (sm SortedMap) Iter(cb iter.Callback) {
+ sm.Range(func(key, _ interface{}) bool {
+ return cb(key)
+ })
+}
+
+type lessFunc func(l, r interface{}) bool
+
+type comparer struct {
+ less lessFunc
+}
+
+func (me comparer) Compare(i, j interface{}) int {
+ if me.less(i, j) {
+ return -1
+ } else if me.less(j, i) {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+func NewSortedMap(less lessFunc) Mappish {
+ return SortedMap{
+ SortedMap: immutable.NewSortedMap(comparer{less}),
+ }
+}
+
+type Mappish interface {
+ Set(key, value interface{}) Mappish
+ Delete(key interface{}) Mappish
+ Get(key interface{}) (interface{}, bool)
+ Range(func(_, _ interface{}) bool)
+ Len() int
+ iter.Iterable
+}
+
+func GetLeft(l, _ interface{}) interface{} {
+ return l
+}
+
+//go:noescape
+//go:linkname nilinterhash runtime.nilinterhash
+func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
+
+func interfaceHash(x interface{}) uint32 {
+ return uint32(nilinterhash(unsafe.Pointer(&x), 0))
+}
+
+type Lenner interface {
+ Len() int
+}