2021-09-11 19:12:47 +00:00
|
|
|
package kv
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2021-12-20 09:35:32 +00:00
|
|
|
"sync"
|
2021-09-11 19:12:47 +00:00
|
|
|
|
2021-11-13 11:29:08 +00:00
|
|
|
"codeberg.org/gruf/go-errors"
|
2021-09-11 19:12:47 +00:00
|
|
|
)
|
|
|
|
|
2021-11-13 11:29:08 +00:00
|
|
|
var ErrStateClosed = errors.New("store/kv: state closed")
|
2021-09-11 19:12:47 +00:00
|
|
|
|
|
|
|
// StateRO provides a read-only window to the store. While this
|
|
|
|
// state is active during the Read() function window, the entire
|
|
|
|
// store will be read-locked. The state is thread-safe for concurrent
|
|
|
|
// use UNTIL the moment that your supplied function to Read() returns,
|
|
|
|
// then the state has zero guarantees
|
|
|
|
type StateRO struct {
|
|
|
|
store *KVStore
|
2021-12-20 09:35:32 +00:00
|
|
|
mutex sync.RWMutex
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRO) Get(key string) ([]byte, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return nil, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.get(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRO) GetStream(key string) (io.ReadCloser, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return nil, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.getStream(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRO) Has(key string) (bool, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return false, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.has(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
2021-12-20 09:35:32 +00:00
|
|
|
func (st *StateRO) Release() {
|
|
|
|
// Get state write lock
|
|
|
|
st.mutex.Lock()
|
|
|
|
defer st.mutex.Unlock()
|
|
|
|
|
|
|
|
// Release the store
|
|
|
|
if st.store != nil {
|
|
|
|
st.store.mutex.RUnlock()
|
|
|
|
st.store = nil
|
|
|
|
}
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// StateRW provides a read-write window to the store. While this
|
|
|
|
// state is active during the Update() function window, the entire
|
|
|
|
// store will be locked. The state is thread-safe for concurrent
|
|
|
|
// use UNTIL the moment that your supplied function to Update() returns,
|
|
|
|
// then the state has zero guarantees
|
|
|
|
type StateRW struct {
|
|
|
|
store *KVStore
|
2021-12-20 09:35:32 +00:00
|
|
|
mutex sync.RWMutex
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) Get(key string) ([]byte, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return nil, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.get(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) GetStream(key string) (io.ReadCloser, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return nil, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.getStream(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) Put(key string, value []byte) error {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.put(st.store.mutexMap.Lock, key, value)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) PutStream(key string, r io.Reader) error {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.putStream(st.store.mutexMap.Lock, key, r)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) Has(key string) (bool, error) {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return false, ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.has(st.store.mutexMap.RLock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (st *StateRW) Delete(key string) error {
|
2021-12-20 09:35:32 +00:00
|
|
|
// Get state read lock
|
|
|
|
st.mutex.RLock()
|
|
|
|
defer st.mutex.RUnlock()
|
|
|
|
|
2021-09-11 19:12:47 +00:00
|
|
|
// Check not closed
|
|
|
|
if st.store == nil {
|
|
|
|
return ErrStateClosed
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pass request to store
|
2022-01-16 17:52:30 +00:00
|
|
|
return st.store.delete(st.store.mutexMap.Lock, key)
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|
|
|
|
|
2021-12-20 09:35:32 +00:00
|
|
|
func (st *StateRW) Release() {
|
|
|
|
// Get state write lock
|
|
|
|
st.mutex.Lock()
|
|
|
|
defer st.mutex.Unlock()
|
|
|
|
|
|
|
|
// Release the store
|
|
|
|
if st.store != nil {
|
|
|
|
st.store.mutex.Unlock()
|
|
|
|
st.store = nil
|
|
|
|
}
|
2021-09-11 19:12:47 +00:00
|
|
|
}
|