mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-17 04:48:58 +03:00
57 lines
1.2 KiB
Go
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
|
|
}
|