Commit 4d0947ec authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 98d18081
......@@ -145,17 +145,26 @@ type ΔFtail struct {
mu sync.Mutex
byFile map[zodb.Oid]*_ΔFileTail // file -> vδf tail
filesByRoot map[zodb.Oid]setOid // tree-root -> {} ZBigFile<oid> as of @head
byRoot map[zodb.Oid]*_RootTrack // tree-root -> ({foid}, Zinblk) as of @head
// filesByRoot map[zodb.Oid]setOid // tree-root -> {} ZBigFile<oid> as of @head
// set of files, which are newly tracked and for which byFile[foid].vδE was not yet rebuilt
trackNew setOid // {}foid
ftrackNew setOid // {}foid
// set of tracked ZBlk objects mapped to trees as of @head
// XXX -> Zinroot ? ztrackInRoot ?
ztrackInRoots map[zodb.Oid]setOid // {} zblk -> {}root
/*
// set of tracked ZBlk objects reverse-mapped to trees and block numbers
//
// XXX split -> :
// ΔFtail.trackSetZBlkRoots {} zblk -> {root}
// δftail.trackSetZBlkBlocks {} zblk -> {blk} in tha file/root (shared by all files with same root ?)
trackSetZBlk map[zodb.Oid]*zblkTrack // zblk -> {} root -> {}blk as of @head
ztrackRoots
*/
}
// _ΔFileTail represents tail of revisional changes to one file.
......@@ -175,13 +184,23 @@ type _ΔFileEpoch struct {
newBlkSize int64 // .blksize was changed to newBlkSize ; ----//----
// snapshot of trackSetZBlk for this file right before this epoch
oldTrackSetZBlk map[zodb.Oid]setI64 // {} zblk -> {}blk
// oldTrackSetZBlk map[zodb.Oid]setI64 // {} zblk -> {}blk
oldZinblk map[zodb.Oid]setI64 // {} zblk -> {}blk
}
// _RootTrack represents tracking information about one particular tree as of @head.
// XXX -> _TreeTrack ? _BlktabTrack ?
type _RootTrack struct {
files setOid // {}foid which ZBigFiles refer to this tree
Zinblk map[zodb.Oid]setI64 // {} zblk -> {}blk which blocks map to zblk
}
/* XXX kill
// zblkTrack keeps information in which root/blocks ZBlk is present as of @head.
type zblkTrack struct {
inroot map[zodb.Oid]setI64 // {} root -> {}blk
}
*/
// _RebuildJob represents currently in-progress vδE rebuilding job.
type _RebuildJob struct {
......@@ -216,9 +235,9 @@ func NewΔFtail(at0 zodb.Tid, db *zodb.DB) *ΔFtail {
return &ΔFtail{
δBtail: xbtree.NewΔBtail(at0, db),
byFile: map[zodb.Oid]*_ΔFileTail{},
filesByRoot: map[zodb.Oid]setOid{},
trackNew: setOid{},
trackSetZBlk: map[zodb.Oid]*zblkTrack{},
byRoot: map[zodb.Oid]*_RootTrack{},
ftrackNew: setOid{},
ztrackInRoots: map[zodb.Oid]setOid{},
}
}
......@@ -262,18 +281,21 @@ func (δFtail *ΔFtail) Track(file *ZBigFile, blk int64, path []btree.LONode, bl
δFtail.mu.Lock()
defer δFtail.mu.Unlock()
files, ok := δFtail.filesByRoot[root]
rt, ok := δFtail.byRoot[root]
if !ok {
files = setOid{}
δFtail.filesByRoot[root] = files
rt = &_RootTrack{
files: setOid{},
Zinblk: map[zodb.Oid]setI64{},
}
files.Add(foid)
δFtail.byRoot[root] = rt
}
rt.files.Add(foid)
δftail, ok := δFtail.byFile[foid]
if !ok {
δftail = &_ΔFileTail{root: root, vδE: nil /*will need to be rebuilt to past till tail*/}
δFtail.byFile[foid] = δftail
δFtail.trackNew.Add(foid)
δFtail.ftrackNew.Add(foid)
}
if δftail.root != root {
// .root can change during epochs, but in between them it must be stable
......@@ -284,19 +306,18 @@ func (δFtail *ΔFtail) Track(file *ZBigFile, blk int64, path []btree.LONode, bl
// associate zblk with root, if it was not hole
if zblk != nil {
zoid := zblk.POid()
zt, ok := δFtail.trackSetZBlk[zoid]
inroot, ok := δFtail.ztrackInRoots[zoid]
if !ok {
zt = &zblkTrack{}
δFtail.trackSetZBlk[zoid] = zt
inroot = make(setOid, 1)
δFtail.ztrackInRoots[zoid] = inroot
}
inroot.Add(zoid)
inblk, ok := zt.inroot[root]
inblk, ok := rt.Zinblk[zoid]
if !ok {
inblk = make(setI64, 1)
if zt.inroot == nil {
zt.inroot = make(map[zodb.Oid]setI64)
}
zt.inroot[root] = inblk
rt.Zinblk[zoid] = inblk
}
inblk.Add(blk)
}
......@@ -337,7 +358,7 @@ func (δFtail *ΔFtail) rebuild1IfNeeded(foid zodb.Oid) (vδE []_ΔFileEpoch, he
// release the lock while building to allow simultaneous access to other files
job = &_RebuildJob{ready: make(chan struct{})}
δftail.rebuildJob = job
δFtail.trackNew.Del(foid)
δFtail.ftrackNew.Del(foid)
δBtail := δFtail.δBtail
δFtail.mu.Unlock()
......@@ -347,7 +368,7 @@ func (δFtail *ΔFtail) rebuild1IfNeeded(foid zodb.Oid) (vδE []_ΔFileEpoch, he
if err == nil {
δftail.vδE = vδE
} else {
δFtail.trackNew.Add(foid)
δFtail.ftrackNew.Add(foid)
}
δftail.rebuildJob = nil
......@@ -357,7 +378,7 @@ func (δFtail *ΔFtail) rebuild1IfNeeded(foid zodb.Oid) (vδE []_ΔFileEpoch, he
return vδE, root, err
}
// _rebuildAll rebuilds vδE for all files from trackNew requests.
// _rebuildAll rebuilds vδE for all files from ftrackNew requests.
//
// must be calledwith δFtail.mu locked.
func (δFtail *ΔFtail) _rebuildAll() (err error) {
......@@ -366,13 +387,13 @@ func (δFtail *ΔFtail) _rebuildAll() (err error) {
δBtail := δFtail.δBtail
δZtail := δBtail.ΔZtail()
db := δBtail.DB()
for foid := range δFtail.trackNew {
δFtail.trackNew.Del(foid)
for foid := range δFtail.ftrackNew {
δFtail.ftrackNew.Del(foid)
δftail := δFtail.byFile[foid]
// no need to set δftail.rebuildJob - we are under lock
δftail.vδE, err = vδEBuild(foid, δZtail, db)
if err != nil {
δFtail.trackNew.Add(foid)
δFtail.ftrackNew.Add(foid)
return err
}
}
......@@ -427,14 +448,17 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) (_ ΔF, err error) {
newRoot: δ.blktabNew,
oldBlkSize: δ.blksizeOld,
newBlkSize: δ.blksizeNew,
oldTrackSetZBlk: map[zodb.Oid]setI64{},
oldZinblk: map[zodb.Oid]setI64{},
}
for oid, zt := range δFtail.trackSetZBlk {
inblk, ok := zt.inroot[δftail.root]
rt, ok := δFtail.byRoot[δftail.root]
if ok {
for zoid, inblk := range rt.Zinblk {
δE.oldZinblk[zoid] = inblk.Clone()
inroot, ok := δFtail.ztrackInRoots[zoid]
if ok {
δE.oldTrackSetZBlk[oid] = inblk
delete(zt.inroot, δftail.root)
inroot.Del(δftail.root)
}
}
}
......@@ -447,11 +471,11 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) (_ ΔF, err error) {
//fmt.Printf("δB.ByRoot: %v\n", δB.ByRoot)
for root, δt := range δB.ByRoot {
//fmt.Printf("root: %v δt: %v\n", root, δt)
files := δFtail.filesByRoot[root]
rt := δFtail.byRoot[root] // XXX root must be tracked, right?
// NOTE files might be empty e.g. if a zfile was tracked, then
// deleted, but the tree referenced by zfile.blktab is still
// not-deleted, remains tracked and is changed.
for file := range files {
for file := range rt.files {
δfile, ok := δF.ByFile[file]
if !ok {
δfile = &ΔFile{Rev: δF.Rev, Blocks: make(setI64)}
......@@ -468,51 +492,43 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) (_ ΔF, err error) {
δfile.Size = true
}
// update trackSetZBlk according to btree changes
// update Zinblk according to btree changes
for blk, δzblk := range δt {
if δzblk.Old != xbtree.VDEL {
ztOld, ok := δFtail.trackSetZBlk[δzblk.Old]
if ok {
inblk, ok := ztOld.inroot[root]
inblk, ok := rt.Zinblk[δzblk.Old]
if ok {
inblk.Del(blk)
}
}
// XXX update Zinroot (potentially del)
}
if δzblk.New != xbtree.VDEL {
ztNew, ok := δFtail.trackSetZBlk[δzblk.New]
if !ok {
ztNew = &zblkTrack{}
δFtail.trackSetZBlk[δzblk.New] = ztNew
}
inblk, ok := ztNew.inroot[root]
inblk, ok := rt.Zinblk[δzblk.New]
if !ok {
inblk = make(setI64, 1)
if ztNew.inroot == nil {
ztNew.inroot = make(map[zodb.Oid]setI64)
}
ztNew.inroot[root] = inblk
rt.Zinblk[δzblk.New] = inblk
}
inblk.Add(blk)
// XXX update Zinroot (add)
}
}
}
// take zblk changes into account
for _, oid := range δZ.Changev {
zt, ok := δFtail.trackSetZBlk[oid]
inroot, ok := δFtail.ztrackInRoots[oid]
if !ok {
continue // not tracked
}
for root, inblk := range zt.inroot {
if len(inblk) == 0 {
for root := range inroot {
rt := δFtail.byRoot[root] // must be there
inblk, ok := rt.Zinblk[oid]
if !ok || len(inblk) == 0 {
continue
}
//fmt.Printf("root: %v inblk: %v\n", root, inblk)
files := δFtail.filesByRoot[root]
for file := range files {
for file := range rt.files {
δfile, ok := δF.ByFile[file]
if !ok {
δfile = &ΔFile{Rev: δF.Rev, Blocks: make(setI64)}
......@@ -539,21 +555,24 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) (_ ΔF, err error) {
// update .filesByRoot
if δ.blktabOld != xbtree.VDEL {
files, ok := δFtail.filesByRoot[δ.blktabOld]
rt, ok := δFtail.byRoot[δ.blktabOld]
if ok {
files.Del(foid)
if len(files) == 0 {
delete(δFtail.filesByRoot, δ.blktabOld)
rt.files.Del(foid)
if len(rt.files) == 0 {
delete(δFtail.byRoot, δ.blktabOld)
}
}
}
if δ.blktabNew != xbtree.VDEL {
files, ok := δFtail.filesByRoot[δ.blktabNew]
rt, ok := δFtail.byRoot[δ.blktabNew]
if !ok {
files = setOid{}
δFtail.filesByRoot[δ.blktabNew] = files
rt = &_RootTrack{
files: setOid{},
Zinblk: map[zodb.Oid]setI64{},
}
δFtail.byRoot[δ.blktabNew] = rt
}
files.Add(foid)
rt.files.Add(foid)
}
}
......@@ -692,9 +711,9 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado
// head
root = headRoot
head = δFtail.Head()
for zblk, zt := range δFtail.trackSetZBlk { // XXX locking
inblk, ok := zt.inroot[root]
rt, ok := δFtail.byRoot[root] // XXX locking
if ok {
for zblk, inblk := range rt.Zinblk { // XXX -> no clone
Zinblk[zblk] = inblk.Clone()
}
}
......@@ -702,7 +721,7 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado
δE := vδE[ie+1]
root = δE.oldRoot
head = δE.Rev - 1 // TODO better set to exact revision coming before δE.Rev
for zblk, inblk := range δE.oldTrackSetZBlk {
for zblk, inblk := range δE.oldZinblk {
Zinblk[zblk] = inblk.Clone() // XXX Clone needed ? -> just use oldTrackSetZBlk directly
// XXX -> just use Zinblk = δE.oldTrackSetZBlk directly (without full clone)
// XXX no -> vvv we adjust Zinblk -> thinking
......@@ -1006,7 +1025,7 @@ func vδEBuild(foid zodb.Oid, δZtail *zodb.ΔTail, db *zodb.DB) (vδE []_ΔFile
newRoot: δ.blktabNew,
oldBlkSize: δ.blksizeOld,
newBlkSize: δ.blksizeNew,
oldTrackSetZBlk: nil, // nothing was tracked
oldZinblk: nil, // nothing was tracked
}
vδE = append(vδE, δE)
}
......
......@@ -247,7 +247,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
newRoot: t.Root(),
oldBlkSize: -1,
newBlkSize: blksize,
oldTrackSetZBlk: nil,
oldZinblk: nil,
})
epochv = append(epochv, t1.At)
for blk, zblk := range δt1 {
......@@ -423,12 +423,12 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
δE.oldBlkSize = -1
δE.newBlkSize = blksize
}
oldTrackSetZBlk := map[zodb.Oid]setI64{}
oldZinblk := map[zodb.Oid]setI64{}
for zblk, inblk := range ZinblkPrev {
oid, _ := commit.XGetBlkByName(zblk)
oldTrackSetZBlk[oid] = inblk
oldZinblk[oid] = inblk
}
δE.oldTrackSetZBlk = oldTrackSetZBlk
δE.oldZinblk = oldZinblk
vδE = append(vδE, δE)
}
......@@ -445,26 +445,64 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
retrackAll()
}
// verify δFtail.trackSetZBlk
trackZinblk := map[string]setI64{}
for oid, zt := range δFtail.trackSetZBlk {
zblki := commit.ZBlkTab[oid]
for root, blocks := range zt.inroot {
if root != t.Root() {
t.Errorf(".trackSetZBlk: zblk %s points to unexpected blktab %s", zblki.Name, t.Root())
continue
// verify byRoot, Zinroot
trackZinroot := map[string]setOid{}
trackRfiles := map[zodb.Oid]setOid{}
for root, rt := range δFtail.byRoot {
trackRfiles[root] = rt.files
for zoid := range rt.Zinblk {
zblki := commit.ZBlkTab[zoid]
inroot, ok := trackZinroot[zblki.Name]
if !ok {
inroot = setOid{}
trackZinroot[zblki.Name] = inroot
}
inroot.Add(root)
}
}
inblk, ok := trackZinblk[zblki.Name]
Zinroot := map[string]setOid{}
for zblk := range Zinblk {
inroot := setOid{}; inroot.Add(t.Root())
Zinroot[zblk] = inroot
}
if !reflect.DeepEqual(trackZinroot, Zinroot) {
t.Errorf("Zinroot:\n~have: %v\n want: %v", trackZinroot, Zinroot)
}
filesOK := setOid{}
if !delfile {
filesOK.Add(foid)
}
RfilesOK := map[zodb.Oid]setOid{
t.Root(): filesOK,
}
if !reflect.DeepEqual(trackRfiles, RfilesOK) {
t.Errorf("Rfiles:\n~have: %v\n want: %v", trackRfiles, RfilesOK)
}
// verify Zinblk
trackZinblk := map[string]setI64{}
switch {
case len(δFtail.byRoot) == 0:
// ok
case len(δFtail.byRoot) == 1:
rt, ok := δFtail.byRoot[t.Root()]
if !ok {
inblk = setI64{}
trackZinblk[zblki.Name] = inblk
t.Errorf(".byRoot points to unexpected blktab")
} else {
for zoid, inblk := range rt.Zinblk {
zblki := commit.ZBlkTab[zoid]
trackZinblk[zblki.Name] = inblk.Clone() // XXX clone needed?
}
inblk.Update(blocks)
}
default:
t.Errorf("len(.byRoot) != (0,1) ; byRoot: %v", δFtail.byRoot)
}
if !reflect.DeepEqual(trackZinblk, Zinblk) {
t.Errorf(".trackSetZBlk:\n~have: %v\n want: %v", trackZinblk, Zinblk)
t.Errorf("Zinblk:\n~have: %v\n want: %v", trackZinblk, Zinblk)
}
// ForgetPast configured threshold
......@@ -485,16 +523,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
vδE = vδE[icut:]
}
// verify δFtail.filesByRoot
filesByRootOK := map[zodb.Oid]setOid{}
if !delfile {
__ := setOid{}; __.Add(foid)
filesByRootOK[t.Root()] = __
}
if !reflect.DeepEqual(δFtail.filesByRoot, filesByRootOK) {
t.Errorf("filesByRoot:\nhave: %v\nwant: %v", δFtail.filesByRoot, filesByRootOK)
}
// verify δftail.root
δftail := δFtail.byFile[foid]
rootOK := t.Root()
......
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