Commit 341cc93b authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 523794af
......@@ -158,6 +158,8 @@ type ΔFtail struct {
type _ΔFileTail struct {
root zodb.Oid // .blktab as of @head
vδE []_ΔFileEpoch // epochs (changes to ZBigFile object itself) ; nil if not yet rebuilt
rebuildJob *_RebuildJob // !nil if vδE rebuild is currently in-progress
}
// _ΔFileEpoch represent a change to ZBigFile object.
......@@ -177,6 +179,12 @@ type zblkTrack struct {
inroot map[zodb.Oid]setI64 // {} root -> {}blk
}
// _RebuildJob represents currently in-progress vδE rebuilding job.
type _RebuildJob struct {
ready chan struct{} // closed when job completes
err error
}
// ΔF represents a change in files space.
type ΔF struct {
......@@ -299,10 +307,11 @@ func (δFtail *ΔFtail) rebuildAll() (err error) {
δZtail := δBtail.ΔZtail()
db := δBtail.DB()
for foid := range δFtail.trackNew {
δFtail.trackNew.Del(foid) // XXX -> to after vδEBuild
δFtail.trackNew.Del(foid)
δftail := δFtail.byFile[foid]
δftail.vδE, err = vδEBuild(foid, δZtail, db)
if err != nil {
δFtail.trackNew.Add(foid)
return err
}
}
......@@ -315,23 +324,54 @@ func (δFtail *ΔFtail) rebuildAll() (err error) {
// it returns corresponding δftail for convenience. XXX
// the only case when vδE actually needs to be rebuilt is when the file just started to be tracked.
//
// XXX naming -> vδEForFile ?
// XXX naming -> vδEForFile ? vδEBuildIfNeeded?
func (δFtail *ΔFtail) rebuild1IfNeeded(foid zodb.Oid) (vδE []_ΔFileEpoch, headRoot zodb.Oid, err error) {
δFtail.mu.Lock() // TODO verify that there is no in-progress writers
defer δFtail.mu.Unlock()
δftail := δFtail.byFile[foid]
if δftail.vδE == nil {
δFtail.trackNew.Del(foid)
δBtail := δFtail.δBtail
// XXX indicate in-progress rebuild via job
root := δftail.root
vδE = δftail.vδE
if vδE != nil {
return vδE, root, nil
}
// vδE needs to be built
job := δftail.rebuildJob
// rebuild is currently in-progress -> wait for corrsponding job to complete
if job != nil {
δFtail.mu.Unlock()
vδE, err = vδEBuild(foid, δBtail.ΔZtail(), δBtail.DB())
δFtail.mu.Lock()
<-job.ready
if job.err == nil {
δFtail.mu.Lock()
vδE = δftail.vδE
}
return vδE, root, job.err
}
// we become responsible to build vδE
// do the build without the lock
job = &_RebuildJob{ready: make(chan struct{})}
δftail.rebuildJob = job
δFtail.trackNew.Del(foid)
δBtail := δFtail.δBtail
δFtail.mu.Unlock()
vδE, err = vδEBuild(foid, δBtail.ΔZtail(), δBtail.DB())
δFtail.mu.Lock()
if err == nil {
δftail.vδE = vδE
} else {
δFtail.trackNew.Add(foid)
}
return δftail.vδE, δftail.root, err
δftail.rebuildJob = nil
job.err = err
close(job.ready)
return vδE, root, err
}
// Update updates δFtail given raw ZODB changes.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment