Commit e4802b23 authored by Jan Mercl's avatar Jan Mercl

Make tree version numbers more robust

parent 5f12ed84
all: .PHONY: all todo clean cover generic
go fmt
go test -i all: editor
go test
go build go build
go vet go vet
go install go install
make todo make todo
editor:
go fmt
go test -i
go test
todo: todo:
@grep -n ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* *.go || true @grep -n ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* *.go || true
@grep -n TODO *.go || true @grep -n TODO *.go || true
...@@ -15,10 +19,10 @@ todo: ...@@ -15,10 +19,10 @@ todo:
clean: clean:
@go clean @go clean
rm -f *~ cov cov.html rm -f *~
gocov: cover:
gocov test $(COV) | gocov-html > cov.html t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
generic: generic:
@# writes to stdout a version where the type of key is KEY and the type @# writes to stdout a version where the type of key is KEY and the type
......
...@@ -230,6 +230,7 @@ func (t *Tree) Clear() { ...@@ -230,6 +230,7 @@ func (t *Tree) Clear() {
} }
func (t *Tree) cat(p *x, q, r *d, pi int) { func (t *Tree) cat(p *x, q, r *d, pi int) {
t.ver++
q.mvL(r, r.c) q.mvL(r, r.c)
if r.n != nil { if r.n != nil {
r.n.p = q r.n.p = q
...@@ -246,6 +247,7 @@ func (t *Tree) cat(p *x, q, r *d, pi int) { ...@@ -246,6 +247,7 @@ func (t *Tree) cat(p *x, q, r *d, pi int) {
} }
func (t *Tree) catX(p, q, r *x, pi int) { func (t *Tree) catX(p, q, r *x, pi int) {
t.ver++
q.x[q.c].sep = p.x[pi].sep q.x[q.c].sep = p.x[pi].sep
copy(q.x[q.c+1:], r.x[:r.c]) copy(q.x[q.c+1:], r.x[:r.c])
q.c += r.c + 1 q.c += r.c + 1
...@@ -298,7 +300,6 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { ...@@ -298,7 +300,6 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
} }
case *d: case *d:
t.extract(x, i) t.extract(x, i)
t.ver++
if x.c >= kd { if x.c >= kd {
return return
} }
...@@ -327,6 +328,7 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) { ...@@ -327,6 +328,7 @@ func (t *Tree) Delete(k interface{} /*K*/) (ok bool) {
} }
func (t *Tree) extract(q *d, i int) { // (r interface{} /*V*/) { func (t *Tree) extract(q *d, i int) { // (r interface{} /*V*/) {
t.ver++
//r = q.d[i].v // prepared for Extract //r = q.d[i].v // prepared for Extract
q.c-- q.c--
if i < q.c { if i < q.c {
...@@ -411,6 +413,7 @@ func (t *Tree) Get(k interface{} /*K*/) (v interface{} /*V*/, ok bool) { ...@@ -411,6 +413,7 @@ func (t *Tree) Get(k interface{} /*K*/) (v interface{} /*V*/, ok bool) {
} }
func (t *Tree) insert(q *d, i int, k interface{} /*K*/, v interface{} /*V*/) *d { func (t *Tree) insert(q *d, i int, k interface{} /*K*/, v interface{} /*V*/) *d {
t.ver++
c := q.c c := q.c
if i < c { if i < c {
copy(q.d[i+1:], q.d[i:c]) copy(q.d[i+1:], q.d[i:c])
...@@ -438,6 +441,7 @@ func (t *Tree) Len() int { ...@@ -438,6 +441,7 @@ func (t *Tree) Len() int {
} }
func (t *Tree) overflow(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /*V*/) { func (t *Tree) overflow(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /*V*/) {
t.ver++
l, r := p.siblings(pi) l, r := p.siblings(pi)
if l != nil && l.c < 2*kd { if l != nil && l.c < 2*kd {
...@@ -546,7 +550,6 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -546,7 +550,6 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
default: default:
t.overflow(p, x, pi, i, k, v) t.overflow(p, x, pi, i, k, v)
} }
t.ver++
return return
} }
} }
...@@ -558,6 +561,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) { ...@@ -558,6 +561,7 @@ func (t *Tree) Set(k interface{} /*K*/, v interface{} /*V*/) {
} }
func (t *Tree) split(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /*V*/) { func (t *Tree) split(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /*V*/) {
t.ver++
r := &d{} r := &d{}
if q.n != nil { if q.n != nil {
r.n = q.n r.n = q.n
...@@ -588,6 +592,7 @@ func (t *Tree) split(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} / ...@@ -588,6 +592,7 @@ func (t *Tree) split(p *x, q *d, pi, i int, k interface{} /*K*/, v interface{} /
} }
func (t *Tree) splitX(p *x, pp **x, pi int, i *int) { func (t *Tree) splitX(p *x, pp **x, pi int, i *int) {
t.ver++
q := *pp q := *pp
r := &x{} r := &x{}
copy(r.x[:], q.x[kx+1:]) copy(r.x[:], q.x[kx+1:])
...@@ -609,6 +614,7 @@ func (t *Tree) splitX(p *x, pp **x, pi int, i *int) { ...@@ -609,6 +614,7 @@ func (t *Tree) splitX(p *x, pp **x, pi int, i *int) {
} }
func (t *Tree) underflow(p *x, q *d, pi int) { func (t *Tree) underflow(p *x, q *d, pi int) {
t.ver++
l, r := p.siblings(pi) l, r := p.siblings(pi)
if l != nil && l.c+q.c >= 2*kd { if l != nil && l.c+q.c >= 2*kd {
...@@ -624,6 +630,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -624,6 +630,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
} }
func (t *Tree) underflowX(p *x, pp **x, pi int, i *int) { func (t *Tree) underflowX(p *x, pp **x, pi int, i *int) {
t.ver++
var l, r *x var l, r *x
q := *pp q := *pp
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
// This is how, for example, 'example/int.go' was created: // This is how, for example, 'example/int.go' was created:
// //
// $ mkdir example // $ mkdir example
// $ make generic | sed -e 's/int/int/g' -e 's/int/int/g' > example/int.go // $ make generic | sed -e 's/key/int/g' -e 's/value/int/g' > example/int.go
// //
package b package b
...@@ -39,9 +39,10 @@ const ( ...@@ -39,9 +39,10 @@ const (
type ( type (
// Cmp compares a and b. Return value is: // Cmp compares a and b. Return value is:
// //
// -1 if a < b // < 0 if a < b
// 0 if a == b // 0 if a == b
// +1 if a > b // > 0 if a > b
//
Cmp func(a, b int) int Cmp func(a, b int) int
d struct { // data page d struct { // data page
...@@ -194,6 +195,7 @@ func (t *Tree) Clear() { ...@@ -194,6 +195,7 @@ func (t *Tree) Clear() {
} }
func (t *Tree) cat(p *x, q, r *d, pi int) { func (t *Tree) cat(p *x, q, r *d, pi int) {
t.ver++
q.mvL(r, r.c) q.mvL(r, r.c)
if r.n != nil { if r.n != nil {
r.n.p = q r.n.p = q
...@@ -210,6 +212,7 @@ func (t *Tree) cat(p *x, q, r *d, pi int) { ...@@ -210,6 +212,7 @@ func (t *Tree) cat(p *x, q, r *d, pi int) {
} }
func (t *Tree) catX(p, q, r *x, pi int) { func (t *Tree) catX(p, q, r *x, pi int) {
t.ver++
q.x[q.c].sep = p.x[pi].sep q.x[q.c].sep = p.x[pi].sep
copy(q.x[q.c+1:], r.x[:r.c]) copy(q.x[q.c+1:], r.x[:r.c])
q.c += r.c + 1 q.c += r.c + 1
...@@ -262,7 +265,6 @@ func (t *Tree) Delete(k int) (ok bool) { ...@@ -262,7 +265,6 @@ func (t *Tree) Delete(k int) (ok bool) {
} }
case *d: case *d:
t.extract(x, i) t.extract(x, i)
t.ver++
if x.c >= kd { if x.c >= kd {
return return
} }
...@@ -291,6 +293,7 @@ func (t *Tree) Delete(k int) (ok bool) { ...@@ -291,6 +293,7 @@ func (t *Tree) Delete(k int) (ok bool) {
} }
func (t *Tree) extract(q *d, i int) { // (r int) { func (t *Tree) extract(q *d, i int) { // (r int) {
t.ver++
//r = q.d[i].v // prepared for Extract //r = q.d[i].v // prepared for Extract
q.c-- q.c--
if i < q.c { if i < q.c {
...@@ -375,6 +378,7 @@ func (t *Tree) Get(k int) (v int, ok bool) { ...@@ -375,6 +378,7 @@ func (t *Tree) Get(k int) (v int, ok bool) {
} }
func (t *Tree) insert(q *d, i int, k int, v int) *d { func (t *Tree) insert(q *d, i int, k int, v int) *d {
t.ver++
c := q.c c := q.c
if i < c { if i < c {
copy(q.d[i+1:], q.d[i:c]) copy(q.d[i+1:], q.d[i:c])
...@@ -402,6 +406,7 @@ func (t *Tree) Len() int { ...@@ -402,6 +406,7 @@ func (t *Tree) Len() int {
} }
func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) { func (t *Tree) overflow(p *x, q *d, pi, i int, k int, v int) {
t.ver++
l, r := p.siblings(pi) l, r := p.siblings(pi)
if l != nil && l.c < 2*kd { if l != nil && l.c < 2*kd {
...@@ -510,7 +515,6 @@ func (t *Tree) Set(k int, v int) { ...@@ -510,7 +515,6 @@ func (t *Tree) Set(k int, v int) {
default: default:
t.overflow(p, x, pi, i, k, v) t.overflow(p, x, pi, i, k, v)
} }
t.ver++
return return
} }
} }
...@@ -522,6 +526,7 @@ func (t *Tree) Set(k int, v int) { ...@@ -522,6 +526,7 @@ func (t *Tree) Set(k int, v int) {
} }
func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) { func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) {
t.ver++
r := &d{} r := &d{}
if q.n != nil { if q.n != nil {
r.n = q.n r.n = q.n
...@@ -552,6 +557,7 @@ func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) { ...@@ -552,6 +557,7 @@ func (t *Tree) split(p *x, q *d, pi, i int, k int, v int) {
} }
func (t *Tree) splitX(p *x, pp **x, pi int, i *int) { func (t *Tree) splitX(p *x, pp **x, pi int, i *int) {
t.ver++
q := *pp q := *pp
r := &x{} r := &x{}
copy(r.x[:], q.x[kx+1:]) copy(r.x[:], q.x[kx+1:])
...@@ -573,6 +579,7 @@ func (t *Tree) splitX(p *x, pp **x, pi int, i *int) { ...@@ -573,6 +579,7 @@ func (t *Tree) splitX(p *x, pp **x, pi int, i *int) {
} }
func (t *Tree) underflow(p *x, q *d, pi int) { func (t *Tree) underflow(p *x, q *d, pi int) {
t.ver++
l, r := p.siblings(pi) l, r := p.siblings(pi)
if l != nil && l.c+q.c >= 2*kd { if l != nil && l.c+q.c >= 2*kd {
...@@ -588,6 +595,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) { ...@@ -588,6 +595,7 @@ func (t *Tree) underflow(p *x, q *d, pi int) {
} }
func (t *Tree) underflowX(p *x, pp **x, pi int, i *int) { func (t *Tree) underflowX(p *x, pp **x, pi int, i *int) {
t.ver++
var l, r *x var l, r *x
q := *pp q := *pp
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment