keep ref ids in RefIndex sorted

master
Oliver Tonnhofer 2013-05-06 13:42:58 +02:00
parent 1f0fca5552
commit 40c8b04181
2 changed files with 61 additions and 2 deletions

17
cache/diff.go vendored
View File

@ -3,6 +3,7 @@ package cache
import (
"code.google.com/p/goprotobuf/proto"
bin "encoding/binary"
"sort"
"sync"
)
@ -39,8 +40,7 @@ func (index *RefIndex) Add(id, ref int64) error {
refs.Ids = make([]int64, 0, 1)
}
// TODO change to delta encoding
// TODO check for duplicates
refs.Ids = append(refs.Ids, ref)
refs.insertId(ref)
data, err = proto.Marshal(refs)
if err != nil {
@ -50,6 +50,19 @@ func (index *RefIndex) Add(id, ref int64) error {
return err
}
func (r *Refs) insertId(ref int64) {
i := sort.Search(len(r.Ids), func(i int) bool {
return r.Ids[i] >= ref
})
if i < len(r.Ids) && r.Ids[i] >= ref {
r.Ids = append(r.Ids, 0)
copy(r.Ids[i+1:], r.Ids[i:])
r.Ids[i] = ref
} else {
r.Ids = append(r.Ids, ref)
}
}
func (index *RefIndex) Get(id int64) []int64 {
keyBuf := make([]byte, 8)
bin.PutVarint(keyBuf, id)

46
cache/diff_test.go vendored Normal file
View File

@ -0,0 +1,46 @@
package cache
import (
"testing"
)
func TestInsertId(t *testing.T) {
refs := Refs{}
refs.Ids = make([]int64, 0, 1)
refs.insertId(1)
if refs.Ids[0] != 1 {
t.Fatal(refs)
}
refs.insertId(10)
if refs.Ids[0] != 1 && refs.Ids[1] != 10 {
t.Fatal(refs)
}
// insert twice
refs.insertId(10)
if refs.Ids[0] != 1 && refs.Ids[1] != 10 {
t.Fatal(refs)
}
// insert before
refs.insertId(0)
if refs.Ids[0] != 0 && refs.Ids[1] != 1 && refs.Ids[2] != 10 {
t.Fatal(refs)
}
// insert after
refs.insertId(12)
if refs.Ids[0] != 0 && refs.Ids[1] != 1 && refs.Ids[2] != 10 && refs.Ids[3] != 12 {
t.Fatal(refs)
}
// insert between
refs.insertId(11)
if refs.Ids[0] != 0 && refs.Ids[1] != 1 && refs.Ids[2] != 10 && refs.Ids[3] != 11 && refs.Ids[4] != 12 {
t.Fatal(refs)
}
}