diff --git a/sdks/storage/utils.go b/sdks/storage/utils.go new file mode 100644 index 0000000..39268dd --- /dev/null +++ b/sdks/storage/utils.go @@ -0,0 +1,13 @@ +package cdssdk + +import ( + "strings" +) + +func JoinObjectPath(comps ...string) string { + return strings.Join(comps, ObjectPathSeparator) +} + +func SplitObjectPath(pat string) []string { + return strings.Split(pat, ObjectPathSeparator) +} diff --git a/utils/sync2/token_pool.go b/utils/sync2/token_pool.go new file mode 100644 index 0000000..3fda84b --- /dev/null +++ b/utils/sync2/token_pool.go @@ -0,0 +1,60 @@ +package sync2 + +import "sync" + +type TokenPool[T any] struct { + tokens []T + cond *sync.Cond + closed bool +} + +func NewTokenPool[T any]() *TokenPool[T] { + return &TokenPool[T]{ + tokens: make([]T, 0), + cond: sync.NewCond(new(sync.Mutex)), + } +} + +func NewTokenPoolWithTokens[T any](tokens ...T) *TokenPool[T] { + b := NewTokenPool[T]() + b.tokens = append(b.tokens, tokens...) + return b +} + +func (b *TokenPool[T]) Take() (T, bool) { + b.cond.L.Lock() + defer b.cond.L.Unlock() + var ret T + + if b.closed { + return ret, false + } + + if len(b.tokens) == 0 { + b.cond.Wait() + + if len(b.tokens) == 0 { + return ret, false + } + } + + ret = b.tokens[0] + b.tokens = b.tokens[1:] + + return ret, true +} + +func (b *TokenPool[T]) Put(t T) { + b.cond.L.Lock() + b.tokens = append(b.tokens, t) + b.cond.L.Unlock() + b.cond.Signal() +} + +func (b *TokenPool[T]) Close() { + b.cond.L.Lock() + b.closed = true + b.cond.L.Unlock() + + b.cond.Broadcast() +}