Merge pull request #4145 from greatroar/index-encode

index: Optimize generatePackList
This commit is contained in:
Michael Eischer 2023-01-21 01:01:12 +01:00 committed by GitHub
commit 0f398b82e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 17 deletions

View file

@ -317,9 +317,9 @@ type blobJSON struct {
} }
// generatePackList returns a list of packs. // generatePackList returns a list of packs.
func (idx *Index) generatePackList() ([]*packJSON, error) { func (idx *Index) generatePackList() ([]packJSON, error) {
list := []*packJSON{} list := make([]packJSON, 0, len(idx.packs))
packs := make(map[restic.ID]*packJSON) packs := make(map[restic.ID]int, len(list)) // Maps to index in list.
for typ := range idx.byType { for typ := range idx.byType {
m := &idx.byType[typ] m := &idx.byType[typ]
@ -329,18 +329,13 @@ func (idx *Index) generatePackList() ([]*packJSON, error) {
panic("null pack id") panic("null pack id")
} }
debug.Log("handle blob %v", e.id) i, ok := packs[packID]
// see if pack is already in map
p, ok := packs[packID]
if !ok { if !ok {
// else create new pack i = len(list)
p = &packJSON{ID: packID} list = append(list, packJSON{ID: packID})
packs[packID] = i
// and append it to the list and map
list = append(list, p)
packs[p.ID] = p
} }
p := &list[i]
// add blob // add blob
p.Blobs = append(p.Blobs, blobJSON{ p.Blobs = append(p.Blobs, blobJSON{
@ -355,14 +350,12 @@ func (idx *Index) generatePackList() ([]*packJSON, error) {
}) })
} }
debug.Log("done")
return list, nil return list, nil
} }
type jsonIndex struct { type jsonIndex struct {
Supersedes restic.IDs `json:"supersedes,omitempty"` Supersedes restic.IDs `json:"supersedes,omitempty"`
Packs []*packJSON `json:"packs"` Packs []packJSON `json:"packs"`
} }
// Encode writes the JSON serialization of the index to the writer w. // Encode writes the JSON serialization of the index to the writer w.

View file

@ -3,6 +3,7 @@ package index_test
import ( import (
"bytes" "bytes"
"context" "context"
"fmt"
"math/rand" "math/rand"
"sync" "sync"
"testing" "testing"
@ -405,6 +406,26 @@ func BenchmarkDecodeIndexParallel(b *testing.B) {
}) })
} }
func BenchmarkEncodeIndex(b *testing.B) {
for _, n := range []int{100, 1000, 10000} {
idx, _ := createRandomIndex(rand.New(rand.NewSource(0)), n)
b.Run(fmt.Sprint(n), func(b *testing.B) {
buf := new(bytes.Buffer)
err := idx.Encode(buf)
rtest.OK(b, err)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
buf.Reset()
_ = idx.Encode(buf)
}
})
}
}
func TestIndexUnserializeOld(t *testing.T) { func TestIndexUnserializeOld(t *testing.T) {
idx, oldFormat, err := index.DecodeIndex(docOldExample, restic.NewRandomID()) idx, oldFormat, err := index.DecodeIndex(docOldExample, restic.NewRandomID())
rtest.OK(t, err) rtest.OK(t, err)