Commit d99b1b41 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 37c2e806
......@@ -136,6 +136,15 @@ func (a Set) Equal(b Set) bool {
return true
}
// Clone returns copy of the set.
func (orig Set) Clone() Set {
klon := make(Set, len(orig))
for v := range orig {
klon.Add(v)
}
return klon
}
// --------
func (s Set) SortedElements() []VALUE {
......
......@@ -138,6 +138,15 @@ func (a SetI64) Equal(b SetI64) bool {
return true
}
// Clone returns copy of the set.
func (orig SetI64) Clone() SetI64 {
klon := make(SetI64, len(orig))
for v := range orig {
klon.Add(v)
}
return klon
}
// --------
func (s SetI64) SortedElements() []int64 {
......
......@@ -138,6 +138,15 @@ func (a SetOid) Equal(b SetOid) bool {
return true
}
// Clone returns copy of the set.
func (orig SetOid) Clone() SetOid {
klon := make(SetOid, len(orig))
for v := range orig {
klon.Add(v)
}
return klon
}
// --------
func (s SetOid) SortedElements() []_Oid {
......
......@@ -93,8 +93,6 @@ type ΔBtail struct {
// includes all changed objects, not only tracked ones.
δZtail *zodb.ΔTail
// XXX vvv keys ∈ tracked -> keys ∈ kadj[tracked] ?
// vδB []ΔB // data with δB changes; Noted only by keys ∈ tracked subset
byRoot map[zodb.Oid]*ΔTtail // {} root -> [] k/v change history; only for keys ∈ tracked subset
// handle to make connections to access database.
......@@ -102,17 +100,13 @@ type ΔBtail struct {
db *zodb.DB // to open connections to load new/old tree|buckets
// set of tracked nodes as of @head state.
// For this set all vδT are fully computed.
// The set of nodes that were requested to be tracked, but were not yet
// taken into account, is kept in ΔTtail.trackNew & co.
trackSet PPTreeSubSet
// set of nodes that were requested to be tracked, but for which vδB was not yet rebuilt
trackNew PPTreeSubSet
}
// ΔB represents a change in BTrees space.
type ΔB struct {
Rev zodb.Tid
ByRoot map[zodb.Oid]map[Key]ΔValue // {} root -> {}(key, δvalue)
// set of trees for which trackNew is non-empty
trackNewRoots SetOid
}
// ΔTtail represent tail of revisional changes to one BTree.
......@@ -121,6 +115,11 @@ type ΔB struct {
type ΔTtail struct {
vδT []ΔTree // changes to tree keys; rev↑. covers keys ∈ tracked subset
// set of nodes that were requested to be tracked in this tree, but for
// which vδT was not yet rebuilt
trackNew PPTreeSubSet
// XXX + trackNewKeys RangedKeySet
// {}k/v @tail for keys that are changed in (tail, head].
KVAtTail map[Key]Value // XXX not needed since vδT has ΔValue ?
......@@ -128,6 +127,13 @@ type ΔTtail struct {
lastRevOf map[Key]zodb.Tid // {} key -> last
}
// ΔB represents a change in BTrees space.
type ΔB struct {
Rev zodb.Tid
ByRoot map[zodb.Oid]map[Key]ΔValue // {} root -> {}(key, δvalue)
}
// ΔTree describes changes to one BTree in one revision.
// XXX -> ΔT ?
type ΔTree struct {
......@@ -148,8 +154,17 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail {
δZtail: zodb.NewΔTail(at0),
byRoot: map[zodb.Oid]*ΔTtail{},
trackSet: PPTreeSubSet{},
trackNew: PPTreeSubSet{},
db: db,
trackNewRoots: SetOid{},
db: db,
}
}
// newΔTtail creates new empty ΔTtail object.
func newΔTtail() *ΔTtail {
return &ΔTtail{
trackNew: PPTreeSubSet{},
KVAtTail: make(map[Key]Value),
lastRevOf: make(map[Key]zodb.Tid),
}
}
......@@ -163,15 +178,16 @@ func (orig *ΔBtail) clone() *ΔBtail {
klon.δZtail.Append(δZ.Rev, δZ.Changev)
}
// trackSet, trackNew
// trackSet, trackNewRoots
klon.trackSet = orig.trackSet.Clone()
klon.trackNew = orig.trackNew.Clone()
klon.trackNewRoots = orig.trackNewRoots.Clone()
// byRoot
klon.byRoot = make(map[zodb.Oid]*ΔTtail, len(orig.byRoot))
for root, origΔTtail := range orig.byRoot {
klonΔTtail := &ΔTtail{}
klonΔTtail.vδT = append(klonΔTtail.vδT, origΔTtail.vδT...)
klonΔTtail.trackNew = origΔTtail.trackNew.Clone()
klonΔTtail.KVAtTail = make(map[Key]Value, len(origΔTtail.KVAtTail))
for k, v := range origΔTtail.KVAtTail {
klonΔTtail.KVAtTail[k] = v
......@@ -186,14 +202,6 @@ func (orig *ΔBtail) clone() *ΔBtail {
return klon
}
// newΔTtail creates new empty ΔTtail object.
func newΔTtail() *ΔTtail {
return &ΔTtail{
KVAtTail: make(map[Key]Value),
lastRevOf: make(map[Key]zodb.Tid),
}
}
// (tail, head] coverage
func (δBtail *ΔBtail) Head() zodb.Tid { return δBtail.δZtail.Head() }
func (δBtail *ΔBtail) Tail() zodb.Tid { return δBtail.δZtail.Tail() }
......@@ -231,38 +239,59 @@ func (δBtail *ΔBtail) track(key Key, keyPresent bool, path []zodb.Oid) error {
// XXX locking
root := path[0]
δBtail.trackNew.AddPath(path)
// track is track of path[-1] (i.e. leaf)
// XXX hack - until rebuild is implemented
if XXX_killWhenRebuildWorks {
_, ok := δBtail.byRoot[root]
δTtail, ok := δBtail.byRoot[root]
if !ok {
δBtail.byRoot[root] = newΔTtail()
δTtail = newΔTtail()
δBtail.byRoot[root] = δTtail
}
}
δBtail.trackNewRoots.Add(root)
δTtail.trackNew.AddPath(path)
// track is track of path[-1] (i.e. leaf)
// XXX update diff XXX here? or as separate step?
// XXX update lastRevOf
return nil
}
// rebuild rebuilds ΔBtail taking trackNew requests into account.
// rebuildAll rebuilds ΔBtail taking all trackNew requests into account.
func (δBtail *ΔBtail) rebuildAll() (err error) {
defer xerr.Context(&err, "ΔBtail rebuildAll")
// XXX locking
trackNewRoots := δBtail.trackNewRoots
for root := range trackNewRoots {
δTtail := δBtail.byRoot[root] // must be there
δtrackSet, err := δTtail.rebuild()
if err != nil {
return err
}
δBtail.trackSet.UnionInplace(δtrackSet)
}
δBtail.trackNewRoots = SetOid{}
return nil
}
// rebuild rebuilds ΔTtail taking trackNew requests into account.
//
// It returns set of nodes that must be added to ΔBtail.trackSet to account for
// keys that becomes tracked. Note: this set is potentially wider compared to .trackNew.
// XXX place
func (δBtail *ΔBtail) rebuild() (err error) {
defer xerr.Context(&err, Btail rebuild")
func (δTtail *ΔTtail) rebuild() (δtrackSet PPTreeSubSet, err error) {
defer xerr.Context(&err, Ttail rebuild")
// XXX locking
tracefΔBtail("\nRebuild @%s .. @%s\n", δBtail.Tail(), δBtail.Head())
tracefΔBtail("trackSet: %v\n", δBtail.trackSet)
tracefΔBtail("trackNew: %v\n", δBtail.trackNew)
tracefΔBtail("trackNew: %v\n", δTtail.trackNew)
trackNew := δBtail.trackNew
δBtail.trackNew = PPTreeSubSet{}
trackNew := δTtail.trackNew
δTtail.trackNew = PPTreeSubSet{}
if len(trackNew) == 0 {
return
return nil, nil
}
// go backwards and merge vδT <- treediff(lo..hi/trackNew)
......@@ -285,7 +314,6 @@ func (δBtail *ΔBtail) rebuild() (err error) {
debugfΔBtail("\n rebuild @%s <- @%s\n", atPrev, δZ.Rev)
debugfΔBtail(" δZ:\t%v\n", δZ.Changev)
debugfΔBtail(" trackNew: %v\n", trackNew)
debugfΔBtail(" trackSet: %v\n", δBtail.trackSet) // XXX needed?
defer debugfΔBtail("\n\n")
// XXX len(δtopsByRoot) == 0 -> skip
......@@ -297,18 +325,18 @@ func (δBtail *ΔBtail) rebuild() (err error) {
zconnPrev, err := δBtail.db.Open(ctx, &zodb.ConnOptions{At: atPrev})
if err != nil {
return err
return nil, err
}
zconnCurr, err := δBtail.db.Open(ctx, &zodb.ConnOptions{At: δZ.Rev})
if err != nil {
return err
return nil, err
}
for root, δtops := range δtopsByRoot {
// diff backwards curr -> prev
δT, δtrack, δtkeycov, err := treediff(ctx, root, δtops, δZTC, trackNew, zconnCurr, zconnPrev)
if err != nil {
return err
return nil, err
}
// FIXME use δtkeycov to recompute track coverage
......@@ -323,12 +351,14 @@ func (δBtail *ΔBtail) rebuild() (err error) {
continue
}
/* XXX kill
δTtail, ok := δBtail.byRoot[root]
if !ok {
// this root was not tracked before -> create δTtail for it with empty changes
δTtail = newΔTtail()
δBtail.byRoot[root] = δTtail
}
*/
// δTtail.vδT <- merge δT*
l := len(δTtail.vδT)
......@@ -363,6 +393,7 @@ func (δBtail *ΔBtail) rebuild() (err error) {
}
}
/*
// trackNew was adjusted to correspond to @tail potentially growing its key coverage.
// Remap it back to @head and merge to .trackSet
for _, δtrack := range vδtrack {
......@@ -370,8 +401,8 @@ func (δBtail *ΔBtail) rebuild() (err error) {
trackNew.ApplyΔ(δtrack)
}
δBtail.trackSet.UnionInplace(trackNew)
return nil
*/
return δtrackSet, nil
}
// Update updates δB with per-object level ZODB changes.
......@@ -398,18 +429,25 @@ func (δBtail *ΔBtail) _Update(δZ *zodb.EventCommit) (_ ΔB, δTKeyCov _ΔTrac
tracefΔBtail("\nUpdate @%s -> @%s δZ: %v\n", δBtail.Head(), δZ.Tid, δZ.Changev)
tracefΔBtail("trackSet: %v\n", δBtail.trackSet)
tracefΔBtail("trackNew: %v\n", δBtail.trackNew)
for _, root := range δBtail.trackNewRoots.SortedElements() {
δTtail := δBtail.byRoot[root]
tracefΔBtail("[%s].trackNew: %v\n", δTtail.trackNew)
}
δTKeyCov = _ΔTrackKeyCov{ByRoot: make(map[zodb.Oid]*RangedKeySet)}
if XXX_killWhenRebuildWorks {
// XXX hack - until vvv is reenabled
δBtail.trackSet.UnionInplace(δBtail.trackNew)
δBtail.trackNew = PPTreeSubSet{}
for root := range δBtail.trackNewRoots {
δTtail := δBtail.byRoot[root] // must succeed
δBtail.trackSet.UnionInplace(δTtail.trackNew)
δTtail.trackNew = PPTreeSubSet{}
}
δBtail.trackNewRoots = SetOid{}
} else {
// XXX reenable (currently breaks wcfs tests)
// update .trackSet and vδB from .trackNew
err = δBtail.rebuild()
err = δBtail.rebuildAll()
if err != nil {
return ΔB{}, δTKeyCov, err
}
......
......@@ -911,7 +911,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// t1 := t2.prev
// t0 := t1.prev
t.Run(fmt.Sprintf("rebuild/%s→%s", t0.tree, t1.tree), func(t *testing.T) {
t.Skip("TODO") // FIXME rebuild is currently broken
// t.Skip("TODO") // FIXME rebuild is currently broken
tAllKeys := allTestKeys(t0, t1, t2)
tAllKeyv := tAllKeys.SortedElements()
......
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