diff options
author | Michael Muré <batolettre@gmail.com> | 2022-12-22 00:48:00 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2022-12-22 00:48:00 +0100 |
commit | d65e8837aa7bb1a6abb6892b9f2664e1b7edb02e (patch) | |
tree | 331b05b689182b4d2bf43fd7cf92ca03b055bff0 /cache | |
parent | 9b98fc06489353053564b431ac0c0d73a5c55a56 (diff) | |
download | git-bug-d65e8837aa7bb1a6abb6892b9f2664e1b7edb02e.tar.gz |
cache: generic withSnapshot, some cleanup
Diffstat (limited to 'cache')
-rw-r--r-- | cache/bug_cache.go | 2 | ||||
-rw-r--r-- | cache/cached.go | 47 | ||||
-rw-r--r-- | cache/repo_cache_test.go | 2 | ||||
-rw-r--r-- | cache/subcache.go | 7 | ||||
-rw-r--r-- | cache/with_snapshot.go | 56 |
5 files changed, 63 insertions, 51 deletions
diff --git a/cache/bug_cache.go b/cache/bug_cache.go index 7b3fa114..3466f186 100644 --- a/cache/bug_cache.go +++ b/cache/bug_cache.go @@ -28,7 +28,7 @@ func NewBugCache(b *bug.Bug, repo repository.ClockedRepo, getUserIdentity getUse repo: repo, entityUpdated: entityUpdated, getUserIdentity: getUserIdentity, - entity: &bug.WithSnapshot{Bug: b}, + entity: &withSnapshot[*bug.Snapshot, bug.Operation]{Interface: b}, }, } } diff --git a/cache/cached.go b/cache/cached.go index 5a31ee59..ce1d6637 100644 --- a/cache/cached.go +++ b/cache/cached.go @@ -9,52 +9,7 @@ import ( "github.com/MichaelMure/git-bug/util/lamport" ) -// type withSnapshot[SnapT dag.Snapshot, OpT dag.OperationWithApply[SnapT]] struct { -// dag.Interface[SnapT, OpT] -// snap dag.Snapshot -// } -// -// -// func (ws *withSnapshot[SnapT, OpT]) Compile() dag.Snapshot { -// if ws.snap == nil { -// snap := ws.Interface.Compile() -// ws.snap = snap -// } -// return ws.snap -// } -// -// // Append intercept Bug.Append() to update the snapshot efficiently -// func (ws *withSnapshot[SnapT, OpT]) Append(op OpT) { -// ws.Interface.Append(op) -// -// if ws.snap == nil { -// return -// } -// -// op.Apply(ws.snap) -// ws.snap. = append(ws.snap.Operations, op) -// } -// -// // Commit intercept Bug.Commit() to update the snapshot efficiently -// func (ws *withSnapshot[SnapT, OpT]) Commit(repo repository.ClockedRepo) error { -// err := ws.Interface.Commit(repo) -// -// if err != nil { -// ws.snap = nil -// return err -// } -// -// // Commit() shouldn't change anything of the bug state apart from the -// // initial ID set -// -// if ws.snap == nil { -// return nil -// } -// -// ws.snap.id = ws.Interface.Id() -// return nil -// } - +// CachedEntityBase provide the base function of an entity managed by the cache. type CachedEntityBase[SnapT dag.Snapshot, OpT dag.Operation] struct { repo repository.ClockedRepo entityUpdated func(id entity.Id) error diff --git a/cache/repo_cache_test.go b/cache/repo_cache_test.go index 395872f7..939cb154 100644 --- a/cache/repo_cache_test.go +++ b/cache/repo_cache_test.go @@ -98,7 +98,7 @@ func TestCache(t *testing.T) { cache, events, err = NewRepoCache(repo) noBuildEventErrors(t, events) require.NoError(t, err) - require.Empty(t, cache.bugs.cached) + require.Len(t, cache.bugs.cached, 0) require.Len(t, cache.bugs.excerpts, 2) require.Len(t, cache.identities.cached, 0) require.Len(t, cache.identities.excerpts, 2) diff --git a/cache/subcache.go b/cache/subcache.go index 0678988a..af75938a 100644 --- a/cache/subcache.go +++ b/cache/subcache.go @@ -198,9 +198,10 @@ func (sc *SubCache[EntityT, ExcerptT, CacheT]) Build() error { return e.Err } - // TODO: doesn't actually record in cache, should we? cached := sc.makeCached(e.Entity, sc.entityUpdated) sc.excerpts[e.Entity.Id()] = sc.makeExcerpt(cached) + // might as well keep them in memory + sc.cached[e.Entity.Id()] = cached indexData := sc.makeIndexData(cached) if err := indexer(e.Entity.Id().String(), indexData); err != nil { @@ -417,12 +418,12 @@ func (sc *SubCache[EntityT, ExcerptT, CacheT]) MergeAll(remote string) <-chan en switch result.Status { case entity.MergeStatusNew, entity.MergeStatusUpdated: e := result.Entity.(EntityT) - - // TODO: doesn't actually record in cache, should we? cached := sc.makeCached(e, sc.entityUpdated) sc.mu.Lock() sc.excerpts[result.Id] = sc.makeExcerpt(cached) + // might as well keep them in memory + sc.cached[result.Id] = cached sc.mu.Unlock() } } diff --git a/cache/with_snapshot.go b/cache/with_snapshot.go new file mode 100644 index 00000000..674b6923 --- /dev/null +++ b/cache/with_snapshot.go @@ -0,0 +1,56 @@ +package cache + +import ( + "sync" + + "github.com/MichaelMure/git-bug/entity/dag" + "github.com/MichaelMure/git-bug/repository" +) + +var _ dag.Interface[dag.Snapshot, dag.OperationWithApply[dag.Snapshot]] = &withSnapshot[dag.Snapshot, dag.OperationWithApply[dag.Snapshot]]{} + +// withSnapshot encapsulate an entity and maintain a snapshot efficiently. +type withSnapshot[SnapT dag.Snapshot, OpT dag.OperationWithApply[SnapT]] struct { + dag.Interface[SnapT, OpT] + mu sync.Mutex + snap *SnapT +} + +func (ws *withSnapshot[SnapT, OpT]) Compile() SnapT { + ws.mu.Lock() + defer ws.mu.Unlock() + if ws.snap == nil { + snap := ws.Interface.Compile() + ws.snap = &snap + } + return *ws.snap +} + +// Append intercept Bug.Append() to update the snapshot efficiently +func (ws *withSnapshot[SnapT, OpT]) Append(op OpT) { + ws.mu.Lock() + defer ws.mu.Unlock() + + ws.Interface.Append(op) + + if ws.snap == nil { + return + } + + op.Apply(*ws.snap) + (*ws.snap).AppendOperation(op) +} + +// Commit intercept Bug.Commit() to update the snapshot efficiently +func (ws *withSnapshot[SnapT, OpT]) Commit(repo repository.ClockedRepo) error { + ws.mu.Lock() + defer ws.mu.Unlock() + + err := ws.Interface.Commit(repo) + if err != nil { + ws.snap = nil + return err + } + + return nil +} |