Commit d99b1b41 authored by Kirill Smelkov's avatar Kirill Smelkov

.

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