Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
b
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
b
Commits
aac3d27e
Commit
aac3d27e
authored
Apr 11, 2017
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
1eca15f8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
128 deletions
+137
-128
all_test.go
all_test.go
+114
-2
btree.go
btree.go
+23
-126
No files found.
all_test.go
View file @
aac3d27e
...
@@ -27,7 +27,7 @@ var caller = func(s string, va ...interface{}) {
...
@@ -27,7 +27,7 @@ var caller = func(s string, va ...interface{}) {
}
}
func
dbg
(
s
string
,
va
...
interface
{})
{
func
dbg
(
s
string
,
va
...
interface
{})
{
//
return
return
if
s
==
""
{
if
s
==
""
{
s
=
strings
.
Repeat
(
"%v "
,
len
(
va
))
s
=
strings
.
Repeat
(
"%v "
,
len
(
va
))
}
}
...
@@ -45,7 +45,7 @@ func TODO(...interface{}) string { //TODOOK
...
@@ -45,7 +45,7 @@ func TODO(...interface{}) string { //TODOOK
func
use
(
...
interface
{})
{}
func
use
(
...
interface
{})
{}
func
init
()
{
func
init
()
{
use
(
caller
,
dbg
,
TODO
,
isNil
,
(
*
Tree
)
.
dump
)
//TODOOK
use
(
caller
,
dbg
,
TODO
,
isNil
,
(
*
Tree
)
.
dump
,
(
*
Tree
)
.
checkHit
)
//TODOOK
}
}
// ============================================================================
// ============================================================================
...
@@ -141,6 +141,116 @@ func (t *Tree) dump() string {
...
@@ -141,6 +141,116 @@ func (t *Tree) dump() string {
return
s
return
s
}
}
func
(
t
*
Tree
)
checkHit
(
k
interface
{}
/*K*/
)
{
badHappenned
:=
false
bad
:=
func
(
s
string
,
va
...
interface
{})
{
dbg
(
s
,
va
...
)
badHappenned
=
true
}
//println()
if
t
.
hitDi
>=
0
{
if
t
.
hitD
.
d
[
t
.
hitDi
]
.
k
!=
k
{
bad
(
"hitD invalid: %v @%v"
,
t
.
hitD
,
t
.
hitDi
)
}
}
if
t
.
hitPi
>=
0
{
if
t
.
hitP
.
x
[
t
.
hitPi
]
.
ch
!=
t
.
hitD
{
bad
(
"hitP invalid: %v @%v"
,
t
.
hitP
,
t
.
hitPi
)
}
}
// rescan from root and check Kmin/Kmax and rest
q
:=
t
.
r
var
p
*
x
pi
:=
-
1
var
dd
*
d
var
i
int
var
ok
bool
var
hitKmin
,
hitKmax
xkey
var
hitPKmax
xkey
//dbg("k: %v", k)
loop
:
for
{
//dbg("p: %p: @%d %v", p, pi, p)
//dbg("q: %p: %v", q, q)
i
,
ok
=
t
.
find
(
q
,
k
)
//dbg("\t-> %v, %v", i, ok)
switch
x
:=
q
.
(
type
)
{
case
*
x
:
hitPKmax
=
hitKmax
// XXX recheck
p
=
x
pi
=
i
if
ok
{
pi
++
}
//dbg("\tpi -> %v", pi)
q
=
p
.
x
[
pi
]
.
ch
if
pi
>
0
{
hitKminPrev
:=
hitKmin
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
if
hitKminPrev
.
kset
&&
t
.
cmp
(
hitKmin
.
k
,
hitKminPrev
.
k
)
<=
0
{
bad
(
"hitKmin not ↑: %v -> %v"
,
hitKminPrev
.
k
,
hitKmin
.
k
)
}
}
if
pi
<
p
.
c
{
//dbg("", p.x, pi)
hitKmax
.
set
(
p
.
x
[
pi
]
.
k
)
// XXX not sure or x[pi+1] ?
if
hitPKmax
.
kset
&&
t
.
cmp
(
hitKmax
.
k
,
hitPKmax
.
k
)
>=
0
{
bad
(
"hitKmax not ↓: %v -> %v"
,
hitPKmax
.
k
,
hitKmax
.
k
)
}
}
case
*
d
:
if
!
ok
{
bad
(
"key %v not found after set"
,
k
)
}
dd
=
x
break
loop
}
}
if
hitKmin
!=
t
.
hitKmin
{
bad
(
"hitKmin mismatch: %v ; want %v"
,
t
.
hitKmin
,
hitKmin
)
}
if
hitKmax
!=
t
.
hitKmax
{
bad
(
"hitKmax mismatch: %v ; want %v"
,
t
.
hitKmax
,
hitKmax
)
}
if
hitPKmax
!=
t
.
hitPKmax
{
bad
(
"hitPKmax mismatch: %v ; want %v"
,
t
.
hitPKmax
,
hitPKmax
)
}
if
dd
!=
t
.
hitD
||
i
!=
t
.
hitDi
{
bad
(
"hitD mismatch: %v @%d ; want %v @%d"
,
t
.
hitD
,
t
.
hitDi
,
dd
,
i
)
}
if
p
!=
t
.
hitP
||
pi
!=
t
.
hitPi
{
bad
(
"hitP mismatch: %v @%d ; want %v @%d"
,
t
.
hitP
,
t
.
hitPi
,
p
,
pi
)
}
//v2, ok := t.Get(k)
//if !ok || v2 != v {
// bad("get(%v) -> %v, %v; want %v, %v", k, v2, ok, v, true)
//}
if
badHappenned
{
panic
(
0
)
}
}
func
rng
()
*
mathutil
.
FC32
{
func
rng
()
*
mathutil
.
FC32
{
x
,
err
:=
mathutil
.
NewFC32
(
math
.
MinInt32
/
4
,
math
.
MaxInt32
/
4
,
false
)
x
,
err
:=
mathutil
.
NewFC32
(
math
.
MinInt32
/
4
,
math
.
MaxInt32
/
4
,
false
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -441,7 +551,9 @@ func benchmarkGetRnd(b *testing.B, n int) {
...
@@ -441,7 +551,9 @@ func benchmarkGetRnd(b *testing.B, n int) {
func
TestSetGet2
(
t
*
testing
.
T
)
{
func
TestSetGet2
(
t
*
testing
.
T
)
{
const
N
=
40000
const
N
=
40000
//const N = 400
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x333333
,
0xcccccc
,
0x314159
}
{
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x333333
,
0xcccccc
,
0x314159
}
{
//for _, x := range []int{0} {
rng
:=
rng
()
rng
:=
rng
()
r
:=
TreeNew
(
cmp
)
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
set
:=
r
.
Set
...
...
btree.go
View file @
aac3d27e
...
@@ -653,120 +653,13 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) {
...
@@ -653,120 +653,13 @@ func (t *Tree) SeekLast() (e *Enumerator, err error) {
return
btEPool
.
get
(
nil
,
true
,
q
.
c
-
1
,
q
.
d
[
q
.
c
-
1
]
.
k
,
q
,
t
,
t
.
ver
),
nil
return
btEPool
.
get
(
nil
,
true
,
q
.
c
-
1
,
q
.
d
[
q
.
c
-
1
]
.
k
,
q
,
t
,
t
.
ver
),
nil
}
}
// verify that t.hit* are computed ok
// XXX -> all_test
// Set sets the value associated with k.
// Set sets the value associated with k.
func
(
t
*
Tree
)
Set
(
k
interface
{}
/*K*/
,
v
interface
{}
/*V*/
)
{
func
(
t
*
Tree
)
Set
(
k
interface
{}
/*K*/
,
v
interface
{}
/*V*/
)
{
//dbg("--- PRE Set(%v, %v)\t(%v @%d, [%v, %v) PKmax: %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmax, t.dump())
//dbg("--- PRE Set(%v, %v)\t(%v @%d, [%v, %v) PKmax: %v)\n%s", k, v, t.hitD, t.hitDi, t.hitKmin, t.hitKmax, t.hitPKmax, t.dump())
defer
func
()
{
defer
t
.
checkHit
(
k
)
badHappenned
:=
false
bad
:=
func
(
s
string
,
va
...
interface
{})
{
dbg
(
s
,
va
...
)
badHappenned
=
true
}
//println()
if
t
.
hitDi
>=
0
{
if
t
.
hitD
.
d
[
t
.
hitDi
]
.
k
!=
k
{
bad
(
"hitD invalid: %v @%v"
,
t
.
hitD
,
t
.
hitDi
)
}
}
if
t
.
hitPi
>=
0
{
if
t
.
hitP
.
x
[
t
.
hitPi
]
.
ch
!=
t
.
hitD
{
bad
(
"hitP invalid: %v @%v"
,
t
.
hitP
,
t
.
hitPi
)
}
}
// rescan from root and check Kmin/Kmax and rest
q
:=
t
.
r
var
p
*
x
pi
:=
-
1
var
dd
*
d
var
i
int
var
ok
bool
var
hitKmin
,
hitKmax
xkey
var
hitPKmax
xkey
//dbg("k: %v", k)
loop
:
for
{
//dbg("p: %p: @%d %v", p, pi, p)
//dbg("q: %p: %v", q, q)
i
,
ok
=
t
.
find
(
q
,
k
)
//dbg("\t-> %v, %v", i, ok)
switch
x
:=
q
.
(
type
)
{
case
*
x
:
hitPKmax
=
hitKmax
// XXX recheck
p
=
x
pi
=
i
if
ok
{
pi
++
}
//dbg("\tpi -> %v", pi)
q
=
p
.
x
[
pi
]
.
ch
if
pi
>
0
{
hitKminPrev
:=
hitKmin
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
if
hitKminPrev
.
kset
&&
t
.
cmp
(
hitKmin
.
k
,
hitKminPrev
.
k
)
<=
0
{
bad
(
"hitKmin not ↑: %v -> %v"
,
hitKminPrev
.
k
,
hitKmin
.
k
)
}
}
if
pi
<
p
.
c
{
//dbg("", p.x, pi)
hitKmax
.
set
(
p
.
x
[
pi
]
.
k
)
// XXX not sure or x[pi+1] ?
if
hitPKmax
.
kset
&&
t
.
cmp
(
hitKmax
.
k
,
hitPKmax
.
k
)
>=
0
{
bad
(
"hitKmax not ↓: %v -> %v"
,
hitPKmax
.
k
,
hitKmax
.
k
)
}
}
case
*
d
:
if
!
ok
{
bad
(
"key %v not found after set"
,
k
)
}
dd
=
x
break
loop
}
}
if
hitKmin
!=
t
.
hitKmin
{
bad
(
"hitKmin mismatch: %v ; want %v"
,
t
.
hitKmin
,
hitKmin
)
}
if
hitKmax
!=
t
.
hitKmax
{
bad
(
"hitKmax mismatch: %v ; want %v"
,
t
.
hitKmax
,
hitKmax
)
}
if
hitPKmax
!=
t
.
hitPKmax
{
bad
(
"hitPKmax mismatch: %v ; want %v"
,
t
.
hitPKmax
,
hitPKmax
)
}
if
dd
!=
t
.
hitD
||
i
!=
t
.
hitDi
{
bad
(
"hitD mismatch: %v @%d ; want %v @%d"
,
t
.
hitD
,
t
.
hitDi
,
dd
,
i
)
}
if
p
!=
t
.
hitP
||
pi
!=
t
.
hitPi
{
bad
(
"hitP mismatch: %v @%d ; want %v @%d"
,
t
.
hitP
,
t
.
hitPi
,
p
,
pi
)
}
v2
,
ok
:=
t
.
Get
(
k
)
if
!
ok
||
v2
!=
v
{
bad
(
"get(%v) -> %v, %v; want %v, %v"
,
k
,
v2
,
ok
,
v
,
true
)
}
if
badHappenned
{
panic
(
0
)
}
}()
//defer func() {
//defer func() {
// dbg("--- POST\n%s\n====\n", t.dump())
// dbg("--- POST\n%s\n====\n", t.dump())
//}()
//}()
...
@@ -780,13 +673,13 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -780,13 +673,13 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
switch
{
switch
{
case
ok
:
case
ok
:
//
dbg("ok'")
dbg
(
"ok'"
)
dd
.
d
[
i
]
.
v
=
v
dd
.
d
[
i
]
.
v
=
v
t
.
hitDi
=
i
t
.
hitDi
=
i
return
return
case
dd
.
c
<
2
*
kd
:
case
dd
.
c
<
2
*
kd
:
//
dbg("insert'")
dbg
(
"insert'"
)
t
.
insert
(
dd
,
i
,
k
,
v
)
t
.
insert
(
dd
,
i
,
k
,
v
)
return
return
...
@@ -797,7 +690,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -797,7 +690,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
//break
//break
p
,
pi
:=
t
.
hitP
,
t
.
hitPi
p
,
pi
:=
t
.
hitP
,
t
.
hitPi
if
p
==
nil
||
p
.
c
<=
2
*
kx
{
// XXX < vs <=
if
p
==
nil
||
p
.
c
<=
2
*
kx
{
// XXX < vs <=
//
dbg("overflow'")
dbg
(
"overflow'"
)
t
.
overflow
(
p
,
dd
,
pi
,
i
,
k
,
v
)
t
.
overflow
(
p
,
dd
,
pi
,
i
,
k
,
v
)
return
return
}
}
...
@@ -809,7 +702,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -809,7 +702,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
var
p
*
x
var
p
*
x
q
:=
t
.
r
q
:=
t
.
r
if
q
==
nil
{
if
q
==
nil
{
//
dbg("empty")
dbg
(
"empty"
)
z
:=
t
.
insert
(
btDPool
.
Get
()
.
(
*
d
),
0
,
k
,
v
)
// XXX update hit
z
:=
t
.
insert
(
btDPool
.
Get
()
.
(
*
d
),
0
,
k
,
v
)
// XXX update hit
t
.
r
,
t
.
first
,
t
.
last
=
z
,
z
,
z
t
.
r
,
t
.
first
,
t
.
last
=
z
,
z
,
z
return
return
...
@@ -826,21 +719,25 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -826,21 +719,25 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if
x
.
c
>
2
*
kx
{
if
x
.
c
>
2
*
kx
{
//x, i = t.splitX(p, x, pi, i)
//x, i = t.splitX(p, x, pi, i)
//
dbg("splitX")
dbg
(
"splitX"
)
x
,
i
,
p
,
pi
=
t
.
splitX
(
p
,
x
,
pi
,
i
)
x
,
i
,
p
,
pi
=
t
.
splitX
(
p
,
x
,
pi
,
i
)
// NOTE splitX changes p
// NOTE splitX changes p which means hit
// Kmin/Kmax/PKmax have to be recomputed
if
pi
>=
0
&&
pi
<
p
.
c
{
if
pi
>=
0
&&
pi
<
p
.
c
{
hitPKmax
.
set
(
p
.
x
[
pi
]
.
k
)
hitPKmax
.
set
(
p
.
x
[
pi
]
.
k
)
// XXX wrong vs oo and not oo above
//dbg("hitPKmax X: %v", hitPKmax)
dbg
(
"hitPKmax X: %v"
,
hitPKmax
)
hitKmax
=
hitPKmax
dbg
(
"hitKmax X: %v"
,
hitKmax
)
}
}
if
pi
>
0
{
if
pi
>
0
{
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
// XXX also recheck vs above
//
dbg("hitKmin X: %v", hitKmin)
dbg
(
"hitKmin X: %v"
,
hitKmin
)
}
}
}
else
{
}
else
{
// p unchanged
// p unchanged
// FIXME move to above without else
hitPKmax
=
hitKmax
hitPKmax
=
hitKmax
}
}
...
@@ -854,12 +751,12 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -854,12 +751,12 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if
pi
>
0
{
// XXX also check < p.c ?
if
pi
>
0
{
// XXX also check < p.c ?
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
hitKmin
.
set
(
p
.
x
[
pi
-
1
]
.
k
)
//
dbg("hitKmin: %v", hitKmin)
dbg
(
"hitKmin: %v"
,
hitKmin
)
}
}
if
pi
<
p
.
c
{
if
pi
<
p
.
c
{
hitKmax
.
set
(
p
.
x
[
pi
]
.
k
)
hitKmax
.
set
(
p
.
x
[
pi
]
.
k
)
//
dbg("hitKmax: %v", hitKmax)
dbg
(
"hitKmax: %v"
,
hitKmax
)
}
}
...
@@ -873,16 +770,16 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
...
@@ -873,16 +770,16 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
switch
{
switch
{
case
ok
:
case
ok
:
//
dbg("ok")
dbg
(
"ok"
)
x
.
d
[
i
]
.
v
=
v
x
.
d
[
i
]
.
v
=
v
t
.
hitD
,
t
.
hitDi
=
x
,
i
t
.
hitD
,
t
.
hitDi
=
x
,
i
case
x
.
c
<
2
*
kd
:
case
x
.
c
<
2
*
kd
:
//
dbg("insert")
dbg
(
"insert"
)
t
.
insert
(
x
,
i
,
k
,
v
)
t
.
insert
(
x
,
i
,
k
,
v
)
default
:
default
:
//
dbg("overflow")
dbg
(
"overflow"
)
// NOTE overflow will correct hit Kmin, Kmax, P and Pi as needed
// NOTE overflow will correct hit Kmin, Kmax, P and Pi as needed
t
.
overflow
(
p
,
x
,
pi
,
i
,
k
,
v
)
t
.
overflow
(
p
,
x
,
pi
,
i
,
k
,
v
)
}
}
...
...
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