1
1
mirror of https://github.com/MichaelMure/git-bug.git synced 2024-12-17 04:48:58 +03:00
git-bug/cache/with_snapshot.go
2022-12-22 00:48:00 +01:00

57 lines
1.2 KiB
Go

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
}