182
vendor/github.com/anacrolix/stm/stmutil/containers.go
generated
vendored
Normal file
182
vendor/github.com/anacrolix/stm/stmutil/containers.go
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
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
|
||||
}
|
||||
|
||||
type List = *immutable.List
|
||||
39
vendor/github.com/anacrolix/stm/stmutil/context.go
generated
vendored
Normal file
39
vendor/github.com/anacrolix/stm/stmutil/context.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package stmutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/anacrolix/stm"
|
||||
)
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
ctxVars = map[context.Context]*stm.Var{}
|
||||
)
|
||||
|
||||
// Returns an STM var that contains a bool equal to `ctx.Err != nil`, and a cancel function to be
|
||||
// called when the user is no longer interested in the var.
|
||||
func ContextDoneVar(ctx context.Context) (*stm.Var, func()) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if v, ok := ctxVars[ctx]; ok {
|
||||
return v, func() {}
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
// TODO: What if we had read-only Vars? Then we could have a global one for this that we
|
||||
// just reuse.
|
||||
v := stm.NewBuiltinEqVar(true)
|
||||
return v, func() {}
|
||||
}
|
||||
v := stm.NewVar(false)
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
stm.AtomicSet(v, true)
|
||||
mu.Lock()
|
||||
delete(ctxVars, ctx)
|
||||
mu.Unlock()
|
||||
}()
|
||||
ctxVars[ctx] = v
|
||||
return v, func() {}
|
||||
}
|
||||
Reference in New Issue
Block a user