filestash/server/plugin/plg_search_sqlitefts/crawlstate.go
2022-01-14 16:38:42 +11:00

121 lines
2.7 KiB
Go

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
}