mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
129 lines
2.5 KiB
Go
129 lines
2.5 KiB
Go
package fileSystem
|
|
|
|
import (
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
Get = "get"
|
|
Set = "set"
|
|
Delete = "delete"
|
|
TestAndSet = "testAndSet"
|
|
)
|
|
|
|
type Event struct {
|
|
Action string `json:"action"`
|
|
Key string `json:"key, omitempty"`
|
|
Dir bool `json:"dir,omitempty"`
|
|
PrevValue string `json:"prevValue,omitempty"`
|
|
Value string `json:"value,omitempty"`
|
|
KVPairs []KeyValuePair `json:"kvs,omitempty"`
|
|
Expiration *time.Time `json:"expiration,omitempty"`
|
|
TTL int64 `json:"ttl,omitempty"` // Time to live in second
|
|
// The command index of the raft machine when the command is executed
|
|
Index uint64 `json:"index"`
|
|
Term uint64 `json:"term"`
|
|
}
|
|
|
|
// When user list a directory, we add all the node into key-value pair slice
|
|
type KeyValuePair struct {
|
|
Key string `json:"key, omitempty"`
|
|
Value string `json:"value,omitempty"`
|
|
Dir bool `json:"dir,omitempty"`
|
|
KVPairs []KeyValuePair `json:"kvs,omitempty"`
|
|
}
|
|
|
|
func newEvent(action string, key string, index uint64, term uint64) *Event {
|
|
return &Event{
|
|
Action: action,
|
|
Key: key,
|
|
Index: index,
|
|
Term: term,
|
|
}
|
|
}
|
|
|
|
type eventQueue struct {
|
|
events []*Event
|
|
size int
|
|
front int
|
|
back int
|
|
capacity int
|
|
}
|
|
|
|
func (eq *eventQueue) insert(e *Event) {
|
|
|
|
eq.back = (eq.back + 1) % eq.capacity
|
|
eq.events[eq.back] = e
|
|
|
|
if eq.size == eq.capacity { //dequeue
|
|
eq.front = (eq.back + 1) % eq.capacity
|
|
} else {
|
|
eq.size++
|
|
}
|
|
|
|
}
|
|
|
|
type EventHistory struct {
|
|
Queue eventQueue
|
|
StartIndex uint64
|
|
rwl sync.RWMutex
|
|
}
|
|
|
|
func newEventHistory(capacity int) *EventHistory {
|
|
return &EventHistory{
|
|
Queue: eventQueue{
|
|
capacity: capacity,
|
|
events: make([]*Event, capacity),
|
|
back: -1,
|
|
},
|
|
}
|
|
}
|
|
|
|
// addEvent function adds event into the eventHistory
|
|
func (eh *EventHistory) addEvent(e *Event) {
|
|
eh.rwl.Lock()
|
|
defer eh.rwl.Unlock()
|
|
|
|
eh.Queue.insert(e)
|
|
|
|
eh.StartIndex = eh.Queue.events[eh.Queue.front].Index
|
|
}
|
|
|
|
func (eh *EventHistory) scan(prefix string, index uint64) (*Event, error) {
|
|
eh.rwl.RLock()
|
|
defer eh.rwl.RUnlock()
|
|
|
|
start := index - eh.StartIndex
|
|
|
|
if start < 0 {
|
|
|
|
// TODO: Add error type
|
|
return nil, nil
|
|
}
|
|
|
|
if start >= uint64(eh.Queue.size) {
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
i := int((start + uint64(eh.Queue.front)) % uint64(eh.Queue.capacity))
|
|
|
|
for {
|
|
|
|
e := eh.Queue.events[i]
|
|
if strings.HasPrefix(e.Key, prefix) {
|
|
return e, nil
|
|
}
|
|
|
|
i = (i + 1) % eh.Queue.capacity
|
|
|
|
if i == eh.Queue.back {
|
|
// TODO: Add error type
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
}
|