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() }
// 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()
//
// XXX put keycov back to come first?
func (δBtail *ΔBtail) Track(nodePath []Node, keycov KeyRange) {
/* XXX kill
if traceΔBtail {
pathv := []string{}
for _, node := range nodePath { pathv = append(pathv, vnode(node)) }
tracefΔBtail("\nTrack %s %s\n", keycov, strings.Join(pathv, " -> "))
tracefΔBtail("trackSet: %s\n", δBtail.trackSet) // XXX locking
}
*/
head := δBtail.Head()
for _, node := range nodePath {
......@@ -367,6 +371,13 @@ func nodePathToPath(nodePath []Node) (path []zodb.Oid) {
func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) {
// 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
// empty artificial tree. We need to do the normalization because we
// later check whether leaf path[-1] ∈ trackSet and without
......@@ -388,6 +399,7 @@ func (δBtail *ΔBtail) track(path []zodb.Oid, keycov KeyRange) {
}
return
}
// XXX also check if leaf ∈ trackNew ?
// XXX also check if keycov ∈ krebuildJobs
// queue path into trackNew
......@@ -432,10 +444,15 @@ func (δBtail *ΔBtail) rebuild1IfNeeded(root zodb.Oid) error {
return δBtail.rebuild1(root)
}
// vδTSnapWithTrackedKey returns vδT snapshot for root that takes into account all previous Track requests related to key.
func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT []ΔTree, err error) {
// 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δTSnapForTrackedKey(root zodb.Oid, key Key) (vδT []ΔTree, err error) {
// XXX δBtail.lock
δ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) {
// key ∉ ktrackNew
......@@ -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
// lauch rebuild job for all keys queued in ktrackNew so far
err = δTtail._runRebuildJob(root, δBtail)
if err != nil {
return nil, err
}
......@@ -473,10 +489,13 @@ func (δBtail *ΔBtail) vδTSnapWithTrackedKey(root zodb.Oid, key Key) (vδT []
return vδT, nil
}
// vδTSnapWithTracked 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) {
// vδTSnapForTracked returns vδT snapshot for root that takes into account all previous Track requests.
func (δBtail *ΔBtail) vδTSnapForTracked(root zodb.Oid) (vδT []ΔTree, err error) {
// XXX δBtail.lock
δ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
wg := xsync.NewWorkGroup(context.Background())
......@@ -543,7 +562,7 @@ func (δTtail *_ΔTtail) _runRebuildJob(root zodb.Oid, δBtail *ΔBtail) (err er
}
// merge rebuild result
if err != nil {
if err == nil {
// XXX comment about RCU snapshot
δTtail.vδT = vδTClone(δTtail.vδT)
δrevSet := vδTMergeInplace(&δTtail.vδT, vδTnew)
......@@ -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.
func (δBtail *ΔBtail) vδTSnapWithTracked(root zodb.Oid) (vδT []ΔTree, err error) {
// vδTSnapForTracked returns vδT snapshot for root that takes into account all previous Track requests.
func (δBtail *ΔBtail) vδTSnapForTracked(root zodb.Oid) (vδT []ΔTree, err error) {
// XXX δBtail.lock
δTtail := δBtail.byRoot[root] // must be there
......@@ -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
}
......@@ -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) {
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()
head := δBtail.Head()
if !(tail < at && at <= head) {
panicf("at out of bounds: at: @%s, (tail, head] = (@%s, @%s]", at, tail, head)
}
// XXX locking
// // XXX locking
value = VDEL
valueExact = false
rev = tail
revExact = false
// XXX need to rebuild only if key was not rebuilt yet
// XXX need to rebuild only for key, not for whole trackNew
vδT, err := δBtail.vδTSnapForTrackedKey(root, key)
// // 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.rebuild1IfNeeded(root)
// err = δBtail.rebuild1IfNeeded(root)
if err != nil {
return value, rev, valueExact, revExact, err
}
δTtail := δBtail.byRoot[root]
if δTtail == nil {
panicf("δBtail: root<%s> not tracked", root)
}
vδT := δTtail.vδT
debugfΔBtail(" vδT: %v\n", vδT)
// δTtail := δBtail.byRoot[root]
// if δTtail == nil {
// panicf("δBtail: root<%s> not tracked", root)
// }
// vδT := δTtail.vδT
// TODO key not tracked -> panic (check key ∈ lastRevOf -- see vvv)
// 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