diff options
author | Mike Goldin <mike.goldin@protonmail.ch> | 2020-10-01 08:16:31 -0400 |
---|---|---|
committer | Mike Goldin <mike.goldin@protonmail.ch> | 2020-11-17 08:09:51 -0500 |
commit | 0a827af60acc0e37a4c25b4ffc059b4bb020b77c (patch) | |
tree | 0b473b8a8badf9214d239eeba9a5ae171d9cfc6f /cache | |
parent | b285c57dc62caac2c1f09e74eeece406b0e7cc00 (diff) | |
download | git-bug-0a827af60acc0e37a4c25b4ffc059b4bb020b77c.tar.gz |
Create a search cache index when git-bug starts up if none exists
Diffstat (limited to 'cache')
-rw-r--r-- | cache/repo_cache.go | 36 | ||||
-rw-r--r-- | cache/repo_cache_bug.go | 67 |
2 files changed, 102 insertions, 1 deletions
diff --git a/cache/repo_cache.go b/cache/repo_cache.go index 4fc88015..632469e4 100644 --- a/cache/repo_cache.go +++ b/cache/repo_cache.go @@ -15,6 +15,7 @@ import ( "github.com/MichaelMure/git-bug/identity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/process" + "github.com/blevesearch/bleve" ) // 1: original format @@ -56,6 +57,8 @@ type RepoCache struct { muBug sync.RWMutex // excerpt of bugs data for all bugs bugExcerpts map[entity.Id]*BugExcerpt + // searchable cache of all bugs + searchCache bleve.Index // bug loaded in memory bugs map[entity.Id]*BugCache // loadedBugs is an LRU cache that records which bugs the cache has loaded in @@ -116,6 +119,7 @@ func (c *RepoCache) load() error { if err != nil { return err } + return c.loadIdentityCache() } @@ -166,6 +170,11 @@ func (c *RepoCache) Close() error { c.bugs = make(map[entity.Id]*BugCache) c.bugExcerpts = nil + if c.searchCache != nil { + c.searchCache.Close() + c.searchCache = nil + } + lockPath := repoLockFilePath(c.repo) return os.Remove(lockPath) } @@ -198,6 +207,11 @@ func (c *RepoCache) buildCache() error { allBugs := bug.ReadAllLocal(c.repo) + err := c.ensureBleveIndex() + if err != nil { + return fmt.Errorf("Unable to create or open search cache. Error: %v", err) + } + for b := range allBugs { if b.Err != nil { return b.Err @@ -205,9 +219,31 @@ func (c *RepoCache) buildCache() error { snap := b.Bug.Compile() c.bugExcerpts[b.Bug.Id()] = NewBugExcerpt(b.Bug, &snap) + + if err := c.addBugToSearchIndex(&snap); err != nil { + return err + } } _, _ = fmt.Fprintln(os.Stderr, "Done.") + + return nil +} + +func (c *RepoCache) addBugToSearchIndex(snap *bug.Snapshot) error { + searchableBug := struct { + Text []string + }{} + + for _, comment := range snap.Comments { + searchableBug.Text = append(searchableBug.Text, comment.Message) + } + + err := c.searchCache.Index(snap.Id().String(), searchableBug) + if err != nil { + return err + } + return nil } diff --git a/cache/repo_cache_bug.go b/cache/repo_cache_bug.go index 0c583e0d..dd833b46 100644 --- a/cache/repo_cache_bug.go +++ b/cache/repo_cache_bug.go @@ -14,9 +14,13 @@ import ( "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/query" "github.com/MichaelMure/git-bug/repository" + "github.com/blevesearch/bleve" ) -const bugCacheFile = "bug-cache" +const ( + bugCacheFile = "bug-cache" + searchCacheDir = "search-cache" +) var errBugNotInCache = errors.New("bug missing from cache") @@ -24,6 +28,10 @@ func bugCacheFilePath(repo repository.Repo) string { return path.Join(repo.GetPath(), "git-bug", bugCacheFile) } +func searchCacheDirPath(repo repository.Repo) string { + return path.Join(repo.GetPath(), "git-bug", searchCacheDir) +} + // bugUpdated is a callback to trigger when the excerpt of a bug changed, // that is each time a bug is updated func (c *RepoCache) bugUpdated(id entity.Id) error { @@ -43,6 +51,10 @@ func (c *RepoCache) bugUpdated(id entity.Id) error { c.bugExcerpts[id] = NewBugExcerpt(b.bug, b.Snapshot()) c.muBug.Unlock() + if err := c.addBugToSearchIndex(b.Snapshot()); err != nil { + return err + } + // we only need to write the bug cache return c.writeBugCache() } @@ -73,10 +85,52 @@ func (c *RepoCache) loadBugCache() error { return fmt.Errorf("unknown cache format version %v", aux.Version) } + err = c.ensureBleveIndex() + if err != nil { + return fmt.Errorf("Unable to create or open search cache. Error: %v", err) + } + count, err := c.searchCache.DocCount() + if err != nil { + return err + } + if count != uint64(len(c.bugExcerpts)) { + return fmt.Errorf("count mismatch between bleve and bug excerpts") + } + c.bugExcerpts = aux.Excerpts return nil } +func (c *RepoCache) ensureBleveIndex() error { + blevePath := searchCacheDirPath(c.repo) + + // Try to open the bleve index. If there is _any_ error, whether it be that + // the bleve index does not exist or is corrupt, handle that by nuking the + // bleve index and recreating it. + bleveIndex, err := bleve.Open(blevePath) + if err != nil { + // If the index does not exist, we don't care. We're going to create it + // next. + _ = os.RemoveAll(blevePath) + + mapping := bleve.NewIndexMapping() + dir := searchCacheDirPath(c.repo) + + bleveIndex, err := bleve.New(dir, mapping) + if err != nil { + return err + } + + c.searchCache = bleveIndex + + return nil + } + + c.searchCache = bleveIndex + + return nil +} + // write will serialize on disk the bug cache file func (c *RepoCache) writeBugCache() error { c.muBug.RLock() @@ -256,6 +310,17 @@ func (c *RepoCache) QueryBugs(q *query.Query) []entity.Id { var filtered []*BugExcerpt + //if q.Search != nil { + // booleanQuery := bleve.NewBooleanQuery() + // for _, term := range q.Search { + // query := bleve.NewMatchQuery(term) + // booleanQuery.AddMust(query) + // } + + // search := bleve.NewSearchRequest(booleanQuery) + // searchResults, _ := c.searchCache.Search(search) + //} + for _, excerpt := range c.bugExcerpts { if matcher.Match(excerpt, c) { filtered = append(filtered, excerpt) |