Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
5909d6a4
Commit
5909d6a4
authored
Oct 05, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
0d62b05e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
118 additions
and
21 deletions
+118
-21
wcfs/internal/xbtree/zrangemap_rebuildjob.go
wcfs/internal/xbtree/zrangemap_rebuildjob.go
+8
-8
wcfs/internal/xbtree/δbtail.go
wcfs/internal/xbtree/δbtail.go
+110
-13
No files found.
wcfs/internal/xbtree/zrangemap_rebuildjob.go
View file @
5909d6a4
// 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.
// Copyright (C) 2021 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Kirill Smelkov <kirr@nexedi.com>
...
@@ -33,7 +33,7 @@ import (
...
@@ -33,7 +33,7 @@ import (
const
trace_RangedMap_RebuildJob
=
false
const
trace_RangedMap_RebuildJob
=
false
const
debug_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.
// Zero value represents empty map.
type
_RangedMap_RebuildJob
struct
{
type
_RangedMap_RebuildJob
struct
{
...
@@ -45,19 +45,19 @@ type _RangedMap_RebuildJob struct {
...
@@ -45,19 +45,19 @@ type _RangedMap_RebuildJob struct {
// _RangedMap_RebuildJobEntry represents one entry in _RangedMap_RebuildJob.
// _RangedMap_RebuildJobEntry represents one entry in _RangedMap_RebuildJob.
type
_RangedMap_RebuildJobEntry
struct
{
type
_RangedMap_RebuildJobEntry
struct
{
Value
_RebuildJob
Value
*
_RebuildJob
blib
.
KeyRange
blib
.
KeyRange
}
}
// Get returns value associated with key k.
// 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
)
v
,
_
:=
M
.
Get_
(
k
)
return
v
return
v
}
}
// Set changes M to map key k to value 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
)
M
.
SetRange
(
blib
.
KeyRange
{
Lo
:
k
,
Hi_
:
k
},
v
)
}
}
...
@@ -75,7 +75,7 @@ func (M *_RangedMap_RebuildJob) Has(k Key) bool {
...
@@ -75,7 +75,7 @@ func (M *_RangedMap_RebuildJob) Has(k Key) bool {
// Get_ is comma-ok version of Get.
// 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
{
if
trace_RangedMap_RebuildJob
{
fmt
.
Printf
(
"
\n\n
Get_:
\n
"
)
fmt
.
Printf
(
"
\n\n
Get_:
\n
"
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
fmt
.
Printf
(
" M: %s
\n
"
,
M
)
...
@@ -108,7 +108,7 @@ func (M *_RangedMap_RebuildJob) Get_(k Key) (v _RebuildJob, ok bool) {
...
@@ -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.
// 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
}
e
:=
_RangedMap_RebuildJobEntry
{
v
,
r
}
if
trace_RangedMap_RebuildJob
{
if
trace_RangedMap_RebuildJob
{
fmt
.
Printf
(
"
\n\n
SetRange:
\n
"
)
fmt
.
Printf
(
"
\n\n
SetRange:
\n
"
)
...
@@ -390,7 +390,7 @@ func (M *_RangedMap_RebuildJob) verify() {
...
@@ -390,7 +390,7 @@ func (M *_RangedMap_RebuildJob) verify() {
}()
}()
hi_Prev
:=
KeyMin
hi_Prev
:=
KeyMin
var
v_Prev
_RebuildJob
var
v_Prev
*
_RebuildJob
for
i
,
e
:=
range
M
.
entryv
{
for
i
,
e
:=
range
M
.
entryv
{
hiPrev
:=
hi_Prev
+
1
hiPrev
:=
hi_Prev
+
1
if
i
>
0
{
if
i
>
0
{
...
...
wcfs/internal/xbtree/δbtail.go
View file @
5909d6a4
...
@@ -67,13 +67,19 @@ package xbtree
...
@@ -67,13 +67,19 @@ package xbtree
//
//
// XXX concurrency
// 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
// (*) implemented in treediff.go
// (+) full database scan
// (+) 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
(
import
(
"context"
"context"
...
@@ -89,6 +95,7 @@ import (
...
@@ -89,6 +95,7 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xtail"
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xtail"
)
)
//type zodbOid = zodb.Oid XXX kill probably
const
traceΔBtail
=
false
const
traceΔBtail
=
false
const
debugΔBtail
=
false
const
debugΔBtail
=
false
...
@@ -141,11 +148,11 @@ type ΔBtail struct {
...
@@ -141,11 +148,11 @@ type ΔBtail struct {
// 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.
// For this set all vδT are fully computed.
// The set of
nodes that were requested to be tracked, but were not yet
// The set of
keys(nodes) that were requested to be tracked, but were
//
taken into account, is kept in _ΔTtail.
trackNew & co.
//
not yet taken into account, is kept in _ΔTtail.k
trackNew & co.
trackSet
blib
.
PPTreeSubSet
trackSet
blib
.
PPTreeSubSet
// set of trees for which _ΔTtail.trackNew is non-empty
// set of trees for which _ΔTtail.
k
trackNew is non-empty
trackNewRoots
setOid
trackNewRoots
setOid
// handle to make connections to access database.
// handle to make connections to access database.
...
@@ -159,13 +166,18 @@ type ΔBtail struct {
...
@@ -159,13 +166,18 @@ type ΔBtail 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
// // set of keys(nodes) that were requested to be tracked in this tree,
// which vδT was not yet rebuilt
// // 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
trackNew
blib
.
PPTreeSubSet
// XXX + trackNewKeys RangedKeySet (concurrency)
// set of keys(nodes) for which rebuild is in progress
// XXX + trackSetKeys RangedKeySet
krebuildJobs
_RangedMap_RebuildJob
// {} keycov -> job
rebuildNew
_RangedMap_RebuildJob
// keycov -> _RebuildJob
}
}
// _ΔBroots represents roots-only part of ΔB.
// _ΔBroots represents roots-only part of ΔB.
...
@@ -189,9 +201,11 @@ type ΔTree struct {
...
@@ -189,9 +201,11 @@ type ΔTree struct {
}
}
// _RebuildJob represents currently in-progress rebuilding job. XXX
// XXX place
// XXX place
type
_RebuildJob
struct
{
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 {
...
@@ -407,6 +421,87 @@ func (δBtail *ΔBtail) rebuild1IfNeeded(root zodb.Oid) error {
return
δBtail
.
rebuild1
(
root
)
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.
// rebuild1 rebuilds ΔBtail for single root.
func
(
δBtail
*
ΔBtail
)
rebuild1
(
root
zodb
.
Oid
)
error
{
func
(
δBtail
*
ΔBtail
)
rebuild1
(
root
zodb
.
Oid
)
error
{
// XXX locking
// XXX locking
...
@@ -895,6 +990,7 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
...
@@ -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 if key was not rebuilt yet
// XXX need to rebuild only for key, not for whole trackNew
// 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
{
if
err
!=
nil
{
return
value
,
rev
,
valueExact
,
revExact
,
err
return
value
,
rev
,
valueExact
,
revExact
,
err
...
@@ -904,11 +1000,12 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
...
@@ -904,11 +1000,12 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
if
δTtail
==
nil
{
if
δTtail
==
nil
{
panicf
(
"δBtail: root<%s> not tracked"
,
root
)
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
for
i
:=
len
(
δTtail
.
vδT
)
-
1
;
i
>=
0
;
i
--
{
for
i
:=
len
(
vδT
)
-
1
;
i
>=
0
;
i
--
{
δT
:=
δTtail
.
vδT
[
i
]
δT
:=
vδT
[
i
]
δvalue
,
ok_
:=
δT
.
KV
[
key
]
δvalue
,
ok_
:=
δT
.
KV
[
key
]
if
ok_
{
if
ok_
{
valueExact
=
true
valueExact
=
true
...
@@ -951,7 +1048,7 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl
...
@@ -951,7 +1048,7 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl
δTtail
,
ok
:=
δBtail
.
byRoot
[
root
]
δTtail
,
ok
:=
δBtail
.
byRoot
[
root
]
if
!
ok
{
if
!
ok
{
return
[]
ΔTree
{}
return
[]
ΔTree
{}
// XXX -> panic (root must be tracked)
}
}
vδT
:=
δTtail
.
vδT
vδT
:=
δTtail
.
vδT
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment