mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-17 04:48:58 +03:00
cache: generic withSnapshot, some cleanup
This commit is contained in:
parent
9b98fc0648
commit
d65e8837aa
@ -19,8 +19,11 @@ func TestQueries(t *testing.T) {
|
||||
random_bugs.FillRepoWithSeed(repo, 10, 42)
|
||||
|
||||
mrc := cache.NewMultiRepoCache()
|
||||
_, _, err := mrc.RegisterDefaultRepository(repo)
|
||||
_, events, err := mrc.RegisterDefaultRepository(repo)
|
||||
require.NoError(t, err)
|
||||
for event := range events {
|
||||
require.NoError(t, event.Err)
|
||||
}
|
||||
|
||||
handler := NewHandler(mrc, nil)
|
||||
|
||||
|
2
cache/bug_cache.go
vendored
2
cache/bug_cache.go
vendored
@ -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},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
47
cache/cached.go
vendored
47
cache/cached.go
vendored
@ -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
|
||||
|
2
cache/repo_cache_test.go
vendored
2
cache/repo_cache_test.go
vendored
@ -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)
|
||||
|
7
cache/subcache.go
vendored
7
cache/subcache.go
vendored
@ -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()
|
||||
}
|
||||
}
|
||||
|
56
cache/with_snapshot.go
vendored
Normal file
56
cache/with_snapshot.go
vendored
Normal file
@ -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
|
||||
}
|
@ -135,20 +135,20 @@ func LoadBackend(env *Env) func(*cobra.Command, []string) error {
|
||||
}
|
||||
|
||||
if events != nil {
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Building cache... ")
|
||||
env.Err.Println("Building cache... ")
|
||||
}
|
||||
|
||||
for event := range events {
|
||||
if event.Err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "Cache building error [%s]: %v\n", event.Typename, event.Err)
|
||||
env.Err.Printf("Cache building error [%s]: %v\n", event.Typename, event.Err)
|
||||
continue
|
||||
}
|
||||
|
||||
switch event.Event {
|
||||
case cache.BuildEventStarted:
|
||||
_, _ = fmt.Fprintf(os.Stderr, "[%s] started\n", event.Typename)
|
||||
env.Err.Printf("[%s] started\n", event.Typename)
|
||||
case cache.BuildEventFinished:
|
||||
_, _ = fmt.Fprintf(os.Stderr, "[%s] done\n", event.Typename)
|
||||
env.Err.Printf("[%s] done\n", event.Typename)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,11 +105,25 @@ func runWebUI(env *execenv.Env, opts webUIOptions) error {
|
||||
}
|
||||
|
||||
mrc := cache.NewMultiRepoCache()
|
||||
_, _, err := mrc.RegisterDefaultRepository(env.Repo)
|
||||
_, events, err := mrc.RegisterDefaultRepository(env.Repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for event := range events {
|
||||
if event.Err != nil {
|
||||
env.Err.Printf("Cache building error [%s]: %v\n", event.Typename, event.Err)
|
||||
continue
|
||||
}
|
||||
|
||||
switch event.Event {
|
||||
case cache.BuildEventStarted:
|
||||
env.Err.Printf("[%s] started\n", event.Typename)
|
||||
case cache.BuildEventFinished:
|
||||
env.Err.Printf("[%s] done\n", event.Typename)
|
||||
}
|
||||
}
|
||||
|
||||
var errOut io.Writer
|
||||
if opts.logErrors {
|
||||
errOut = env.Err
|
||||
|
@ -43,6 +43,10 @@ func (snap *Snapshot) AllOperations() []dag.Operation {
|
||||
return snap.Operations
|
||||
}
|
||||
|
||||
func (snap *Snapshot) AppendOperation(op dag.Operation) {
|
||||
snap.Operations = append(snap.Operations, op)
|
||||
}
|
||||
|
||||
// EditTime returns the last time a bug was modified
|
||||
func (snap *Snapshot) EditTime() time.Time {
|
||||
if len(snap.Operations) == 0 {
|
||||
|
@ -1,53 +0,0 @@
|
||||
package bug
|
||||
|
||||
import (
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
)
|
||||
|
||||
var _ Interface = &WithSnapshot{}
|
||||
|
||||
// WithSnapshot encapsulate a Bug and maintain the corresponding Snapshot efficiently
|
||||
type WithSnapshot struct {
|
||||
*Bug
|
||||
snap *Snapshot
|
||||
}
|
||||
|
||||
func (b *WithSnapshot) Compile() *Snapshot {
|
||||
if b.snap == nil {
|
||||
snap := b.Bug.Compile()
|
||||
b.snap = snap
|
||||
}
|
||||
return b.snap
|
||||
}
|
||||
|
||||
// Append intercept Bug.Append() to update the snapshot efficiently
|
||||
func (b *WithSnapshot) Append(op Operation) {
|
||||
b.Bug.Append(op)
|
||||
|
||||
if b.snap == nil {
|
||||
return
|
||||
}
|
||||
|
||||
op.Apply(b.snap)
|
||||
b.snap.Operations = append(b.snap.Operations, op)
|
||||
}
|
||||
|
||||
// Commit intercept Bug.Commit() to update the snapshot efficiently
|
||||
func (b *WithSnapshot) Commit(repo repository.ClockedRepo) error {
|
||||
err := b.Bug.Commit(repo)
|
||||
|
||||
if err != nil {
|
||||
b.snap = nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Commit() shouldn't change anything of the bug state apart from the
|
||||
// initial ID set
|
||||
|
||||
if b.snap == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.snap.id = b.Bug.Id()
|
||||
return nil
|
||||
}
|
@ -12,6 +12,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var _ Snapshot = &snapshotMock{}
|
||||
|
||||
type snapshotMock struct {
|
||||
ops []Operation
|
||||
}
|
||||
@ -20,6 +22,10 @@ func (s *snapshotMock) AllOperations() []Operation {
|
||||
return s.ops
|
||||
}
|
||||
|
||||
func (s *snapshotMock) AppendOperation(op Operation) {
|
||||
s.ops = append(s.ops, op)
|
||||
}
|
||||
|
||||
func TestSetMetadata(t *testing.T) {
|
||||
snap := &snapshotMock{}
|
||||
|
||||
|
@ -90,6 +90,8 @@ type OperationDoesntChangeSnapshot interface {
|
||||
type Snapshot interface {
|
||||
// AllOperations returns all the operations that have been applied to that snapshot, in order
|
||||
AllOperations() []Operation
|
||||
// AppendOperation add an operation in the list
|
||||
AppendOperation(op Operation)
|
||||
}
|
||||
|
||||
// OpBase implement the common feature that every Operation should support.
|
||||
|
Loading…
Reference in New Issue
Block a user