Commit a31b3751 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 4d9005ee
......@@ -72,15 +72,52 @@ package xbtree
// parallel ΔBtail employs special organization of vδT rebuild process:
//
// 1. vδT is managed under read-copy-update (RCU) discipline: before making
// any vδT change the mutator atomically clones whole vδT and applies the
// any vδT change the mutator atomically clones whole vδT and applies its
// change to the clone. This way a query, once it retrieves vδT snapshot,
// does not need to further synchronize with vδT mutators.
// does not need to further synchronize with vδT mutators, and can count on
// that retrieved vδT snapshot will remain immutable.
//
// 2.
// 2. a Track request goes through 3 states: "new", "handle-in-progress" and
// "handled". At each state keys/nodes of the Track are maintained in:
//
// trackSet, ktrackNew, krebuildJobs + explain rebuild algo (query lock, check ktrackNew, krebuildJob, go/merge/...)
// - ΔTtail.ktrackNew and .trackNew for "new",
// - ΔTtail.krebuildJobs for "handle-in-progress", and
// - ΔBtail.trackSet for "handled"
//
// XXX queries work on vδT snapshot. When updated, vδT is modified via RCU ...
// trackSet keeps nodes, and implicitly keys, from all handled Track
// requests. For all keys, covered by trackSet, vδT is fully computed.
//
// a new Track(keycov, path) is remembered in ktrackNew and trackNew to be
// further processed when a query should need keys from keycov. vδT is not
// yet providing data for keycov keys.
//
// 3. when a query is served, it needs to retrieve vδT snapshot that takes
// related previous Track requests into account. Retrieving such snapshots
// is implemented in vδTSnapForTracked*() family of functions: there it
// checks ktrackNew/trackNew, and if those sets overlap with query's keys
// of interest, run vδT rebuild for keys queued in ktrackNew.
//
// the main part of that rebuild can be run without any locks, because it
// does not use nor modify any ΔBtail data, and for δ(vδT) it just computes
// a fresh full vδT build modulo retrieved ktrackNew. Only after that
// computation is complete, ΔBtail is locked again to quickly merge in
// δ(vδT) update back into vδT.
//
// This organization is based on the fact that
//
// vδT/(T₁∪T₂) = vδT/T₁ | vδT/T₂
//
// i.e. vδT computed for tracked set being union of T₁ and T₂ is the same
// as merge of vδT computed for tracked set T₁ and vδT computed for tracked
// set T₂.
//
// this merge property allows to run computation for δ(vδT) with ΔBtail
// unlocked, which in turn enables running several Track/queries in
// parallel.
//
// 4. while vδT rebuild is being run, krebuildJobs keeps corresponding keycov
// entry to indicate in-progress rebuild. Should a query need vδT for keys
// from that job, it first waits for corresponding job(s) to complete.
//
// This locking organization allows non-overlapping queries/track-requests to
// run simultaneously. This property is essential to WCFS because otherwise WCFS
......@@ -195,13 +232,9 @@ type ΔBtail struct {
//
// See ΔBtail documentation for details.
type _ΔTtail struct {
// XXX explain about snapshot mode + RCU -> move most text to overview
// ...
// XXX text from old rebuild:
// clone vδT before modifying it
// queries such as SliceByRootRev return slices of vδT and we do not
// want to change data that is already returned to user.
vδT []ΔTree // changes to tree keys; rev↑. covers keys ∈ tracked subset
// changes to tree keys; rev↑. covers keys ∈ tracked subset
// Note: changes to vδT go through RCU - see "Concurrency" in overview.
vδT []ΔTree
// set of keys that were requested to be tracked in this tree,
// but for which vδT rebuild was not yet started
......@@ -964,12 +997,10 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) (/*readon
for ; i >= 0 && vδT[i].Rev > lo; i-- {}
i++
// NOTE: no need to duplicate returned vδT slice because
// _ΔTtail.rebuild clones vδT before modifying it. This way the data we
// return to caller will stay unchanged even if rebuild is running
// simultaneously.
//
// XXX adjust the doc to refer to vδT RCU in overview?
// NOTE: no need to duplicate returned vδT slice because vδT is
// modified via RCU: i.e. _ΔTtail.rebuild clones vδT before modifying it.
// This way the data we return to caller will stay unchanged even if
// rebuild is running simultaneously.
return vδT[i:j+1]
}
......
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