From fc05e35a08c689df0d03fc7d4bcb5bb13b0548b1 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Tue, 30 May 2023 20:12:36 +0200 Subject: [PATCH] index: let indexmap.Each iterate in allocation order Iterating through the indexmap according to the bucket order has the problem that all indexEntries are accessed in random order which is rather cache inefficient. As we already keep a list of all allocated blocks, just iterate through it. This allows iterating through a batch of indexEntries without random memory accesses. In addition, the packID will likely remain similar across multiple blobs as all blobs of a pack file are added as a single batch. --- internal/index/indexmap.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/internal/index/indexmap.go b/internal/index/indexmap.go index dfb4a1422..15f253d76 100644 --- a/internal/index/indexmap.go +++ b/internal/index/indexmap.go @@ -54,13 +54,10 @@ func (m *indexMap) add(id restic.ID, packIdx int, offset, length uint32, uncompr // foreach calls fn for all entries in the map, until fn returns false. func (m *indexMap) foreach(fn func(*indexEntry) bool) { - for _, ei := range m.buckets { - for ei != 0 { - e := m.resolve(ei) - if !fn(e) { - return - } - ei = e.next + blockCount := m.blockList.Size() + for i := uint(1); i < blockCount; i++ { + if !fn(m.resolve(i)) { + return } } }