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
14175e51
Commit
14175e51
authored
Jun 22, 2014
by
Jan Mercl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix missed splits
parent
858434e3
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
86 additions
and
131 deletions
+86
-131
all_test.go
all_test.go
+8
-48
btree.go
btree.go
+36
-14
example/int.go
example/int.go
+42
-69
No files found.
all_test.go
View file @
14175e51
...
...
@@ -218,8 +218,8 @@ func TestSetGet0(t *testing.T) {
}
func
TestSetGet1
(
t
*
testing
.
T
)
{
const
N
=
5
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
const
N
=
6
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x3
33333
,
0xcccccc
,
0x3
14259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
...
...
@@ -253,10 +253,6 @@ func TestSetGet1(t *testing.T) {
}
}
func
BenchmarkSetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e2
)
}
func
BenchmarkSetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSetSeq
(
b
,
1e3
)
}
...
...
@@ -287,10 +283,6 @@ func benchmarkSetSeq(b *testing.B, n int) {
b
.
StopTimer
()
}
func
BenchmarkGetSeq1e2
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e2
)
}
func
BenchmarkGetSeq1e3
(
b
*
testing
.
B
)
{
benchmarkGetSeq
(
b
,
1e3
)
}
...
...
@@ -322,10 +314,6 @@ func benchmarkGetSeq(b *testing.B, n int) {
b
.
StopTimer
()
}
func
BenchmarkSetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e2
)
}
func
BenchmarkSetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSetRnd
(
b
,
1e3
)
}
...
...
@@ -361,10 +349,6 @@ func benchmarkSetRnd(b *testing.B, n int) {
b
.
StopTimer
()
}
func
BenchmarkGetRnd1e2
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e2
)
}
func
BenchmarkGetRnd1e3
(
b
*
testing
.
B
)
{
benchmarkGetRnd
(
b
,
1e3
)
}
...
...
@@ -402,8 +386,8 @@ func benchmarkGetRnd(b *testing.B, n int) {
}
func
TestSetGet2
(
t
*
testing
.
T
)
{
const
N
=
5
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
const
N
=
6
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x3
33333
,
0xcccccc
,
0x3
14259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
...
...
@@ -548,8 +532,8 @@ func TestDelete0(t *testing.T) {
}
func
TestDelete1
(
t
*
testing
.
T
)
{
const
N
=
6
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
const
N
=
7
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x3
33333
,
0xcccccc
,
0x3
14259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
...
...
@@ -573,10 +557,6 @@ func TestDelete1(t *testing.T) {
}
}
func
benchmarkDelSeq1e2
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e2
)
}
func
benchmarkDelSeq1e3
(
b
*
testing
.
B
)
{
benchmarkDelSeq
(
b
,
1e3
)
}
...
...
@@ -610,10 +590,6 @@ func benchmarkDelSeq(b *testing.B, n int) {
b
.
StopTimer
()
}
func
BenchmarkDelRnd1e2
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e2
)
}
func
BenchmarkDelRnd1e3
(
b
*
testing
.
B
)
{
benchmarkDelRnd
(
b
,
1e3
)
}
...
...
@@ -653,8 +629,8 @@ func benchmarkDelRnd(b *testing.B, n int) {
}
func
TestDelete2
(
t
*
testing
.
T
)
{
const
N
=
5
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x314259
}
{
const
N
=
6
0000
for
_
,
x
:=
range
[]
int
{
0
,
-
1
,
0x555555
,
0xaaaaaa
,
0x3
33333
,
0xcccccc
,
0x3
14259
}
{
r
:=
TreeNew
(
cmp
)
set
:=
r
.
Set
a
:=
make
([]
int
,
N
)
...
...
@@ -819,10 +795,6 @@ func TestEnumeratorPrev(t *testing.T) {
}
}
func
BenchmarkSeekSeq1e2
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e2
)
}
func
BenchmarkSeekSeq1e3
(
b
*
testing
.
B
)
{
benchmarkSeekSeq
(
b
,
1e3
)
}
...
...
@@ -855,10 +827,6 @@ func benchmarkSeekSeq(b *testing.B, n int) {
b
.
StopTimer
()
}
func
BenchmarkSeekRnd1e2
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e2
)
}
func
BenchmarkSeekRnd1e3
(
b
*
testing
.
B
)
{
benchmarkSeekRnd
(
b
,
1e3
)
}
...
...
@@ -894,10 +862,6 @@ func benchmarkSeekRnd(b *testing.B, n int) {
}
}
func
BenchmarkNext1e2
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e2
)
}
func
BenchmarkNext1e3
(
b
*
testing
.
B
)
{
benchmarkNext
(
b
,
1e3
)
}
...
...
@@ -940,10 +904,6 @@ func benchmarkNext(b *testing.B, n int) {
}
}
func
BenchmarkPrev1e2
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e2
)
}
func
BenchmarkPrev1e3
(
b
*
testing
.
B
)
{
benchmarkPrev
(
b
,
1e3
)
}
...
...
btree.go
View file @
14175e51
...
...
@@ -36,34 +36,46 @@
//
// No other changes to int.go are (strictly) necessary, it compiles just fine.
//
// Running the benchmarks for 1000 keys on a machine with Intel
X5450 CPU @ 3
// GHz, Go release 1.3.
// Running the benchmarks for 1000 keys on a machine with Intel
i5-4670 CPU @
//
3.4
GHz, Go release 1.3.
//
// $ go test -bench 1e3 example/all_test.go example/int.go
// PASS
// 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
// BenchmarkSetSeq1e3 10000 146740 ns/op
// BenchmarkGetSeq1e3 10000 108261 ns/op
// BenchmarkSetRnd1e3 10000 254359 ns/op
// BenchmarkGetRnd1e3 10000 134621 ns/op
// BenchmarkDelRnd1e3 10000 211864 ns/op
// BenchmarkSeekSeq1e3 10000 148628 ns/op
// BenchmarkSeekRnd1e3 10000 215166 ns/op
// BenchmarkNext1e3 200000 9211 ns/op
// BenchmarkPrev1e3 200000 8843 ns/op
// ok command-line-arguments 25.071s
// $
package
b
import
(
"fmt"
"io"
)
//TODO check vs orig initialize/finalize
const
(
kx
=
128
// min
2 //TODO benchmark tune this number if using custom key/value type(s).
kd
=
64
// min 1
//TODO benchmark tune this number if using custom key/value type(s).
kx
=
3
2
//TODO benchmark tune this number if using custom key/value type(s).
kd
=
32
//TODO benchmark tune this number if using custom key/value type(s).
)
func
init
()
{
if
kd
<
1
{
panic
(
fmt
.
Errorf
(
"kd %d: out of range"
,
kd
))
}
if
kx
<
2
{
panic
(
fmt
.
Errorf
(
"kx %d: out of range"
,
kx
))
}
}
type
(
// Cmp compares a and b. Return value is:
//
...
...
@@ -529,6 +541,11 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
if
ok
{
switch
x
:=
q
.
(
type
)
{
case
*
x
:
if
x
.
c
>
2
*
kx
{
t
.
splitX
(
p
,
&
x
,
pi
,
&
i
)
}
pi
=
i
+
1
p
=
x
q
=
x
.
x
[
i
+
1
]
.
ch
continue
case
*
d
:
...
...
@@ -580,6 +597,11 @@ func (t *Tree) Put(k interface{} /*K*/, upd func(oldV interface{} /*V*/, exists
if
ok
{
switch
x
:=
q
.
(
type
)
{
case
*
x
:
if
x
.
c
>
2
*
kx
{
t
.
splitX
(
p
,
&
x
,
pi
,
&
i
)
}
pi
=
i
+
1
p
=
x
q
=
x
.
x
[
i
+
1
]
.
ch
continue
case
*
d
:
...
...
example/int.go
View file @
14175e51
...
...
@@ -2,68 +2,31 @@
// 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.
//
// Changelog
//
// 2014-04-18: Added new method Put.
//
// Generic types
//
// Keys and their associated values are interface{} typed, similar to all of
// the containers in the standard library.
//
// Semiautomatic production of a type specific variant of this package is
// supported via
//
// $ make generic
//
// This command 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 these tokens with your
// desired type(s), using any technique you're comfortable with.
//
// This is how, for example, 'example/int.go' was created:
//
// $ mkdir example
// $
// $ # Note: the command bellow must be actually written using the words
// $ # 'key' and 'value' in all CAPS. The proper form is avoided in this
// $ # documentation to not confuse any text replacement mechanism.
// $
// $ 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.
//
// Running the benchmarks for 1000 keys on a machine with Intel X5450 CPU @ 3
// GHz, Go release 1.3.
//
// $ go test -bench 1e3 example/all_test.go example/int.go
// PASS
// 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 implements a int->int B+tree.
package
b
import
(
"fmt"
"io"
)
//TODO check vs orig initialize/finalize
const
(
kx
=
128
// min
2 //TODO benchmark tune this number if using custom key/value type(s).
kd
=
64
// min 1
//TODO benchmark tune this number if using custom key/value type(s).
kx
=
3
2
//TODO benchmark tune this number if using custom key/value type(s).
kd
=
32
//TODO benchmark tune this number if using custom key/value type(s).
)
func
init
()
{
if
kd
<
1
{
panic
(
fmt
.
Errorf
(
"kd %d: out of range"
,
kd
))
}
if
kx
<
2
{
panic
(
fmt
.
Errorf
(
"kx %d: out of range"
,
kx
))
}
}
type
(
// Cmp compares a and b. Return value is:
//
...
...
@@ -363,15 +326,15 @@ func (t *Tree) find(q interface{}, k int) (i int, ok bool) {
return
l
,
false
}
//
A //
First returns the first item of the tree in the key collating order, or
//
A //
(zero-value, zero-value) if the tree is empty.
//A
func (t *Tree) First() (k int, v int) {
//A
if q := t.first; q != nil {
//A
q := &q.d[0]
//A
k, v = q.k, q.v
//A
}
//A
return
//A
}
// First returns the first item of the tree in the key collating order, or
// (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
]
k
,
v
=
q
.
k
,
q
.
v
}
return
}
// Get returns the value associated with k and true if it exists. Otherwise Get
// returns (zero-value, false).
...
...
@@ -414,15 +377,15 @@ func (t *Tree) insert(q *d, i int, k int, v int) *d {
return
q
}
//
A //
Last returns the last item of the tree in the key collating order, or
//
A //
(zero-value, zero-value) if the tree is empty.
//A
func (t *Tree) Last() (k int, v int) {
//A
if q := t.last; q != nil {
//A
q := &q.d[q.c-1]
//A
k, v = q.k, q.v
//A
}
//A
return
//A
}
// 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
]
k
,
v
=
q
.
k
,
q
.
v
}
return
}
// Len returns the number of items in the tree.
func
(
t
*
Tree
)
Len
()
int
{
...
...
@@ -529,6 +492,11 @@ func (t *Tree) Set(k int, v int) {
if
ok
{
switch
x
:=
q
.
(
type
)
{
case
*
x
:
if
x
.
c
>
2
*
kx
{
t
.
splitX
(
p
,
&
x
,
pi
,
&
i
)
}
pi
=
i
+
1
p
=
x
q
=
x
.
x
[
i
+
1
]
.
ch
continue
case
*
d
:
...
...
@@ -580,6 +548,11 @@ func (t *Tree) Put(k int, upd func(oldV int, exists bool) (newV int, write bool)
if
ok
{
switch
x
:=
q
.
(
type
)
{
case
*
x
:
if
x
.
c
>
2
*
kx
{
t
.
splitX
(
p
,
&
x
,
pi
,
&
i
)
}
pi
=
i
+
1
p
=
x
q
=
x
.
x
[
i
+
1
]
.
ch
continue
case
*
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