Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
7fe0d5a4
Commit
7fe0d5a4
authored
Feb 04, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
897b9100
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
47 additions
and
47 deletions
+47
-47
go/zodb/db.go
go/zodb/db.go
+2
-2
go/zodb/δtail.go
go/zodb/δtail.go
+20
-20
go/zodb/δtail_test.go
go/zodb/δtail_test.go
+25
-25
No files found.
go/zodb/db.go
View file @
7fe0d5a4
...
@@ -405,7 +405,7 @@ func (conn *Connection) resyncAndDBUnlock(txn transaction.Transaction, at Tid) {
...
@@ -405,7 +405,7 @@ func (conn *Connection) resyncAndDBUnlock(txn transaction.Transaction, at Tid) {
// both conn.at and at are covered by δtail - we can invalidate selectively
// both conn.at and at are covered by δtail - we can invalidate selectively
if
(
δtail
.
Tail
()
<
conn
.
at
&&
conn
.
at
<=
δtail
.
Head
())
&&
// XXX conn.at can = δtail.Tail
if
(
δtail
.
Tail
()
<
conn
.
at
&&
conn
.
at
<=
δtail
.
Head
())
&&
// XXX conn.at can = δtail.Tail
(
δtail
.
Tail
()
<
at
&&
at
<=
δtail
.
Head
())
{
(
δtail
.
Tail
()
<
at
&&
at
<=
δtail
.
Head
())
{
var
δv
[]
δ
RevEntry
var
δv
[]
Δ
RevEntry
if
conn
.
at
<=
at
{
if
conn
.
at
<=
at
{
δv
=
δtail
.
SliceByRev
(
conn
.
at
,
at
)
δv
=
δtail
.
SliceByRev
(
conn
.
at
,
at
)
}
else
{
}
else
{
...
@@ -414,7 +414,7 @@ func (conn *Connection) resyncAndDBUnlock(txn transaction.Transaction, at Tid) {
...
@@ -414,7 +414,7 @@ func (conn *Connection) resyncAndDBUnlock(txn transaction.Transaction, at Tid) {
}
}
for
_
,
δ
:=
range
δv
{
for
_
,
δ
:=
range
δv
{
for
_
,
oid
:=
range
δ
.
c
hangev
{
for
_
,
oid
:=
range
δ
.
C
hangev
{
δobj
[
oid
]
=
struct
{}{}
δobj
[
oid
]
=
struct
{}{}
}
}
}
}
...
...
go/zodb/δtail.go
View file @
7fe0d5a4
...
@@ -59,18 +59,18 @@ import (
...
@@ -59,18 +59,18 @@ import (
type
ΔTail
struct
{
type
ΔTail
struct
{
head
Tid
head
Tid
tail
Tid
tail
Tid
tailv
[]
δ
RevEntry
// XXX -> revv ?
tailv
[]
Δ
RevEntry
// XXX -> revv ?
lastRevOf
map
[
Oid
]
Tid
// index for LastRevOf queries
lastRevOf
map
[
Oid
]
Tid
// index for LastRevOf queries
// XXX -> lastRevOf = {} oid -> []rev↑ if linear scan in LastRevOf starts to eat cpu
// XXX -> lastRevOf = {} oid -> []rev↑ if linear scan in LastRevOf starts to eat cpu
}
}
//
δ
RevEntry represents information of what have been changed in one revision.
//
Δ
RevEntry represents information of what have been changed in one revision.
//
//
// XXX -> CommitEvent?
-> ΔRevEntry?
// XXX -> CommitEvent?
type
δ
RevEntry
struct
{
type
Δ
RevEntry
struct
{
r
ev
Tid
R
ev
Tid
c
hangev
[]
Oid
C
hangev
[]
Oid
}
}
// NewΔTail creates new ΔTail object.
// NewΔTail creates new ΔTail object.
...
@@ -112,7 +112,7 @@ func (δtail *ΔTail) Tail() Tid {
...
@@ -112,7 +112,7 @@ func (δtail *ΔTail) Tail() Tid {
// the caller must not modify returned slice.
// the caller must not modify returned slice.
//
//
// Note: contrary to regular go slicing, low is exclusive while high is inclusive.
// Note: contrary to regular go slicing, low is exclusive while high is inclusive.
func
(
δtail
*
ΔTail
)
SliceByRev
(
low
,
high
Tid
)
/*readonly*/
[]
δ
RevEntry
{
func
(
δtail
*
ΔTail
)
SliceByRev
(
low
,
high
Tid
)
/*readonly*/
[]
Δ
RevEntry
{
tail
:=
δtail
.
Tail
()
tail
:=
δtail
.
Tail
()
head
:=
δtail
.
head
head
:=
δtail
.
head
if
!
(
tail
<=
low
&&
low
<=
high
&&
high
<=
head
)
{
if
!
(
tail
<=
low
&&
low
<=
high
&&
high
<=
head
)
{
...
@@ -128,14 +128,14 @@ func (δtail *ΔTail) SliceByRev(low, high Tid) /*readonly*/ []δRevEntry {
...
@@ -128,14 +128,14 @@ func (δtail *ΔTail) SliceByRev(low, high Tid) /*readonly*/ []δRevEntry {
// find max j : [j].rev ≤ high XXX linear scan -> binary search
// find max j : [j].rev ≤ high XXX linear scan -> binary search
j
:=
len
(
tailv
)
-
1
j
:=
len
(
tailv
)
-
1
for
;
j
>=
0
&&
tailv
[
j
]
.
r
ev
>
high
;
j
--
{}
for
;
j
>=
0
&&
tailv
[
j
]
.
R
ev
>
high
;
j
--
{}
if
j
<
0
{
if
j
<
0
{
return
nil
// ø
return
nil
// ø
}
}
// find max i : [i].rev > low XXX linear scan -> binary search
// find max i : [i].rev > low XXX linear scan -> binary search
i
:=
j
i
:=
j
for
;
i
>=
0
&&
tailv
[
i
]
.
r
ev
>
low
;
i
--
{}
for
;
i
>=
0
&&
tailv
[
i
]
.
R
ev
>
low
;
i
--
{}
i
++
i
++
return
tailv
[
i
:
j
+
1
]
return
tailv
[
i
:
j
+
1
]
...
@@ -154,7 +154,7 @@ func (δtail *ΔTail) Append(rev Tid, changev []Oid) {
...
@@ -154,7 +154,7 @@ func (δtail *ΔTail) Append(rev Tid, changev []Oid) {
}
}
δtail
.
head
=
rev
δtail
.
head
=
rev
δtail
.
tailv
=
append
(
δtail
.
tailv
,
δ
RevEntry
{
rev
,
changev
})
δtail
.
tailv
=
append
(
δtail
.
tailv
,
Δ
RevEntry
{
rev
,
changev
})
for
_
,
id
:=
range
changev
{
for
_
,
id
:=
range
changev
{
δtail
.
lastRevOf
[
id
]
=
rev
δtail
.
lastRevOf
[
id
]
=
rev
}
}
...
@@ -169,14 +169,14 @@ func (δtail *ΔTail) ForgetPast(revCut Tid) {
...
@@ -169,14 +169,14 @@ func (δtail *ΔTail) ForgetPast(revCut Tid) {
icut
:=
0
icut
:=
0
for
i
,
δ
:=
range
δtail
.
tailv
{
for
i
,
δ
:=
range
δtail
.
tailv
{
rev
:=
δ
.
r
ev
rev
:=
δ
.
R
ev
if
rev
>
revCut
{
if
rev
>
revCut
{
break
break
}
}
icut
=
i
+
1
icut
=
i
+
1
// if forgotten revision was last for id, we have to update lastRevOf index
// if forgotten revision was last for id, we have to update lastRevOf index
for
_
,
id
:=
range
δ
.
c
hangev
{
for
_
,
id
:=
range
δ
.
C
hangev
{
if
δtail
.
lastRevOf
[
id
]
==
rev
{
if
δtail
.
lastRevOf
[
id
]
==
rev
{
delete
(
δtail
.
lastRevOf
,
id
)
delete
(
δtail
.
lastRevOf
,
id
)
}
}
...
@@ -187,7 +187,7 @@ func (δtail *ΔTail) ForgetPast(revCut Tid) {
...
@@ -187,7 +187,7 @@ func (δtail *ΔTail) ForgetPast(revCut Tid) {
// 1) growing underlying storage array indefinitely
// 1) growing underlying storage array indefinitely
// 2) keeping underlying storage after forget
// 2) keeping underlying storage after forget
l
:=
len
(
δtail
.
tailv
)
-
icut
l
:=
len
(
δtail
.
tailv
)
-
icut
tailv
:=
make
([]
δ
RevEntry
,
l
)
tailv
:=
make
([]
Δ
RevEntry
,
l
)
copy
(
tailv
,
δtail
.
tailv
[
icut
:
])
copy
(
tailv
,
δtail
.
tailv
[
icut
:
])
δtail
.
tailv
=
tailv
δtail
.
tailv
=
tailv
...
@@ -226,8 +226,8 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
...
@@ -226,8 +226,8 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
if
l
==
0
{
if
l
==
0
{
return
at
,
false
return
at
,
false
}
}
revMin
:=
δtail
.
tailv
[
0
]
.
r
ev
revMin
:=
δtail
.
tailv
[
0
]
.
R
ev
revMax
:=
δtail
.
tailv
[
l
-
1
]
.
r
ev
revMax
:=
δtail
.
tailv
[
l
-
1
]
.
R
ev
if
!
(
revMin
<=
at
&&
at
<=
revMax
)
{
if
!
(
revMin
<=
at
&&
at
<=
revMax
)
{
return
at
,
false
return
at
,
false
}
}
...
@@ -235,7 +235,7 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
...
@@ -235,7 +235,7 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
// we have the coverage
// we have the coverage
rev
,
ok
:=
δtail
.
lastRevOf
[
id
]
rev
,
ok
:=
δtail
.
lastRevOf
[
id
]
if
!
ok
{
if
!
ok
{
return
δtail
.
tailv
[
0
]
.
r
ev
,
false
return
δtail
.
tailv
[
0
]
.
R
ev
,
false
}
}
if
rev
<=
at
{
if
rev
<=
at
{
...
@@ -246,17 +246,17 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
...
@@ -246,17 +246,17 @@ func (δtail *ΔTail) LastRevOf(id Oid, at Tid) (_ Tid, exact bool) {
// XXX linear scan - see .lastRevOf comment.
// XXX linear scan - see .lastRevOf comment.
for
i
:=
l
-
1
;
i
>=
0
;
i
--
{
for
i
:=
l
-
1
;
i
>=
0
;
i
--
{
δ
:=
δtail
.
tailv
[
i
]
δ
:=
δtail
.
tailv
[
i
]
if
δ
.
r
ev
>
at
{
if
δ
.
R
ev
>
at
{
continue
continue
}
}
for
_
,
δid
:=
range
δ
.
c
hangev
{
for
_
,
δid
:=
range
δ
.
C
hangev
{
if
id
==
δid
{
if
id
==
δid
{
return
δ
.
r
ev
,
true
return
δ
.
R
ev
,
true
}
}
}
}
}
}
// nothing found
// nothing found
return
δtail
.
tailv
[
0
]
.
r
ev
,
false
return
δtail
.
tailv
[
0
]
.
R
ev
,
false
}
}
go/zodb/δtail_test.go
View file @
7fe0d5a4
...
@@ -28,22 +28,22 @@ import (
...
@@ -28,22 +28,22 @@ import (
func
TestΔTail
(
t
*
testing
.
T
)
{
func
TestΔTail
(
t
*
testing
.
T
)
{
var
δtail
*
ΔTail
var
δtail
*
ΔTail
// R is syntactic sugar to create 1
δ
RevEntry
// R is syntactic sugar to create 1
Δ
RevEntry
R
:=
func
(
rev
Tid
,
changev
...
Oid
)
δ
RevEntry
{
R
:=
func
(
rev
Tid
,
changev
...
Oid
)
Δ
RevEntry
{
return
δ
RevEntry
{
rev
,
changev
}
return
Δ
RevEntry
{
rev
,
changev
}
}
}
// δAppend is syntactic sugar for δtail.Append
// δAppend is syntactic sugar for δtail.Append
δAppend
:=
func
(
δ
δ
RevEntry
)
{
δAppend
:=
func
(
δ
Δ
RevEntry
)
{
δtail
.
Append
(
δ
.
rev
,
δ
.
c
hangev
)
δtail
.
Append
(
δ
.
Rev
,
δ
.
C
hangev
)
}
}
// δCheck verifies that δtail state corresponds to provided tailv
// δCheck verifies that δtail state corresponds to provided tailv
δCheck
:=
func
(
tail
,
head
Tid
,
tailv
...
δ
RevEntry
)
{
δCheck
:=
func
(
tail
,
head
Tid
,
tailv
...
Δ
RevEntry
)
{
t
.
Helper
()
t
.
Helper
()
for
i
:=
1
;
i
<
len
(
tailv
);
i
++
{
for
i
:=
1
;
i
<
len
(
tailv
);
i
++
{
if
!
(
tailv
[
i
-
1
]
.
rev
<
tailv
[
i
]
.
r
ev
)
{
if
!
(
tailv
[
i
-
1
]
.
Rev
<
tailv
[
i
]
.
R
ev
)
{
panic
(
"test tailv: rev not ↑"
)
panic
(
"test tailv: rev not ↑"
)
}
}
}
}
...
@@ -86,13 +86,13 @@ func TestΔTail(t *testing.T) {
...
@@ -86,13 +86,13 @@ func TestΔTail(t *testing.T) {
// make sure returned region is indeed correct
// make sure returned region is indeed correct
tbefore
:=
Tid
(
0
)
tbefore
:=
Tid
(
0
)
if
ilo
-
1
>=
0
{
if
ilo
-
1
>=
0
{
tbefore
=
tailv
[
ilo
-
1
]
.
r
ev
-
1
tbefore
=
tailv
[
ilo
-
1
]
.
R
ev
-
1
}
}
tail
:=
tailv
[
ilo
]
.
r
ev
-
1
tail
:=
tailv
[
ilo
]
.
R
ev
-
1
head
:=
tailv
[
ihi
-
1
]
.
r
ev
head
:=
tailv
[
ihi
-
1
]
.
R
ev
hafter
:=
TidMax
hafter
:=
TidMax
if
ihi
<
len
(
tailv
)
{
if
ihi
<
len
(
tailv
)
{
hafter
=
tailv
[
ihi
]
.
r
ev
hafter
=
tailv
[
ihi
]
.
R
ev
}
}
if
!
(
tbefore
<
rlo
&&
rlo
<=
tail
&&
head
<=
rhi
&&
rhi
<
hafter
)
{
if
!
(
tbefore
<
rlo
&&
rlo
<=
tail
&&
head
<=
rhi
&&
rhi
<
hafter
)
{
...
@@ -105,23 +105,23 @@ func TestΔTail(t *testing.T) {
...
@@ -105,23 +105,23 @@ func TestΔTail(t *testing.T) {
for
ihi
:=
ilo
;
ihi
<
len
(
tailv
);
ihi
++
{
for
ihi
:=
ilo
;
ihi
<
len
(
tailv
);
ihi
++
{
// [ilo, ihi)
// [ilo, ihi)
sliceByRev
(
sliceByRev
(
tailv
[
ilo
]
.
r
ev
-
1
,
tailv
[
ilo
]
.
R
ev
-
1
,
tailv
[
ihi
]
.
r
ev
-
1
,
tailv
[
ihi
]
.
R
ev
-
1
,
ilo
,
ihi
,
ilo
,
ihi
,
)
)
// [ilo, ihi]
// [ilo, ihi]
sliceByRev
(
sliceByRev
(
tailv
[
ilo
]
.
r
ev
-
1
,
tailv
[
ilo
]
.
R
ev
-
1
,
tailv
[
ihi
]
.
r
ev
,
tailv
[
ihi
]
.
R
ev
,
ilo
,
ihi
+
1
,
ilo
,
ihi
+
1
,
)
)
// (ilo, ihi]
// (ilo, ihi]
if
ilo
+
1
<
len
(
tailv
)
{
if
ilo
+
1
<
len
(
tailv
)
{
sliceByRev
(
sliceByRev
(
tailv
[
ilo
]
.
r
ev
,
tailv
[
ilo
]
.
R
ev
,
tailv
[
ihi
]
.
r
ev
,
tailv
[
ihi
]
.
R
ev
,
ilo
+
1
,
ihi
+
1
,
ilo
+
1
,
ihi
+
1
,
)
)
}
}
...
@@ -129,8 +129,8 @@ func TestΔTail(t *testing.T) {
...
@@ -129,8 +129,8 @@ func TestΔTail(t *testing.T) {
// (ilo, ihi)
// (ilo, ihi)
if
ilo
+
1
<
len
(
tailv
)
&&
ilo
+
1
<=
ihi
{
if
ilo
+
1
<
len
(
tailv
)
&&
ilo
+
1
<=
ihi
{
sliceByRev
(
sliceByRev
(
tailv
[
ilo
]
.
r
ev
,
tailv
[
ilo
]
.
R
ev
,
tailv
[
ihi
]
.
r
ev
-
1
,
tailv
[
ihi
]
.
R
ev
-
1
,
ilo
+
1
,
ihi
,
ilo
+
1
,
ihi
,
)
)
}
}
...
@@ -140,13 +140,13 @@ func TestΔTail(t *testing.T) {
...
@@ -140,13 +140,13 @@ func TestΔTail(t *testing.T) {
// verify lastRevOf query / index
// verify lastRevOf query / index
lastRevOf
:=
make
(
map
[
Oid
]
Tid
)
lastRevOf
:=
make
(
map
[
Oid
]
Tid
)
for
_
,
δ
:=
range
tailv
{
for
_
,
δ
:=
range
tailv
{
for
_
,
id
:=
range
δ
.
c
hangev
{
for
_
,
id
:=
range
δ
.
C
hangev
{
idRev
,
exact
:=
δtail
.
LastRevOf
(
id
,
δ
.
r
ev
)
idRev
,
exact
:=
δtail
.
LastRevOf
(
id
,
δ
.
R
ev
)
if
!
(
idRev
==
δ
.
r
ev
&&
exact
)
{
if
!
(
idRev
==
δ
.
R
ev
&&
exact
)
{
t
.
Fatalf
(
"LastRevOf(%v, at=%s) -> %s, %v ; want %s, %v"
,
id
,
δ
.
rev
,
idRev
,
exact
,
δ
.
r
ev
,
true
)
t
.
Fatalf
(
"LastRevOf(%v, at=%s) -> %s, %v ; want %s, %v"
,
id
,
δ
.
Rev
,
idRev
,
exact
,
δ
.
R
ev
,
true
)
}
}
lastRevOf
[
id
]
=
δ
.
r
ev
lastRevOf
[
id
]
=
δ
.
R
ev
}
}
}
}
...
@@ -255,7 +255,7 @@ func TestΔTail(t *testing.T) {
...
@@ -255,7 +255,7 @@ func TestΔTail(t *testing.T) {
// access to whole underlying array from a slice.
// access to whole underlying array from a slice.
}
}
func
tailvEqual
(
a
,
b
[]
δ
RevEntry
)
bool
{
func
tailvEqual
(
a
,
b
[]
Δ
RevEntry
)
bool
{
// for empty one can be nil and another !nil [] = reflect.DeepEqual
// for empty one can be nil and another !nil [] = reflect.DeepEqual
// does not think those are equal.
// does not think those are equal.
return
(
len
(
a
)
==
0
&&
len
(
b
)
==
0
)
||
return
(
len
(
a
)
==
0
&&
len
(
b
)
==
0
)
||
...
...
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