Commit dea85e87 authored by Kirill Smelkov's avatar Kirill Smelkov

X Switch GetAt to vδTSnapForTrackedKey

parent 4ef8dd3c
...@@ -319,13 +319,17 @@ func (δBtail *ΔBtail) Tail() zodb.Tid { return δBtail.δZtail.Tail() } ...@@ -319,13 +319,17 @@ func (δBtail *ΔBtail) Tail() zodb.Tid { return δBtail.δZtail.Tail() }
// All path elements must be Tree except last one which, for non-empty tree, must be Bucket. // All path elements must be Tree except last one which, for non-empty tree, must be Bucket.
// //
// Objects in the path must be with .PJar().At() == .Head() // Objects in the path must be with .PJar().At() == .Head()
//
// XXX put keycov back to come first?
func (δBtail *ΔBtail) Track(nodePath []Node, keycov KeyRange) { func (δBtail *ΔBtail) Track(nodePath []Node, keycov KeyRange) {
/* XXX kill
if traceΔBtail { if traceΔBtail {
pathv := []string{} pathv := []string{}
for _, node := range nodePath { pathv = append(pathv, vnode(node)) } for _, node := range nodePath { pathv = append(pathv, vnode(node)) }
tracefΔBtail("\nTrack %s %s\n", keycov, strings.Join(pathv, " -> ")) tracefΔBtail("\nTrack %s %s\n", keycov, strings.Join(pathv, " -> "))
tracefΔBtail("trackSet: %s\n", δBtail.trackSet) // XXX locking tracefΔBtail("trackSet: %s\n", δBtail.trackSet) // XXX locking
} }
*/
head := δBtail.Head() head := δBtail.Head()
for _, node := range nodePath { for _, node := range nodePath {
...@@ -367,6 +371,13 @@ func nodePathToPath(nodePath []Node) (path []zodb.Oid) { ...@@ -367,6 +371,13 @@ func nodePathToPath(nodePath []Node) (path []zodb.Oid) {
func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) { func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) {
// XXX locking // XXX locking
if traceΔBtail {
pathv := []string{}
for _, node := range path { pathv = append(pathv, node.String()) }
tracefΔBtail("\nTrack %s %s\n", keycov, strings.Join(pathv, " -> "))
tracefΔBtail("trackSet: %s\n", δBtail.trackSet)
}
// first normalize path: remove embedded bucket and check if it was an // first normalize path: remove embedded bucket and check if it was an
// empty artificial tree. We need to do the normalization because we // empty artificial tree. We need to do the normalization because we
// later check whether leaf path[-1] ∈ trackSet and without // later check whether leaf path[-1] ∈ trackSet and without
...@@ -388,6 +399,7 @@ func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) { ...@@ -388,6 +399,7 @@ func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) {
} }
return return
} }
// XXX also check if leaf ∈ trackNew ?
// XXX also check if keycov ∈ krebuildJobs // XXX also check if keycov ∈ krebuildJobs
// queue path into trackNew // queue path into trackNew
...@@ -432,10 +444,15 @@ func (δBtail *ΔBtail) rebuild1IfNeeded(root zodb.Oid) error { ...@@ -432,10 +444,15 @@ func (δBtail *ΔBtail) rebuild1IfNeeded(root zodb.Oid) error {
return δBtail.rebuild1(root) return δBtail.rebuild1(root)
} }
// vδTSnapWithTrackedKey returns vδT snapshot for root that takes into account all previous Track requests related to key. // vδTSnapForTrackedKey returns vδT snapshot for root that takes into account at least all previous Track requests related to key.
func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT []ΔTree, err error) { func (δBtail *ΔBtail) vδTSnapForTrackedKey(root zodb.Oid, key Key) (vδT []ΔTree, err error) {
// XXX δBtail.lock // XXX δBtail.lock
δTtail := δBtail.byRoot[root] // must be there δTtail := δBtail.byRoot[root] // must be there
if δTtail == nil {
panicf("δBtail: root<%s> not tracked", root)
}
// TODO key not tracked -> panic (check key ∈ lastRevOf)
if !δTtail.ktrackNew.Has(key) { if !δTtail.ktrackNew.Has(key) {
// key ∉ ktrackNew // key ∉ ktrackNew
...@@ -461,7 +478,6 @@ func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT [] ...@@ -461,7 +478,6 @@ func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT []
// key ∈ ktrackNew -> this goroutine becomes responsible to start rebuilding vδT for it // key ∈ ktrackNew -> this goroutine becomes responsible to start rebuilding vδT for it
// lauch rebuild job for all keys queued in ktrackNew so far // lauch rebuild job for all keys queued in ktrackNew so far
err = δTtail._runRebuildJob(root, δBtail) err = δTtail._runRebuildJob(root, δBtail)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -473,10 +489,13 @@ func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT [] ...@@ -473,10 +489,13 @@ func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT []
return vδT, nil return vδT, nil
} }
// vδTSnapWithTracked returns vδT snapshot for root that takes into account all previous Track requests. // vδTSnapForTracked returns vδT snapshot for root that takes into account all previous Track requests.
func (δBtail *ΔBtail) vδTSnapWithTracked(root zodb.Oid) (vδT []ΔTree, err error) { func (δBtail *ΔBtail) vδTSnapForTracked(root zodb.Oid) (vδT []ΔTree, err error) {
// XXX δBtail.lock // XXX δBtail.lock
δTtail := δBtail.byRoot[root] // must be there δTtail := δBtail.byRoot[root] // must be there
if δTtail == nil {
panicf("δBtail: root<%s> not tracked", root)
}
// prepare to wait for all already running jobs, if any // prepare to wait for all already running jobs, if any
wg := xsync.NewWorkGroup(context.Background()) wg := xsync.NewWorkGroup(context.Background())
...@@ -543,7 +562,7 @@ func (δTtail *_ΔTtail) _runRebuildJob(root zodb.Oid, δBtail *ΔBtail) (err er ...@@ -543,7 +562,7 @@ func (δTtail *_ΔTtail) _runRebuildJob(root zodb.Oid, δBtail *ΔBtail) (err er
} }
// merge rebuild result // merge rebuild result
if err != nil { if err == nil {
// XXX comment about RCU snapshot // XXX comment about RCU snapshot
δTtail.vδT = vδTClone(δTtail.vδT) δTtail.vδT = vδTClone(δTtail.vδT)
δrevSet := vδTMergeInplace(&δTtail.vδT, vδTnew) δrevSet := vδTMergeInplace(&δTtail.vδT, vδTnew)
...@@ -561,8 +580,8 @@ func (δTtail *_ΔTtail) _runRebuildJob(root zodb.Oid, δBtail *ΔBtail) (err er ...@@ -561,8 +580,8 @@ func (δTtail *_ΔTtail) _runRebuildJob(root zodb.Oid, δBtail *ΔBtail) (err er
} }
/* /*
// vδTSnapWithTracked returns vδT snapshot for root that takes into account all previous Track requests. // vδTSnapForTracked returns vδT snapshot for root that takes into account all previous Track requests.
func (δBtail *ΔBtail) vδTSnapWithTracked(root zodb.Oid) (vδT []ΔTree, err error) { func (δBtail *ΔBtail) vδTSnapForTracked(root zodb.Oid) (vδT []ΔTree, err error) {
// XXX δBtail.lock // XXX δBtail.lock
δTtail := δBtail.byRoot[root] // must be there δTtail := δBtail.byRoot[root] // must be there
...@@ -817,6 +836,8 @@ func vδTBuild(root zodb.Oid, trackNew blib.PPTreeSubSet, δZtail *zodb.ΔTail, ...@@ -817,6 +836,8 @@ func vδTBuild(root zodb.Oid, trackNew blib.PPTreeSubSet, δZtail *zodb.ΔTail,
} }
} }
tracefΔBtail("-> vδT: %v\n", vδT)
tracefΔBtail("-> trackNew*: %v\n", trackNew)
return vδT, trackNew, nil return vδT, trackNew, nil
} }
...@@ -1231,32 +1252,50 @@ func (δTtail *_ΔTtail) forgetPast(revCut zodb.Tid) { ...@@ -1231,32 +1252,50 @@ func (δTtail *_ΔTtail) forgetPast(revCut zodb.Tid) {
func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value, rev zodb.Tid, valueExact, revExact bool, err error) { func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value, rev zodb.Tid, valueExact, revExact bool, err error) {
defer xerr.Contextf(&err, "δBtail: root<%s>: get %d @%s", root, key, at) defer xerr.Contextf(&err, "δBtail: root<%s>: get %d @%s", root, key, at)
if traceΔBtail {
tracefΔBtail("\nGet root<%s>[%s] @%s\n", root, kstr(key), at)
defer func() {
vexact := ""
rexact := ""
if !valueExact {
vexact = "~"
}
if !revExact {
rexact = "~"
}
tracefΔBtail("-> value: %s%s rev: @%s%s\n", value, vexact, rev, rexact)
}()
}
tail := δBtail.Tail() tail := δBtail.Tail()
head := δBtail.Head() head := δBtail.Head()
if !(tail < at && at <= head) { if !(tail < at && at <= head) {
panicf("at out of bounds: at: @%s, (tail, head] = (@%s, @%s]", at, tail, head) panicf("at out of bounds: at: @%s, (tail, head] = (@%s, @%s]", at, tail, head)
} }
// XXX locking // // XXX locking
value = VDEL value = VDEL
valueExact = false valueExact = false
rev = tail rev = tail
revExact = false revExact = false
// XXX need to rebuild only if key was not rebuilt yet vδT, err := δBtail.vδTSnapForTrackedKey(root, key)
// XXX need to rebuild only for key, not for whole trackNew // // XXX need to rebuild only if key was not rebuilt yet
// // XXX need to rebuild only for key, not for whole trackNew
// err = δBtail.rebuild1KeyIfNeeded(root, key) XXX reenable // err = δBtail.rebuild1KeyIfNeeded(root, key) XXX reenable
err = δBtail.rebuild1IfNeeded(root) // err = δBtail.rebuild1IfNeeded(root)
if err != nil { if err != nil {
return value, rev, valueExact, revExact, err return value, rev, valueExact, revExact, err
} }
δTtail := δBtail.byRoot[root] debugfΔBtail(" vδT: %v\n", vδT)
if δTtail == nil {
panicf("δBtail: root<%s> not tracked", root) // δTtail := δBtail.byRoot[root]
} // if δTtail == nil {
vδT := δTtail.vδT // panicf("δBtail: root<%s> not tracked", root)
// }
// vδT := δTtail.vδT
// TODO key not tracked -> panic (check key ∈ lastRevOf -- see vvv) // TODO key not tracked -> panic (check key ∈ lastRevOf -- see vvv)
// TODO -> index lastRevOf(key) | linear scan ↓ looking for change ≤ at // TODO -> index lastRevOf(key) | linear scan ↓ looking for change ≤ at
......
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