aboutsummaryrefslogtreecommitdiffstats
path: root/cache
diff options
context:
space:
mode:
Diffstat (limited to 'cache')
-rw-r--r--cache/bug_subcache.go25
-rw-r--r--cache/cached.go6
-rw-r--r--cache/filter.go4
-rw-r--r--cache/identity_subcache.go (renamed from cache/repo_cache_identity.go)2
-rw-r--r--cache/repo_cache.go75
-rw-r--r--cache/resolvers.go42
-rw-r--r--cache/subcache.go28
7 files changed, 73 insertions, 109 deletions
diff --git a/cache/bug_subcache.go b/cache/bug_subcache.go
index a0c8d84c..e61bbf2b 100644
--- a/cache/bug_subcache.go
+++ b/cache/bug_subcache.go
@@ -233,31 +233,6 @@ func (c *RepoCacheBug) NewRaw(author identity.Interface, unixTime int64, title s
return cached, op, nil
}
-// Remove removes a bug from the cache and repo given a bug id prefix
-func (c *RepoCacheBug) Remove(prefix string) error {
- b, err := c.ResolveBugPrefix(prefix)
- if err != nil {
- return err
- }
-
- c.muBug.Lock()
-
- err = bug.Remove(c.repo, b.Id())
- if err != nil {
- c.muBug.Unlock()
-
- return err
- }
-
- delete(c.bugs, b.Id())
- delete(c.bugExcerpts, b.Id())
- c.loadedBugs.Remove(b.Id())
-
- c.muBug.Unlock()
-
- return c.writeBugCache()
-}
-
func (c *RepoCacheBug) addBugToSearchIndex(snap *bug.Snapshot) error {
searchableBug := struct {
Text []string
diff --git a/cache/cached.go b/cache/cached.go
index 5e24e732..75ca58e5 100644
--- a/cache/cached.go
+++ b/cache/cached.go
@@ -104,6 +104,12 @@ func (e *CachedEntityBase[SnapT, OpT]) ResolveOperationWithMetadata(key string,
return matching[0], nil
}
+func (e *CachedEntityBase[SnapT, OpT]) Validate() error {
+ e.mu.RLock()
+ defer e.mu.RUnlock()
+ return e.entity.Validate()
+}
+
func (e *CachedEntityBase[SnapT, OpT]) Commit() error {
e.mu.Lock()
err := e.entity.Commit(e.repo)
diff --git a/cache/filter.go b/cache/filter.go
index 299e7c83..01f635c5 100644
--- a/cache/filter.go
+++ b/cache/filter.go
@@ -9,7 +9,7 @@ import (
)
// resolver has the resolving functions needed by filters.
-// This exist mainly to go through the functions of the cache with proper locking.
+// This exists mainly to go through the functions of the cache with proper locking.
type resolver interface {
ResolveIdentityExcerpt(id entity.Id) (*IdentityExcerpt, error)
}
@@ -211,7 +211,7 @@ func (*Matcher) orMatch(filters []Filter, excerpt *BugExcerpt, resolver resolver
return match
}
-// Check if all of the filters provided match the bug
+// Check if all the filters provided match the bug
func (*Matcher) andMatch(filters []Filter, excerpt *BugExcerpt, resolver resolver) bool {
if len(filters) == 0 {
return true
diff --git a/cache/repo_cache_identity.go b/cache/identity_subcache.go
index a99c7687..a3b5a0f8 100644
--- a/cache/repo_cache_identity.go
+++ b/cache/identity_subcache.go
@@ -7,7 +7,7 @@ import (
)
type RepoCacheIdentity struct {
- SubCache[*IdentityExcerpt, *IdentityCache]
+ SubCache[*IdentityExcerpt, *IdentityCache, identity.Interface]
}
// ResolveIdentityImmutableMetadata retrieve an Identity that has the exact given metadata on
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index c1646d3b..9250bb40 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -6,7 +6,8 @@ import (
"io/ioutil"
"os"
"strconv"
- "sync"
+
+ "golang.org/x/sync/errgroup"
"github.com/MichaelMure/git-bug/entities/bug"
"github.com/MichaelMure/git-bug/entities/identity"
@@ -52,13 +53,10 @@ type RepoCache struct {
// resolvers for all known entities
resolvers entity.Resolvers
- bugs *RepoCacheBug
+ bugs *RepoCacheBug
+ identities *RepoCacheIdentity
- muIdentity sync.RWMutex
- // excerpt of identities data for all identities
- identitiesExcerpts map[entity.Id]*IdentityExcerpt
- // identities loaded in memory
- identities map[entity.Id]*IdentityCache
+ subcaches []cacheMgmt
// the user identity's id, if known
userIdentityId entity.Id
@@ -72,14 +70,20 @@ func NewNamedRepoCache(r repository.ClockedRepo, name string) (*RepoCache, error
c := &RepoCache{
repo: r,
name: name,
- bugs: NewCache(r),
- // maxLoadedBugs: defaultMaxLoadedBugs,
- // bugs: make(map[entity.Id]*BugCache),
- // loadedBugs: newLRUIdCache(),
- // identities: make(map[entity.Id]*IdentityCache),
}
- c.resolvers = makeResolvers(c)
+ bugs := NewSubCache[*BugExcerpt, *BugCache, bug.Interface](r,
+ c.getResolvers, c.GetUserIdentity,
+ "bug", "bugs",
+ formatVersion, defaultMaxLoadedBugs)
+
+ c.subcaches = append(c.subcaches, bugs)
+ c.bugs = &RepoCacheBug{SubCache: *bugs}
+
+ c.resolvers = entity.Resolvers{
+ &IdentityCache{}: entity.ResolverFunc((func(id entity.Id) (entity.Interface, error)(c.identities.Resolve)),
+ &BugCache{}: c.bugs,
+ }
err := c.lock()
if err != nil {
@@ -105,6 +109,15 @@ func (c *RepoCache) Bugs() *RepoCacheBug {
return c.bugs
}
+// Identities gives access to the Identity entities
+func (c *RepoCache) Identities() *RepoCacheIdentity {
+ return c.identities
+}
+
+func (c *RepoCache) getResolvers() entity.Resolvers {
+ return c.resolvers
+}
+
// setCacheSize change the maximum number of loaded bugs
func (c *RepoCache) setCacheSize(size int) {
c.maxLoadedBugs = size
@@ -113,21 +126,20 @@ func (c *RepoCache) setCacheSize(size int) {
// load will try to read from the disk all the cache files
func (c *RepoCache) load() error {
- err := c.loadBugCache()
- if err != nil {
- return err
+ var errG errgroup.Group
+ for _, mgmt := range c.subcaches {
+ errG.Go(mgmt.Load)
}
-
- return c.loadIdentityCache()
+ return errG.Wait()
}
// write will serialize on disk all the cache files
func (c *RepoCache) write() error {
- err := c.writeBugCache()
- if err != nil {
- return err
+ var errG errgroup.Group
+ for _, mgmt := range c.subcaches {
+ errG.Go(mgmt.Write)
}
- return c.writeIdentityCache()
+ return errG.Wait()
}
func (c *RepoCache) lock() error {
@@ -151,17 +163,16 @@ func (c *RepoCache) lock() error {
}
func (c *RepoCache) Close() error {
- c.muBug.Lock()
- defer c.muBug.Unlock()
- c.muIdentity.Lock()
- defer c.muIdentity.Unlock()
-
- c.identities = make(map[entity.Id]*IdentityCache)
- c.identitiesExcerpts = nil
- c.bugs = make(map[entity.Id]*BugCache)
- c.bugExcerpts = nil
+ var errG errgroup.Group
+ for _, mgmt := range c.subcaches {
+ errG.Go(mgmt.Close)
+ }
+ err := errG.Wait()
+ if err != nil {
+ return err
+ }
- err := c.repo.Close()
+ err = c.repo.Close()
if err != nil {
return err
}
diff --git a/cache/resolvers.go b/cache/resolvers.go
deleted file mode 100644
index 9ed2fa4c..00000000
--- a/cache/resolvers.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package cache
-
-import (
- "github.com/MichaelMure/git-bug/entity"
-)
-
-func makeResolvers(cache *RepoCache) entity.Resolvers {
- return entity.Resolvers{
- &IdentityCache{}: newIdentityCacheResolver(cache),
- &BugCache{}: newBugCacheResolver(cache),
- }
-}
-
-var _ entity.Resolver = &identityCacheResolver{}
-
-// identityCacheResolver is an identity Resolver that retrieve identities from
-// the cache
-type identityCacheResolver struct {
- cache *RepoCache
-}
-
-func newIdentityCacheResolver(cache *RepoCache) *identityCacheResolver {
- return &identityCacheResolver{cache: cache}
-}
-
-func (i *identityCacheResolver) Resolve(id entity.Id) (entity.Interface, error) {
- return i.cache.ResolveIdentity(id)
-}
-
-var _ entity.Resolver = &bugCacheResolver{}
-
-type bugCacheResolver struct {
- cache *RepoCache
-}
-
-func newBugCacheResolver(cache *RepoCache) *bugCacheResolver {
- return &bugCacheResolver{cache: cache}
-}
-
-func (b *bugCacheResolver) Resolve(id entity.Id) (entity.Interface, error) {
- return b.cache.ResolveBug(id)
-}
diff --git a/cache/subcache.go b/cache/subcache.go
index 658781d9..66f72767 100644
--- a/cache/subcache.go
+++ b/cache/subcache.go
@@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
"github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entities/identity"
"github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/repository"
)
@@ -22,11 +21,18 @@ type CacheEntity interface {
NeedCommit() bool
}
-type getUserIdentityFunc func() (identity.Interface, error)
+type cacheMgmt interface {
+ Load() error
+ Write() error
+ Build() error
+ Close() error
+}
+
+type getUserIdentityFunc func() (*IdentityCache, error)
type SubCache[ExcerptT Excerpt, CacheT CacheEntity, EntityT entity.Interface] struct {
repo repository.ClockedRepo
- resolvers entity.Resolvers
+ resolvers func() entity.Resolvers
getUserIdentity getUserIdentityFunc
readWithResolver func(repository.ClockedRepo, entity.Resolvers, entity.Id) (EntityT, error)
@@ -46,8 +52,8 @@ type SubCache[ExcerptT Excerpt, CacheT CacheEntity, EntityT entity.Interface] st
func NewSubCache[ExcerptT Excerpt, CacheT CacheEntity, EntityT entity.Interface](
repo repository.ClockedRepo,
- resolvers entity.Resolvers,
- getUserIdentity func() (identity.Interface, error),
+ resolvers func() entity.Resolvers,
+ getUserIdentity getUserIdentityFunc,
typename, namespace string,
version uint, maxLoaded int) *SubCache[ExcerptT, CacheT, EntityT] {
return &SubCache[ExcerptT, CacheT, EntityT]{
@@ -144,8 +150,16 @@ func (sc *SubCache[ExcerptT, CacheT, EntityT]) Write() error {
return f.Close()
}
-func (sc *SubCache[ExcerptT, CacheT, EntityT]) Build() {
+func (sc *SubCache[ExcerptT, CacheT, EntityT]) Build() error {
+
+}
+func (sc *SubCache[ExcerptT, CacheT, EntityT]) Close() error {
+ sc.mu.Lock()
+ defer sc.mu.Unlock()
+ sc.excerpts = nil
+ sc.cached = make(map[entity.Id]CacheT)
+ return nil
}
// AllIds return all known bug ids
@@ -175,7 +189,7 @@ func (sc *SubCache[ExcerptT, CacheT, EntityT]) Resolve(id entity.Id) (CacheT, er
}
sc.mu.RUnlock()
- b, err := sc.readWithResolver(sc.repo, sc.resolvers, id)
+ b, err := sc.readWithResolver(sc.repo, sc.resolvers(), id)
if err != nil {
return nil, err
}