Commit 5909d6a4 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 0d62b05e
// Code generated by gen-rangemap _RangedMap_RebuildJob _RebuildJob; DO NOT EDIT.
// Code generated by gen-rangemap _RangedMap_RebuildJob *_RebuildJob; DO NOT EDIT.
// Copyright (C) 2021 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
......@@ -33,7 +33,7 @@ import (
const trace_RangedMap_RebuildJob = false
const debug_RangedMap_RebuildJob = false
// _RangedMap_RebuildJob is Key->_RebuildJob map with adjacent keys mapped to the same value coalesced into Ranges.
// _RangedMap_RebuildJob is Key->*_RebuildJob map with adjacent keys mapped to the same value coalesced into Ranges.
//
// Zero value represents empty map.
type _RangedMap_RebuildJob struct {
......@@ -45,19 +45,19 @@ type _RangedMap_RebuildJob struct {
// _RangedMap_RebuildJobEntry represents one entry in _RangedMap_RebuildJob.
type _RangedMap_RebuildJobEntry struct {
Value _RebuildJob
Value *_RebuildJob
blib.KeyRange
}
// Get returns value associated with key k.
func (M *_RangedMap_RebuildJob) Get(k Key) _RebuildJob {
func (M *_RangedMap_RebuildJob) Get(k Key) *_RebuildJob {
v, _ := M.Get_(k)
return v
}
// Set changes M to map key k to value v.
func (M *_RangedMap_RebuildJob) Set(k Key, v _RebuildJob) {
func (M *_RangedMap_RebuildJob) Set(k Key, v *_RebuildJob) {
M.SetRange(blib.KeyRange{Lo: k, Hi_: k}, v)
}
......@@ -75,7 +75,7 @@ func (M *_RangedMap_RebuildJob) Has(k Key) bool {
// Get_ is comma-ok version of Get.
func (M *_RangedMap_RebuildJob) Get_(k Key) (v _RebuildJob, ok bool) {
func (M *_RangedMap_RebuildJob) Get_(k Key) (v *_RebuildJob, ok bool) {
if trace_RangedMap_RebuildJob {
fmt.Printf("\n\nGet_:\n")
fmt.Printf(" M: %s\n", M)
......@@ -108,7 +108,7 @@ func (M *_RangedMap_RebuildJob) Get_(k Key) (v _RebuildJob, ok bool) {
}
// SetRange changes M to map key range r to value v.
func (M *_RangedMap_RebuildJob) SetRange(r blib.KeyRange, v _RebuildJob) {
func (M *_RangedMap_RebuildJob) SetRange(r blib.KeyRange, v *_RebuildJob) {
e := _RangedMap_RebuildJobEntry{v,r}
if trace_RangedMap_RebuildJob {
fmt.Printf("\n\nSetRange:\n")
......@@ -390,7 +390,7 @@ func (M *_RangedMap_RebuildJob) verify() {
}()
hi_Prev := KeyMin
var v_Prev _RebuildJob
var v_Prev *_RebuildJob
for i, e := range M.entryv {
hiPrev := hi_Prev + 1
if i > 0 {
......
......@@ -67,13 +67,19 @@ package xbtree
//
// XXX concurrency
//
// trackSet, ktrackNew, krebuildJobs + explain rebuild algo (query lock, check ktrackNew, krebuildJob, go/merge/...)
//
// This locking organization allows non-overlapping queries/track-requests to
// run simultaneously. Without this property WCFS would not be able to serve
// several non-overlapping READ requests to one file in parallel.
//
// --------
//
// (*) implemented in treediff.go
// (+) full database scan
//go:generate ./blib/gen-rangemap _RangedMap_RebuildJob _RebuildJob zrangemap_rebuildjob.go
////go:generate ./blib/gen-rangemap _RangedMap_Path []zodbOid zrangemap_path.go
//go:generate ./blib/gen-rangemap _RangedMap_RebuildJob *_RebuildJob zrangemap_rebuildjob.go
import (
"context"
......@@ -89,6 +95,7 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xtail"
)
//type zodbOid = zodb.Oid XXX kill probably
const traceΔBtail = false
const debugΔBtail = false
......@@ -141,11 +148,11 @@ type ΔBtail struct {
// 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.
// The set of keys(nodes) that were requested to be tracked, but were
// not yet taken into account, is kept in _ΔTtail.ktrackNew & co.
trackSet blib.PPTreeSubSet
// set of trees for which _ΔTtail.trackNew is non-empty
// set of trees for which _ΔTtail.ktrackNew is non-empty
trackNewRoots setOid
// handle to make connections to access database.
......@@ -159,13 +166,18 @@ type ΔBtail 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
// // set of keys(nodes) that were requested to be tracked in this tree,
// // but for which vδT rebuild was not yet started
// ktrackNew _RangedMap_Path // {} keycov -> path
// set of keys that were requested to be tracked in this tree,
// but for which vδT rebuild was not yet started
ktrackNew blib.RangedKeySet // {keycov}
// set of nodes corresponding to ktrackNew
trackNew blib.PPTreeSubSet
// XXX + trackNewKeys RangedKeySet (concurrency)
// XXX + trackSetKeys RangedKeySet
rebuildNew _RangedMap_RebuildJob // keycov -> _RebuildJob
// set of keys(nodes) for which rebuild is in progress
krebuildJobs _RangedMap_RebuildJob // {} keycov -> job
}
// _ΔBroots represents roots-only part of ΔB.
......@@ -189,9 +201,11 @@ type ΔTree struct {
}
// _RebuildJob represents currently in-progress rebuilding job. XXX
// XXX place
type _RebuildJob struct {
// XXX
ready chan struct{} // closed when job completes
err error
}
......@@ -407,6 +421,87 @@ func (δBtail *ΔBtail) rebuild1IfNeeded(root zodb.Oid) error {
return δBtail.rebuild1(root)
}
// rebuild1KeyIfNeeded rebuilds ΔBtail for single root if that root[key] needs rebuilding.
func (δBtail *ΔBtail) rebuild1KeyIfNeeded(root zodb.Oid, key Key) error {
// XXX δBtail.lock
_, ok := δBtail.trackNewRoots[root]
if !ok {
// XXX δBtail.unlock
return nil
}
// XXX move -> ΔTtail.rebuild1KeyIfNeeded?
δTtail := δBtail.byRoot[root] // must be there
// XXX δTtail.lock
// _, inNew := δTtail.ktrackNew.Get_(key)
inNew := δTtail.ktrackNew.Has(key)
if !inNew {
// key ∉ ktrackNew
job, inJobs := δTtail.krebuildJobs.Get_(key)
if !inJobs {
// key ∉ krebuildJobs -> it should be already in trackSet
// XXX δTtail.unlock
// XXX δBtail.unlock
return nil
}
// rebuild for root[key] is in progress -> wait for corresponding job to complete
// XXX δTtail.unlock
// XXX δBtail.unlock
<-job.ready
return job.err
}
// key ∈ ktrackNew -> this goroutine becomes responsible to start rebuilding vδT for it
// lauch rebuild job for all keys queued in ktrackNew so far
job := &_RebuildJob{ready: make(chan struct{})}
/*
trackNewSet := blib.PPTreeSubSet{} // trackNew corresponding to ktrackNew
rebuildKeys := blib.RangedKeySet{} // keys(ktrackNew)
for _, e := range δTtail.ktrackNew.AllRanges() {
trackNewSet.AddPath(e.Value)
rebuildKeys.AddRange(e.KeyRange)
}
*/
trackNew := δTtail.trackNew
rebuildKeys := δTtail.ktrackNew
δTtail.trackNew = blib.PPTreeSubSet{}
δTtail.ktrackNew = blib.RangedKeySet{}
// krebuildJobs += rebuildKeys
for _, r := range rebuildKeys.AllRanges() {
// XXX assert !krebuildJobs.IntersectsRange(e.KeyRange)
δTtail.krebuildJobs.SetRange(r, job)
}
delete(δBtail.trackNewRoots, root)
// XXX δTtail.unlock
// XXX δBtail.unlock
// XXX δTtail.rebuild(for trackNew) -> err
_ = trackNew
// XXX δBtail.lock ? (to update vδBroots)
// XXX δTtail.lock
// XXX merge rebuild result
// krebuildJobs -= rebuildKeys
for _, r := range rebuildKeys.AllRanges() {
// XXX assert krebuildJobs[r] == job
δTtail.krebuildJobs.DelRange(r)
}
// we are done
job.err = nil // XXX stub
close(job.ready)
// XXX unlock
return job.err
}
// rebuild1 rebuilds ΔBtail for single root.
func (δBtail *ΔBtail) rebuild1(root zodb.Oid) error {
// XXX locking
......@@ -895,6 +990,7 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
// 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)
if err != nil {
return value, rev, valueExact, revExact, err
......@@ -904,11 +1000,12 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
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
for i := len(δTtail.vδT)-1; i >= 0; i-- {
δT := δTtail.vδT[i]
for i := len(vδT)-1; i >= 0; i-- {
δT := vδT[i]
δvalue, ok_ := δT.KV[key]
if ok_ {
valueExact = true
......@@ -951,7 +1048,7 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl
δTtail, ok := δBtail.byRoot[root]
if !ok {
return []ΔTree{}
return []ΔTree{} // XXX -> panic (root must be tracked)
}
vδT := δTtail.vδT
......
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