new flat KV structure
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package watcher
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// FileState tracks the known state of a file
|
||||
type FileState struct {
|
||||
Size int64
|
||||
MtimeNano int64
|
||||
MidHash string
|
||||
}
|
||||
|
||||
// WatcherState tracks all files for a single watcher (in-memory)
|
||||
type WatcherState struct {
|
||||
mu sync.RWMutex
|
||||
files map[string]*FileState // key: relative path
|
||||
}
|
||||
|
||||
// NewWatcherState creates a new watcher state tracker
|
||||
func NewWatcherState() *WatcherState {
|
||||
return &WatcherState{
|
||||
files: make(map[string]*FileState),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the file state for a given path, or nil if not tracked
|
||||
func (ws *WatcherState) Get(path string) *FileState {
|
||||
ws.mu.RLock()
|
||||
defer ws.mu.RUnlock()
|
||||
return ws.files[path]
|
||||
}
|
||||
|
||||
// Set updates or adds the file state for a given path
|
||||
func (ws *WatcherState) Set(path string, state *FileState) {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
ws.files[path] = state
|
||||
}
|
||||
|
||||
// Delete removes a file from the tracked state
|
||||
func (ws *WatcherState) Delete(path string) {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
delete(ws.files, path)
|
||||
}
|
||||
|
||||
// GetAll returns a snapshot of all tracked files
|
||||
// The returned map is a copy - safe to modify
|
||||
func (ws *WatcherState) GetAll() map[string]*FileState {
|
||||
ws.mu.RLock()
|
||||
defer ws.mu.RUnlock()
|
||||
|
||||
snapshot := make(map[string]*FileState, len(ws.files))
|
||||
for path, state := range ws.files {
|
||||
// Copy the state to avoid race conditions
|
||||
stateCopy := *state
|
||||
snapshot[path] = &stateCopy
|
||||
}
|
||||
return snapshot
|
||||
}
|
||||
|
||||
// Clear removes all tracked files
|
||||
func (ws *WatcherState) Clear() {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
ws.files = make(map[string]*FileState)
|
||||
}
|
||||
|
||||
// Count returns the number of tracked files
|
||||
func (ws *WatcherState) Count() int {
|
||||
ws.mu.RLock()
|
||||
defer ws.mu.RUnlock()
|
||||
return len(ws.files)
|
||||
}
|
||||
|
||||
// StateRegistry manages per-watcher state
|
||||
type StateRegistry struct {
|
||||
mu sync.RWMutex
|
||||
states map[string]*WatcherState // key: watcher ID
|
||||
}
|
||||
|
||||
// NewStateRegistry creates a new state registry
|
||||
func NewStateRegistry() *StateRegistry {
|
||||
return &StateRegistry{
|
||||
states: make(map[string]*WatcherState),
|
||||
}
|
||||
}
|
||||
|
||||
// GetOrCreate returns the state for a watcher, creating one if needed
|
||||
func (sr *StateRegistry) GetOrCreate(watcherID string) *WatcherState {
|
||||
sr.mu.Lock()
|
||||
defer sr.mu.Unlock()
|
||||
|
||||
state, exists := sr.states[watcherID]
|
||||
if !exists {
|
||||
state = NewWatcherState()
|
||||
sr.states[watcherID] = state
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// Get returns the state for a watcher, or nil if not exists
|
||||
func (sr *StateRegistry) Get(watcherID string) *WatcherState {
|
||||
sr.mu.RLock()
|
||||
defer sr.mu.RUnlock()
|
||||
return sr.states[watcherID]
|
||||
}
|
||||
|
||||
// Clear removes the state for a watcher
|
||||
func (sr *StateRegistry) Clear(watcherID string) {
|
||||
sr.mu.Lock()
|
||||
defer sr.mu.Unlock()
|
||||
|
||||
if state, exists := sr.states[watcherID]; exists {
|
||||
state.Clear()
|
||||
}
|
||||
}
|
||||
|
||||
// ClearAll removes all watcher states
|
||||
func (sr *StateRegistry) ClearAll() {
|
||||
sr.mu.Lock()
|
||||
defer sr.mu.Unlock()
|
||||
|
||||
for _, state := range sr.states {
|
||||
state.Clear()
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes a watcher's state completely
|
||||
func (sr *StateRegistry) Delete(watcherID string) {
|
||||
sr.mu.Lock()
|
||||
defer sr.mu.Unlock()
|
||||
delete(sr.states, watcherID)
|
||||
}
|
||||
|
||||
// Count returns the number of files tracked for a watcher
|
||||
func (sr *StateRegistry) Count(watcherID string) int {
|
||||
sr.mu.RLock()
|
||||
defer sr.mu.RUnlock()
|
||||
|
||||
if state, exists := sr.states[watcherID]; exists {
|
||||
return state.Count()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Reference in New Issue
Block a user