package plg_search_sqlitefts import ( "container/heap" . "github.com/mickael-kerjean/filestash/server/common" "path/filepath" "sync" ) var SProc SearchProcess = SearchProcess{ idx: make([]SearchIndexer, 0), n: -1, } type SearchProcess struct { idx []SearchIndexer n int mu sync.RWMutex } func (this *SearchProcess) HintLs(app *App, path string) *SearchIndexer { id := GenerateID(app) // try to find the search indexer among the existing ones this.mu.RLock() for i := len(this.idx) - 1; i >= 0; i-- { if id == this.idx[i].Id { alreadyHasPath := false for j := 0; j < len(this.idx[i].FoldersUnknown); j++ { if this.idx[i].FoldersUnknown[j].Path == path { alreadyHasPath = true break } } if alreadyHasPath == false { heap.Push(&this.idx[i].FoldersUnknown, &Document{ Type: "directory", Path: path, InitialPath: path, Name: filepath.Base(path), }) } ret := &this.idx[i] this.mu.RUnlock() return ret } } this.mu.RUnlock() // Having all indexers running in memory could be expensive => instead we're cycling a pool search_process_max := SEARCH_PROCESS_MAX() this.mu.Lock() lenIdx := len(this.idx) if lenIdx > 0 && search_process_max > 0 && lenIdx > (search_process_max-1) { toDel := this.idx[0 : lenIdx-(search_process_max-1)] for i := range toDel { toDel[i].DB.Close() } this.idx = this.idx[lenIdx-(search_process_max-1):] } // instantiate the new indexer s := NewSearchIndexer(id, app.Backend) heap.Push(&s.FoldersUnknown, &Document{ Type: "directory", Path: path, InitialPath: path, Name: filepath.Base(path), }) this.idx = append(this.idx, s) this.mu.Unlock() return &s } func (this *SearchProcess) HintRm(app *App, path string) { id := GenerateID(app) this.mu.RLock() for i := len(this.idx) - 1; i >= 0; i-- { if id == this.idx[i].Id { this.idx[i].DB.Exec("DELETE FROM file WHERE path >= ? AND path < ?", path, path+"~") break } } this.mu.RUnlock() } func (this *SearchProcess) HintFile(app *App, path string) { id := GenerateID(app) this.mu.RLock() for i := len(this.idx) - 1; i >= 0; i-- { if id == this.idx[i].Id { this.idx[i].DB.Exec("UPDATE file set indexTime = NULL WHERE path = ?", path) break } } this.mu.RUnlock() } func (this *SearchProcess) Peek() *SearchIndexer { if len(this.idx) == 0 { return nil } this.mu.Lock() if this.n >= len(this.idx)-1 || this.n < 0 { this.n = 0 } else { this.n = this.n + 1 } s := &this.idx[this.n] this.mu.Unlock() return s } func (this *SearchProcess) Reset() { this.mu.Lock() for i := range this.idx { this.idx[i].DB.Close() } this.idx = make([]SearchIndexer, 0) this.mu.Unlock() this.n = -1 }