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

.

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