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
5a1179fd
Commit
5a1179fd
authored
Jun 20, 2014
by
Jan Mercl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Overhaul benchmarks
parent
0496ce60
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1564 additions
and
357 deletions
+1564
-357
all_test.go
all_test.go
+296
-95
btree.go
btree.go
+13
-47
example/Makefile
example/Makefile
+24
-0
example/all_test.go
example/all_test.go
+1146
-0
example/bench_test.go
example/bench_test.go
+0
-188
example/int.go
example/int.go
+85
-27
No files found.
all_test.go
View file @
5a1179fd
...
...
@@ -140,11 +140,7 @@ func TestGet0(t *testing.T) {
t
.
Fatal
(
g
,
e
)
}
v
,
ok
:=
r
.
Get
(
42
)
if
v
!=
nil
{
t
.
Fatal
(
v
)
}
_
,
ok
:=
r
.
Get
(
42
)
if
ok
{
t
.
Fatal
(
ok
)
}
...
...
@@ -228,67 +224,152 @@ func TestSetGet1(t *testing.T) {
t
.
Fatal
(
i
,
k
,
v
,
ok
)
}
if
v
==
nil
{
t
.
Fatal
(
i
,
k
)
}
if
g
,
e
:=
v
.
(
int
),
k
^
x
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
k
|=
1
v
,
ok
=
r
.
Get
(
k
)
_
,
ok
=
r
.
Get
(
k
)
if
ok
{
t
.
Fatal
(
i
,
k
)
}
if
v
!=
nil
{
t
.
Fatal
(
i
,
k
)
}
}
}
}
func
BenchmarkSetSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
func
BenchmarkSetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e2
)
}
func
BenchmarkSetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e3
)
}
func
BenchmarkSetSeq1e4
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e4
)
}
func
BenchmarkSetSeq1e5
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e5
)
}
func
BenchmarkSetSeq1e6
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e6
)
}
func
benchmarkSetSeq
(
b
*
testing
.
B
,
n
int
)
{
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Set
(
j
,
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkGetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e2
)
}
func
BenchmarkGetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e3
)
}
func
BenchmarkGetSeq1e4
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e4
)
}
func
BenchmarkGetSeq1e5
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e5
)
}
func
BenchmarkGetSeq1e6
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e6
)
}
func
BenchmarkSetRnd
(
b
*
testing
.
B
)
{
func
benchmarkGetSeq
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
for
i
:=
0
;
i
<
n
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Get
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkGetSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
func
BenchmarkSetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e2
)
}
func
BenchmarkSetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e3
)
}
func
BenchmarkSetRnd1e4
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e4
)
}
func
BenchmarkSetRnd1e5
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e5
)
}
func
BenchmarkSetRnd1e6
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e6
)
}
func
benchmarkSetRnd
(
b
*
testing
.
B
,
n
int
)
{
rng
:=
rng
()
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Get
(
i
)
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
}
b
.
StopTimer
()
}
func
BenchmarkGetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e2
)
}
func
BenchmarkGetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e3
)
}
func
BenchmarkGetRnd1e4
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e4
)
}
func
BenchmarkGetRnd1e5
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e5
)
}
func
BenchmarkGetRnd
(
b
*
testing
.
B
)
{
func
BenchmarkGetRnd1e6
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e6
)
}
func
benchmarkGetRnd
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
...
...
@@ -297,9 +378,12 @@ func BenchmarkGetRnd(b *testing.B) {
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Get
(
v
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
_
,
v
:=
range
a
{
r
.
Get
(
v
)
}
}
b
.
StopTimer
()
}
func
TestSetGet2
(
t
*
testing
.
T
)
{
...
...
@@ -325,24 +409,15 @@ func TestSetGet2(t *testing.T) {
t
.
Fatal
(
i
,
k
,
v
,
ok
)
}
if
v
==
nil
{
t
.
Fatal
(
i
,
k
)
}
if
g
,
e
:=
v
.
(
int
),
k
^
x
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
k
|=
1
v
,
ok
=
r
.
Get
(
k
)
_
,
ok
=
r
.
Get
(
k
)
if
ok
{
t
.
Fatal
(
i
,
k
)
}
if
v
!=
nil
{
t
.
Fatal
(
i
,
k
)
}
}
}
}
...
...
@@ -367,10 +442,6 @@ func TestSetGet3(t *testing.T) {
t
.
Fatal
(
j
)
}
if
v
==
nil
{
t
.
Fatal
(
j
)
}
if
g
,
e
:=
v
.
(
int
),
j
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
...
...
@@ -487,33 +558,83 @@ func TestDelete1(t *testing.T) {
}
}
func
BenchmarkDelSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
func
benchmarkDelSeq1e2
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e2
)
}
func
benchmarkDelSeq1e3
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e3
)
}
func
benchmarkDelSeq1e4
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e4
)
}
func
benchmarkDelSeq1e5
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e5
)
}
func
benchmarkDelSeq1e6
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e6
)
}
func
benchmarkDelSeq
(
b
*
testing
.
B
,
n
int
)
{
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Delete
(
i
)
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
n
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Delete
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkDelRnd
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
func
BenchmarkDelRnd1e2
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e2
)
}
func
BenchmarkDelRnd1e3
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e3
)
}
func
BenchmarkDelRnd1e4
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e4
)
}
func
BenchmarkDelRnd1e5
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e5
)
}
func
BenchmarkDelRnd1e6
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e6
)
}
func
benchmarkDelRnd
(
b
*
testing
.
B
,
n
int
)
{
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Delete
(
v
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
_
,
v
:=
range
a
{
r
.
Delete
(
v
)
}
}
b
.
StopTimer
()
}
func
TestDelete2
(
t
*
testing
.
T
)
{
...
...
@@ -568,7 +689,6 @@ func TestEnumeratorNext(t *testing.T) {
r
.
Set
(
30
,
300
)
for
verChange
:=
0
;
verChange
<
16
;
verChange
++
{
//t.Logf("Seek %d", test.k)
en
,
hit
:=
r
.
Seek
(
test
.
k
)
if
g
,
e
:=
hit
,
test
.
hit
;
g
!=
e
{
...
...
@@ -578,7 +698,6 @@ func TestEnumeratorNext(t *testing.T) {
j
:=
0
for
{
if
verChange
&
(
1
<<
uint
(
j
))
!=
0
{
//t.Log("version change")
r
.
Set
(
20
,
200
)
}
...
...
@@ -591,7 +710,6 @@ func TestEnumeratorNext(t *testing.T) {
break
}
//t.Logf("Next -> %v: %v", k, v)
if
j
>=
len
(
up
)
{
t
.
Fatal
(
i
,
j
,
verChange
)
}
...
...
@@ -641,7 +759,6 @@ func TestEnumeratorPrev(t *testing.T) {
r
.
Set
(
30
,
300
)
for
verChange
:=
0
;
verChange
<
16
;
verChange
++
{
//t.Logf("Seek %d", test.k)
en
,
hit
:=
r
.
Seek
(
test
.
k
)
if
g
,
e
:=
hit
,
test
.
hit
;
g
!=
e
{
...
...
@@ -651,7 +768,6 @@ func TestEnumeratorPrev(t *testing.T) {
j
:=
0
for
{
if
verChange
&
(
1
<<
uint
(
j
))
!=
0
{
//t.Log("version change")
r
.
Set
(
20
,
200
)
}
...
...
@@ -664,7 +780,6 @@ func TestEnumeratorPrev(t *testing.T) {
break
}
//t.Logf("Prev -> %v: %v", k, v)
if
j
>=
len
(
dn
)
{
t
.
Fatal
(
i
,
j
,
verChange
)
}
...
...
@@ -689,22 +804,66 @@ func TestEnumeratorPrev(t *testing.T) {
}
}
func
BenchmarkSeekSeq
(
b
*
testing
.
B
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
func
BenchmarkSeekSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e2
)
}
func
BenchmarkSeekSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e3
)
}
func
BenchmarkSeekSeq1e4
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e4
)
}
func
BenchmarkSeekSeq1e5
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e5
)
}
func
BenchmarkSeekSeq1e6
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e6
)
}
func
benchmarkSeekSeq
(
b
*
testing
.
B
,
n
int
)
{
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
t
.
Seek
(
i
)
b
.
StopTimer
()
t
:=
TreeNew
(
cmp
)
for
j
:=
0
;
j
<
n
;
j
++
{
t
.
Set
(
j
,
0
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
t
.
Seek
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkSeekRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e2
)
}
func
BenchmarkSeekRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e3
)
}
func
BenchmarkSeekRnd1e4
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e4
)
}
func
BenchmarkSeekRnd
(
b
*
testing
.
B
)
{
func
BenchmarkSeekRnd1e5
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e5
)
}
func
BenchmarkSeekRnd1e6
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e6
)
}
func
benchmarkSeekRnd
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
...
...
@@ -713,15 +872,36 @@ func BenchmarkSeekRnd(b *testing.B) {
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Seek
(
v
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
_
,
v
:=
range
a
{
r
.
Seek
(
v
)
}
}
}
func
BenchmarkNext1e2
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e2
)
}
func
BenchmarkNext1e3
(
b
*
testing
.
B
)
{
const
N
=
1e3
benchmarkNext
(
b
,
1e3
)
}
func
BenchmarkNext1e4
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e4
)
}
func
BenchmarkNext1e5
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e5
)
}
func
BenchmarkNext1e6
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e6
)
}
func
benchmarkNext
(
b
*
testing
.
B
,
n
int
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
N
;
i
++
{
for
i
:=
0
;
i
<
n
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
...
...
@@ -731,23 +911,43 @@ func BenchmarkNext1e3(b *testing.B) {
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
n
:=
0
m
:=
0
for
{
if
_
,
_
,
err
=
en
.
Next
();
err
!=
nil
{
break
}
n
++
m
++
}
if
n
!=
N
{
b
.
Fatal
(
n
)
if
m
!=
n
{
b
.
Fatal
(
m
)
}
}
}
func
BenchmarkPrev1e2
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e2
)
}
func
BenchmarkPrev1e3
(
b
*
testing
.
B
)
{
const
N
=
1e3
benchmarkPrev
(
b
,
1e3
)
}
func
BenchmarkPrev1e4
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e4
)
}
func
BenchmarkPrev1e5
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e5
)
}
func
BenchmarkPrev1e6
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e6
)
}
func
benchmarkPrev
(
b
*
testing
.
B
,
n
int
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
N
;
i
++
{
for
i
:=
0
;
i
<
n
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
...
...
@@ -757,15 +957,16 @@ func BenchmarkPrev1e3(b *testing.B) {
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
n
:=
0
m
:=
0
for
{
if
_
,
_
,
err
=
en
.
Prev
();
err
!=
nil
{
break
}
n
++
m
++
}
if
n
!=
N
{
b
.
Fatal
(
n
)
if
m
!=
n
{
b
.
Fatal
(
m
)
}
}
}
...
...
btree.go
View file @
5a1179fd
...
...
@@ -35,56 +35,22 @@
// $ make generic | sed -e 's/key/int/g' -e 's/value/int/g' > example/int.go
//
// No other changes to int.go are (strictly) necessary, it compiles just fine.
// In a next step, benchmarks from all_test.go were copied into
// example/bench_test.go without any changes. A comparator is defined in
// bench_test.go like this:
//
// func cmp(a, b int) int {
// return a - b
// }
// Running the benchmarks for 1000 keys on a machine with Intel X5450 CPU @ 3
// GHz, Go release 1.3.
//
// Running the benchmarks on a machine with Intel X5450 CPU @ 3 GHz:
//
// Go release (1.1.2)
//
// $ go test -bench . example/bench_test.go example/int.go
// testing: warning: no tests to run
// PASS
// BenchmarkSetSeq 5000000 590 ns/op
// BenchmarkSetRnd 1000000 1530 ns/op
// BenchmarkGetSeq 10000000 373 ns/op
// BenchmarkGetRnd 2000000 1109 ns/op
// BenchmarkDelSeq 5000000 672 ns/op
// BenchmarkDelRnd 1000000 1275 ns/op
// BenchmarkSeekSeq 5000000 552 ns/op
// BenchmarkSeekRnd 1000000 1108 ns/op
// BenchmarkNext1e3 200000 13414 ns/op
// BenchmarkPrev1e3 200000 13215 ns/op
// ok command-line-arguments 51.372s
// $
//
// Go 1.2rc2
//
// $ go test -bench . example/bench_test.go example/int.go
// testing: warning: no tests to run
// $ go test -bench 1e3 example/all_test.go example/int.go
// PASS
// BenchmarkSetSeq 5000000 535 ns/op
// BenchmarkSetRnd 1000000 1428 ns/op
// BenchmarkGetSeq 10000000 376 ns/op
// BenchmarkGetRnd 2000000 1105 ns/op
// BenchmarkDelSeq 5000000 618 ns/op
// BenchmarkDelRnd 1000000 1213 ns/op
// BenchmarkSeekSeq 5000000 538 ns/op
// BenchmarkSeekRnd 1000000 1088 ns/op
// BenchmarkNext1e3 200000 13410 ns/op
// BenchmarkPrev1e3 200000 13528 ns/op
// ok command-line-arguments 48.823s
// $
//
// Note that the Next and Prev benchmarks enumerate 1000 items (KV pairs), so
// getting the next or previous iterated item is performed in about 13-14 ns.
// This is the nice O(1) property of B+trees usually not found in other tree
// types.
// BenchmarkSetSeq1e3 10000 263951 ns/op
// BenchmarkGetSeq1e3 10000 154410 ns/op
// BenchmarkSetRnd1e3 5000 392690 ns/op
// BenchmarkGetRnd1e3 10000 181776 ns/op
// BenchmarkDelRnd1e3 5000 323795 ns/op
// BenchmarkSeekSeq1e3 10000 235939 ns/op
// BenchmarkSeekRnd1e3 5000 299997 ns/op
// BenchmarkNext1e3 200000 14202 ns/op
// BenchmarkPrev1e3 200000 13842 ns/op
// ok command-line-arguments 30.620s
package
b
import
(
...
...
example/Makefile
0 → 100644
View file @
5a1179fd
.PHONY
:
all todo clean cover
all
:
editor
go build
go vet
make todo
editor
:
go
fmt
go
test
-i
go
test
todo
:
@
grep
-n
^[[:space:]]
*
_[[:space:]]
*
=[[
:space:]][[:alpha:]][[:alnum:]]
*
*
.go
||
true
@
grep
-n
TODO
*
.go
||
true
@
grep
-n
BUG
*
.go
||
true
@
grep
-n
println
*
.go
||
true
clean
:
@
go clean
rm
-f
*
~
cover
:
t
=
$(
shell
tempfile
)
;
go
test
-coverprofile
$$
t
&&
go tool cover
-html
$$
t
&&
unlink
$$
t
example/all_test.go
0 → 100644
View file @
5a1179fd
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
b
import
(
"io"
"math"
"runtime/debug"
"testing"
"github.com/cznic/fileutil"
"github.com/cznic/mathutil"
)
func
rng
()
*
mathutil
.
FC32
{
x
,
err
:=
mathutil
.
NewFC32
(
math
.
MinInt32
/
4
,
math
.
MaxInt32
/
4
,
false
)
if
err
!=
nil
{
panic
(
err
)
}
return
x
}
func
cmp
(
a
,
b
int
)
int
{
return
a
-
b
}
func
TestGet0
(
t
*
testing
.
T
)
{
r
:=
TreeNew
(
cmp
)
if
g
,
e
:=
r
.
Len
(),
0
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
_
,
ok
:=
r
.
Get
(
42
)
if
ok
{
t
.
Fatal
(
ok
)
}
}
func
TestSetGet0
(
t
*
testing
.
T
)
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
set
(
42
,
314
)
if
g
,
e
:=
r
.
Len
(),
1
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
v
,
ok
:=
r
.
Get
(
42
)
if
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
v
,
314
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
set
(
42
,
278
)
if
g
,
e
:=
r
.
Len
(),
1
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
v
,
ok
=
r
.
Get
(
42
)
if
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
v
,
278
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
set
(
420
,
50
)
if
g
,
e
:=
r
.
Len
(),
2
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
v
,
ok
=
r
.
Get
(
42
)
if
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
v
,
278
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
v
,
ok
=
r
.
Get
(
420
)
if
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
v
,
50
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
}
func
TestSetGet1
(
t
*
testing
.
T
)
{
const
N
=
90000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
for
i
:=
range
a
{
a
[
i
]
=
(
i
^
x
)
<<
1
}
for
i
,
k
:=
range
a
{
set
(
k
,
k
^
x
)
if
g
,
e
:=
r
.
Len
(),
i
+
1
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
}
for
i
,
k
:=
range
a
{
v
,
ok
:=
r
.
Get
(
k
)
if
!
ok
{
t
.
Fatal
(
i
,
k
,
v
,
ok
)
}
if
g
,
e
:=
v
,
k
^
x
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
k
|=
1
_
,
ok
=
r
.
Get
(
k
)
if
ok
{
t
.
Fatal
(
i
,
k
)
}
}
}
}
func
BenchmarkSetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e2
)
}
func
BenchmarkSetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e3
)
}
func
BenchmarkSetSeq1e4
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e4
)
}
func
BenchmarkSetSeq1e5
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e5
)
}
func
BenchmarkSetSeq1e6
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e6
)
}
func
benchmarkSetSeq
(
b
*
testing
.
B
,
n
int
)
{
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Set
(
j
,
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkGetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e2
)
}
func
BenchmarkGetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e3
)
}
func
BenchmarkGetSeq1e4
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e4
)
}
func
BenchmarkGetSeq1e5
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e5
)
}
func
BenchmarkGetSeq1e6
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e6
)
}
func
benchmarkGetSeq
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
n
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Get
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkSetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e2
)
}
func
BenchmarkSetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e3
)
}
func
BenchmarkSetRnd1e4
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e4
)
}
func
BenchmarkSetRnd1e5
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e5
)
}
func
BenchmarkSetRnd1e6
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e6
)
}
func
benchmarkSetRnd
(
b
*
testing
.
B
,
n
int
)
{
rng
:=
rng
()
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
}
b
.
StopTimer
()
}
func
BenchmarkGetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e2
)
}
func
BenchmarkGetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e3
)
}
func
BenchmarkGetRnd1e4
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e4
)
}
func
BenchmarkGetRnd1e5
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e5
)
}
func
BenchmarkGetRnd1e6
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e6
)
}
func
benchmarkGetRnd
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
_
,
v
:=
range
a
{
r
.
Get
(
v
)
}
}
b
.
StopTimer
()
}
func
TestSetGet2
(
t
*
testing
.
T
)
{
const
N
=
70000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
rng
:=
rng
()
for
i
:=
range
a
{
a
[
i
]
=
(
rng
.
Next
()
^
x
)
<<
1
}
for
i
,
k
:=
range
a
{
set
(
k
,
k
^
x
)
if
g
,
e
:=
r
.
Len
(),
i
+
1
;
g
!=
e
{
t
.
Fatal
(
i
,
x
,
g
,
e
)
}
}
for
i
,
k
:=
range
a
{
v
,
ok
:=
r
.
Get
(
k
)
if
!
ok
{
t
.
Fatal
(
i
,
k
,
v
,
ok
)
}
if
g
,
e
:=
v
,
k
^
x
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
k
|=
1
_
,
ok
=
r
.
Get
(
k
)
if
ok
{
t
.
Fatal
(
i
,
k
)
}
}
}
}
func
TestSetGet3
(
t
*
testing
.
T
)
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
var
i
int
for
i
=
0
;
;
i
++
{
set
(
i
,
-
i
)
if
_
,
ok
:=
r
.
r
.
(
*
x
);
ok
{
break
}
}
for
j
:=
0
;
j
<=
i
;
j
++
{
set
(
j
,
j
)
}
for
j
:=
0
;
j
<=
i
;
j
++
{
v
,
ok
:=
r
.
Get
(
j
)
if
!
ok
{
t
.
Fatal
(
j
)
}
if
g
,
e
:=
v
,
j
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
}
}
func
TestDelete0
(
t
*
testing
.
T
)
{
r
:=
TreeNew
(
cmp
)
if
ok
:=
r
.
Delete
(
0
);
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
0
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
r
.
Set
(
0
,
0
)
if
ok
:=
r
.
Delete
(
1
);
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
1
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
0
);
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
0
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
0
);
ok
{
t
.
Fatal
(
ok
)
}
r
.
Set
(
0
,
0
)
r
.
Set
(
1
,
1
)
if
ok
:=
r
.
Delete
(
1
);
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
1
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
1
);
ok
{
t
.
Fatal
(
ok
)
}
if
ok
:=
r
.
Delete
(
0
);
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
0
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
0
);
ok
{
t
.
Fatal
(
ok
)
}
r
.
Set
(
0
,
0
)
r
.
Set
(
1
,
1
)
if
ok
:=
r
.
Delete
(
0
);
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
1
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
0
);
ok
{
t
.
Fatal
(
ok
)
}
if
ok
:=
r
.
Delete
(
1
);
!
ok
{
t
.
Fatal
(
ok
)
}
if
g
,
e
:=
r
.
Len
(),
0
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
if
ok
:=
r
.
Delete
(
1
);
ok
{
t
.
Fatal
(
ok
)
}
}
func
TestDelete1
(
t
*
testing
.
T
)
{
const
N
=
100000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
for
i
:=
range
a
{
a
[
i
]
=
(
i
^
x
)
<<
1
}
for
_
,
k
:=
range
a
{
set
(
k
,
0
)
}
for
i
,
k
:=
range
a
{
ok
:=
r
.
Delete
(
k
)
if
!
ok
{
t
.
Fatal
(
i
,
x
,
k
)
}
if
g
,
e
:=
r
.
Len
(),
N
-
i
-
1
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
}
}
}
func
benchmarkDelSeq1e2
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e2
)
}
func
benchmarkDelSeq1e3
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e3
)
}
func
benchmarkDelSeq1e4
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e4
)
}
func
benchmarkDelSeq1e5
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e5
)
}
func
benchmarkDelSeq1e6
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e6
)
}
func
benchmarkDelSeq
(
b
*
testing
.
B
,
n
int
)
{
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
n
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
r
.
Delete
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkDelRnd1e2
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e2
)
}
func
BenchmarkDelRnd1e3
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e3
)
}
func
BenchmarkDelRnd1e4
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e4
)
}
func
BenchmarkDelRnd1e5
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e5
)
}
func
BenchmarkDelRnd1e6
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e6
)
}
func
benchmarkDelRnd
(
b
*
testing
.
B
,
n
int
)
{
rng
:=
rng
()
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
r
:=
TreeNew
(
cmp
)
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
_
,
v
:=
range
a
{
r
.
Delete
(
v
)
}
}
b
.
StopTimer
()
}
func
TestDelete2
(
t
*
testing
.
T
)
{
const
N
=
80000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
rng
:=
rng
()
for
i
:=
range
a
{
a
[
i
]
=
(
rng
.
Next
()
^
x
)
<<
1
}
for
_
,
k
:=
range
a
{
set
(
k
,
0
)
}
for
i
,
k
:=
range
a
{
ok
:=
r
.
Delete
(
k
)
if
!
ok
{
t
.
Fatal
(
i
,
x
,
k
)
}
if
g
,
e
:=
r
.
Len
(),
N
-
i
-
1
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
}
}
}
func
TestEnumeratorNext
(
t
*
testing
.
T
)
{
// seeking within 3 keys: 10, 20, 30
table
:=
[]
struct
{
k
int
hit
bool
keys
[]
int
}{
{
5
,
false
,
[]
int
{
10
,
20
,
30
}},
{
10
,
true
,
[]
int
{
10
,
20
,
30
}},
{
15
,
false
,
[]
int
{
20
,
30
}},
{
20
,
true
,
[]
int
{
20
,
30
}},
{
25
,
false
,
[]
int
{
30
}},
{
30
,
true
,
[]
int
{
30
}},
{
35
,
false
,
[]
int
{}},
}
for
i
,
test
:=
range
table
{
up
:=
test
.
keys
r
:=
TreeNew
(
cmp
)
r
.
Set
(
10
,
100
)
r
.
Set
(
20
,
200
)
r
.
Set
(
30
,
300
)
for
verChange
:=
0
;
verChange
<
16
;
verChange
++
{
en
,
hit
:=
r
.
Seek
(
test
.
k
)
if
g
,
e
:=
hit
,
test
.
hit
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
j
:=
0
for
{
if
verChange
&
(
1
<<
uint
(
j
))
!=
0
{
r
.
Set
(
20
,
200
)
}
k
,
v
,
err
:=
en
.
Next
()
if
err
!=
nil
{
if
!
fileutil
.
IsEOF
(
err
)
{
t
.
Fatal
(
i
,
err
)
}
break
}
if
j
>=
len
(
up
)
{
t
.
Fatal
(
i
,
j
,
verChange
)
}
if
g
,
e
:=
k
,
up
[
j
];
g
!=
e
{
t
.
Fatal
(
i
,
j
,
verChange
,
g
,
e
)
}
if
g
,
e
:=
v
,
10
*
up
[
j
];
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
j
++
}
if
g
,
e
:=
j
,
len
(
up
);
g
!=
e
{
t
.
Fatal
(
i
,
j
,
g
,
e
)
}
}
}
}
func
TestEnumeratorPrev
(
t
*
testing
.
T
)
{
// seeking within 3 keys: 10, 20, 30
table
:=
[]
struct
{
k
int
hit
bool
keys
[]
int
}{
{
5
,
false
,
[]
int
{
10
}},
{
10
,
true
,
[]
int
{
10
}},
{
15
,
false
,
[]
int
{
20
,
10
}},
{
20
,
true
,
[]
int
{
20
,
10
}},
{
25
,
false
,
[]
int
{
30
,
20
,
10
}},
{
30
,
true
,
[]
int
{
30
,
20
,
10
}},
{
35
,
false
,
[]
int
{}},
}
for
i
,
test
:=
range
table
{
dn
:=
test
.
keys
r
:=
TreeNew
(
cmp
)
r
.
Set
(
10
,
100
)
r
.
Set
(
20
,
200
)
r
.
Set
(
30
,
300
)
for
verChange
:=
0
;
verChange
<
16
;
verChange
++
{
en
,
hit
:=
r
.
Seek
(
test
.
k
)
if
g
,
e
:=
hit
,
test
.
hit
;
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
j
:=
0
for
{
if
verChange
&
(
1
<<
uint
(
j
))
!=
0
{
r
.
Set
(
20
,
200
)
}
k
,
v
,
err
:=
en
.
Prev
()
if
err
!=
nil
{
if
!
fileutil
.
IsEOF
(
err
)
{
t
.
Fatal
(
i
,
err
)
}
break
}
if
j
>=
len
(
dn
)
{
t
.
Fatal
(
i
,
j
,
verChange
)
}
if
g
,
e
:=
k
,
dn
[
j
];
g
!=
e
{
t
.
Fatal
(
i
,
j
,
verChange
,
g
,
e
)
}
if
g
,
e
:=
v
,
10
*
dn
[
j
];
g
!=
e
{
t
.
Fatal
(
i
,
g
,
e
)
}
j
++
}
if
g
,
e
:=
j
,
len
(
dn
);
g
!=
e
{
t
.
Fatal
(
i
,
j
,
g
,
e
)
}
}
}
}
func
BenchmarkSeekSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e2
)
}
func
BenchmarkSeekSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e3
)
}
func
BenchmarkSeekSeq1e4
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e4
)
}
func
BenchmarkSeekSeq1e5
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e5
)
}
func
BenchmarkSeekSeq1e6
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e6
)
}
func
benchmarkSeekSeq
(
b
*
testing
.
B
,
n
int
)
{
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
b
.
StopTimer
()
t
:=
TreeNew
(
cmp
)
for
j
:=
0
;
j
<
n
;
j
++
{
t
.
Set
(
j
,
0
)
}
debug
.
FreeOSMemory
()
b
.
StartTimer
()
for
j
:=
0
;
j
<
n
;
j
++
{
t
.
Seek
(
j
)
}
}
b
.
StopTimer
()
}
func
BenchmarkSeekRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e2
)
}
func
BenchmarkSeekRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e3
)
}
func
BenchmarkSeekRnd1e4
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e4
)
}
func
BenchmarkSeekRnd1e5
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e5
)
}
func
BenchmarkSeekRnd1e6
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e6
)
}
func
benchmarkSeekRnd
(
b
*
testing
.
B
,
n
int
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
n
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
for
_
,
v
:=
range
a
{
r
.
Seek
(
v
)
}
}
}
func
BenchmarkNext1e2
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e2
)
}
func
BenchmarkNext1e3
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e3
)
}
func
BenchmarkNext1e4
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e4
)
}
func
BenchmarkNext1e5
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e5
)
}
func
BenchmarkNext1e6
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e6
)
}
func
benchmarkNext
(
b
*
testing
.
B
,
n
int
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
n
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
en
,
err
:=
t
.
SeekFirst
()
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
m
:=
0
for
{
if
_
,
_
,
err
=
en
.
Next
();
err
!=
nil
{
break
}
m
++
}
if
m
!=
n
{
b
.
Fatal
(
m
)
}
}
}
func
BenchmarkPrev1e2
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e2
)
}
func
BenchmarkPrev1e3
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e3
)
}
func
BenchmarkPrev1e4
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e4
)
}
func
BenchmarkPrev1e5
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e5
)
}
func
BenchmarkPrev1e6
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e6
)
}
func
benchmarkPrev
(
b
*
testing
.
B
,
n
int
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
n
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
en
,
err
:=
t
.
SeekLast
()
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
m
:=
0
for
{
if
_
,
_
,
err
=
en
.
Prev
();
err
!=
nil
{
break
}
m
++
}
if
m
!=
n
{
b
.
Fatal
(
m
)
}
}
}
func
TestSeekFirst0
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
_
,
err
:=
b
.
SeekFirst
()
if
g
,
e
:=
err
,
io
.
EOF
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
}
func
TestSeekFirst1
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
1
,
10
)
en
,
err
:=
b
.
SeekFirst
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Next
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestSeekFirst2
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
1
,
10
)
b
.
Set
(
2
,
20
)
en
,
err
:=
b
.
SeekFirst
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Next
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
k
!=
2
||
v
!=
20
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestSeekFirst3
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
2
,
20
)
b
.
Set
(
3
,
30
)
b
.
Set
(
1
,
10
)
en
,
err
:=
b
.
SeekFirst
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Next
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
k
!=
2
||
v
!=
20
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
k
!=
3
||
v
!=
30
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Next
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestSeekLast0
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
_
,
err
:=
b
.
SeekLast
()
if
g
,
e
:=
err
,
io
.
EOF
;
g
!=
e
{
t
.
Fatal
(
g
,
e
)
}
}
func
TestSeekLast1
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
1
,
10
)
en
,
err
:=
b
.
SeekLast
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Prev
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestSeekLast2
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
1
,
10
)
b
.
Set
(
2
,
20
)
en
,
err
:=
b
.
SeekLast
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Prev
()
if
k
!=
2
||
v
!=
20
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestSeekLast3
(
t
*
testing
.
T
)
{
b
:=
TreeNew
(
cmp
)
b
.
Set
(
2
,
20
)
b
.
Set
(
3
,
30
)
b
.
Set
(
1
,
10
)
en
,
err
:=
b
.
SeekLast
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
k
,
v
,
err
:=
en
.
Prev
()
if
k
!=
3
||
v
!=
30
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
k
!=
2
||
v
!=
20
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
k
!=
1
||
v
!=
10
||
err
!=
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
k
,
v
,
err
=
en
.
Prev
()
if
err
==
nil
{
t
.
Fatal
(
k
,
v
,
err
)
}
}
func
TestPut
(
t
*
testing
.
T
)
{
tab
:=
[]
struct
{
pre
[]
int
// even index: K, odd index: V
newK
int
// Put(newK, ...
oldV
int
// Put()->oldV
exists
bool
// upd(exists)
write
bool
// upd()->write
post
[]
int
// even index: K, odd index: V
}{
// 0
{
[]
int
{},
1
,
0
,
false
,
false
,
[]
int
{},
},
{
[]
int
{},
1
,
0
,
false
,
true
,
[]
int
{
1
,
-
1
},
},
{
[]
int
{
1
,
10
},
0
,
0
,
false
,
false
,
[]
int
{
1
,
10
},
},
{
[]
int
{
1
,
10
},
0
,
0
,
false
,
true
,
[]
int
{
0
,
-
1
,
1
,
10
},
},
{
[]
int
{
1
,
10
},
1
,
10
,
true
,
false
,
[]
int
{
1
,
10
},
},
// 5
{
[]
int
{
1
,
10
},
1
,
10
,
true
,
true
,
[]
int
{
1
,
-
1
},
},
{
[]
int
{
1
,
10
},
2
,
0
,
false
,
false
,
[]
int
{
1
,
10
},
},
{
[]
int
{
1
,
10
},
2
,
0
,
false
,
true
,
[]
int
{
1
,
10
,
2
,
-
1
},
},
}
for
iTest
,
test
:=
range
tab
{
tr
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
len
(
test
.
pre
);
i
+=
2
{
k
,
v
:=
test
.
pre
[
i
],
test
.
pre
[
i
+
1
]
tr
.
Set
(
k
,
v
)
}
oldV
,
written
:=
tr
.
Put
(
test
.
newK
,
func
(
old
int
,
exists
bool
)
(
newV
int
,
write
bool
)
{
if
g
,
e
:=
exists
,
test
.
exists
;
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
if
exists
{
if
g
,
e
:=
old
,
test
.
oldV
;
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
}
return
-
1
,
test
.
write
})
if
test
.
exists
{
if
g
,
e
:=
oldV
,
test
.
oldV
;
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
}
if
g
,
e
:=
written
,
test
.
write
;
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
n
:=
len
(
test
.
post
)
en
,
err
:=
tr
.
SeekFirst
()
if
err
!=
nil
{
if
n
==
0
&&
err
==
io
.
EOF
{
continue
}
t
.
Fatal
(
iTest
,
err
)
}
for
i
:=
0
;
i
<
len
(
test
.
post
);
i
+=
2
{
k
,
v
,
err
:=
en
.
Next
()
if
err
!=
nil
{
t
.
Fatal
(
iTest
,
err
)
}
if
g
,
e
:=
k
,
test
.
post
[
i
];
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
if
g
,
e
:=
v
,
test
.
post
[
i
+
1
];
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
}
_
,
_
,
err
=
en
.
Next
()
if
g
,
e
:=
err
,
io
.
EOF
;
g
!=
e
{
t
.
Fatal
(
iTest
,
g
,
e
)
}
}
}
example/bench_test.go
deleted
100644 → 0
View file @
0496ce60
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
b
import
(
"math"
"runtime/debug"
"testing"
"github.com/cznic/mathutil"
)
func
cmp
(
a
,
b
int
)
int
{
return
a
-
b
}
func
rng
()
*
mathutil
.
FC32
{
x
,
err
:=
mathutil
.
NewFC32
(
math
.
MinInt32
,
math
.
MaxInt32
,
false
)
if
err
!=
nil
{
panic
(
err
)
}
return
x
}
func
BenchmarkSetSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
}
}
func
BenchmarkSetRnd
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
}
func
BenchmarkGetSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Get
(
i
)
}
}
func
BenchmarkGetRnd
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Get
(
v
)
}
}
func
BenchmarkDelSeq
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Set
(
i
,
i
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
r
.
Delete
(
i
)
}
}
func
BenchmarkDelRnd
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Delete
(
v
)
}
}
func
BenchmarkSeekSeq
(
b
*
testing
.
B
)
{
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
t
.
Seek
(
i
)
}
}
func
BenchmarkSeekRnd
(
b
*
testing
.
B
)
{
r
:=
TreeNew
(
cmp
)
rng
:=
rng
()
a
:=
make
([]
int
,
b
.
N
)
for
i
:=
range
a
{
a
[
i
]
=
rng
.
Next
()
}
for
_
,
v
:=
range
a
{
r
.
Set
(
v
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
_
,
v
:=
range
a
{
r
.
Seek
(
v
)
}
}
func
BenchmarkNext1e3
(
b
*
testing
.
B
)
{
const
N
=
1e3
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
N
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
en
,
err
:=
t
.
SeekFirst
()
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
n
:=
0
for
{
if
_
,
_
,
err
=
en
.
Next
();
err
!=
nil
{
break
}
n
++
}
if
n
!=
N
{
b
.
Fatal
(
n
)
}
}
}
func
BenchmarkPrev1e3
(
b
*
testing
.
B
)
{
const
N
=
1e3
t
:=
TreeNew
(
cmp
)
for
i
:=
0
;
i
<
N
;
i
++
{
t
.
Set
(
i
,
0
)
}
debug
.
FreeOSMemory
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
en
,
err
:=
t
.
SeekLast
()
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
n
:=
0
for
{
if
_
,
_
,
err
=
en
.
Prev
();
err
!=
nil
{
break
}
n
++
}
if
n
!=
N
{
b
.
Fatal
(
n
)
}
}
}
example/int.go
View file @
5a1179fd
...
...
@@ -2,27 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package b implements a B+tree.
//
// Keys and their associated values are interface{} typed, similarly to all of
// the containers in the standard library.
//
// Semiautomatic production of a type specific variant of this package is
// supported via
//
// $ make generic
//
// Performing it will write to stdout a version of the btree.go file where
// every key type occurrence is replaced by the word 'key' (written in all
// CAPS) and every value type occurrence is replaced by the word 'value'
// (written in all CAPS). Then you have to replace theses strings with your
// desired type(s), using any technique you're comfortable with.
//
// This is how, for example, 'example/int.go' was created:
//
// $ mkdir example
// $ make generic | sed -e 's/key/int/g' -e 's/value/int/g' > example/int.go
//
// Package b implements an int->int B+tree.
package
b
import
(
...
...
@@ -233,8 +213,8 @@ func (t *Tree) catX(p, q, r *x, pi int) {
t
.
r
=
q
//TODO recycle r
}
//Delete removes the k's KV pair, if it exists, in which case Delete returns
//true.
//
Delete removes the k's KV pair, if it exists, in which case Delete returns
//
true.
func
(
t
*
Tree
)
Delete
(
k
int
)
(
ok
bool
)
{
pi
:=
-
1
var
p
*
x
...
...
@@ -341,7 +321,7 @@ func (t *Tree) find(q interface{}, k int) (i int, ok bool) {
}
// First returns the first item of the tree in the key collating order, or
// (
nil, nil
) if the tree is empty.
// (
zero-value, zero-value
) if the tree is empty.
func
(
t
*
Tree
)
First
()
(
k
int
,
v
int
)
{
if
q
:=
t
.
first
;
q
!=
nil
{
q
:=
&
q
.
d
[
0
]
...
...
@@ -351,7 +331,7 @@ func (t *Tree) First() (k int, v int) {
}
// Get returns the value associated with k and true if it exists. Otherwise Get
// returns (
nil
, false).
// returns (
zero-value
, false).
func
(
t
*
Tree
)
Get
(
k
int
)
(
v
int
,
ok
bool
)
{
q
:=
t
.
r
if
q
==
nil
{
...
...
@@ -390,8 +370,8 @@ func (t *Tree) insert(q *d, i int, k int, v int) *d {
return
q
}
// Last returns the last item of the tree in the key collating order, or
(nil,
//
nil
) if the tree is empty.
// Last returns the last item of the tree in the key collating order, or
//
(zero-value, zero-value
) if the tree is empty.
func
(
t
*
Tree
)
Last
()
(
k
int
,
v
int
)
{
if
q
:=
t
.
last
;
q
!=
nil
{
q
:=
&
q
.
d
[
q
.
c
-
1
]
...
...
@@ -525,6 +505,84 @@ func (t *Tree) Set(k int, v int) {
return
}
// Put combines Get and Set in a more efficient way where the tree is walked
// only once. The upd(ater) receives (old-value, true) if a KV pair for k
// exists or (zero-value, false) otherwise. It can then return a (new-value,
// true) to create or overwrite the existing value in the KV pair, or
// (whatever, false) if it decides not to create or not to update the value of
// the KV pair.
//
// tree.Set(k, v) conceptually equals
//
// tree.Put(k, func(k, v []byte){ return v, true }([]byte, bool))
//
// modulo the differing return values.
func
(
t
*
Tree
)
Put
(
k
int
,
upd
func
(
oldV
int
,
exists
bool
)
(
newV
int
,
write
bool
))
(
oldV
int
,
written
bool
)
{
pi
:=
-
1
var
p
*
x
q
:=
t
.
r
var
newV
int
if
q
!=
nil
{
for
{
i
,
ok
:=
t
.
find
(
q
,
k
)
if
ok
{
switch
x
:=
q
.
(
type
)
{
case
*
x
:
oldV
=
x
.
x
[
i
]
.
sep
.
d
[
0
]
.
v
newV
,
written
=
upd
(
oldV
,
true
)
if
!
written
{
return
}
x
.
x
[
i
]
.
sep
.
d
[
0
]
.
v
=
newV
case
*
d
:
oldV
=
x
.
d
[
i
]
.
v
newV
,
written
=
upd
(
oldV
,
true
)
if
!
written
{
return
}
x
.
d
[
i
]
.
v
=
newV
}
return
}
switch
x
:=
q
.
(
type
)
{
case
*
x
:
if
x
.
c
>
2
*
kx
{
t
.
splitX
(
p
,
&
x
,
pi
,
&
i
)
}
pi
=
i
p
=
x
q
=
x
.
x
[
i
]
.
ch
case
*
d
:
// new KV pair
newV
,
written
=
upd
(
newV
,
false
)
if
!
written
{
return
}
switch
{
case
x
.
c
<
2
*
kd
:
t
.
insert
(
x
,
i
,
k
,
newV
)
default
:
t
.
overflow
(
p
,
x
,
pi
,
i
,
k
,
newV
)
}
return
}
}
}
// new KV pair in empty tree
newV
,
written
=
upd
(
newV
,
false
)
if
!
written
{
return
}
z
:=
t
.
insert
(
&
d
{},
0
,
k
,
newV
)
t
.
r
,
t
.
first
,
t
.
last
=
z
,
z
,
z
return
}
func
(
t
*
Tree
)
split
(
p
*
x
,
q
*
d
,
pi
,
i
int
,
k
int
,
v
int
)
{
t
.
ver
++
r
:=
&
d
{}
...
...
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