PrefetchContents fetches the provided content IDs into the cache. Note that due to cache configuration, it's not guaranteed that all contents will actually be added to the cache. nolint:gocyclo
(ctx context.Context, contentIDs []ID, hint string)
| 55 | // |
| 56 | //nolint:gocyclo |
| 57 | func (bm *WriteManager) PrefetchContents(ctx context.Context, contentIDs []ID, hint string) []ID { |
| 58 | o := prefetchHintToOptions[hint] |
| 59 | if o == nil { |
| 60 | o = defaultPrefetchOptions |
| 61 | } |
| 62 | |
| 63 | bm.mu.RLock() |
| 64 | defer bm.mu.RUnlock() |
| 65 | |
| 66 | var ( |
| 67 | prefetched []ID |
| 68 | |
| 69 | // keep track of how contents we'll be fetching from each blob |
| 70 | contentsByBlob = map[blob.ID][]Info{} |
| 71 | ) |
| 72 | |
| 73 | for _, ci := range contentIDs { |
| 74 | _, bi, _ := bm.getContentInfoReadLocked(ctx, ci) |
| 75 | if bi == (Info{}) { |
| 76 | continue |
| 77 | } |
| 78 | |
| 79 | contentsByBlob[bi.PackBlobID] = append(contentsByBlob[bi.PackBlobID], bi) |
| 80 | prefetched = append(prefetched, ci) |
| 81 | } |
| 82 | |
| 83 | if hint == "none" { |
| 84 | return prefetched |
| 85 | } |
| 86 | |
| 87 | type work struct { |
| 88 | blobID blob.ID |
| 89 | contentID ID |
| 90 | } |
| 91 | |
| 92 | workCh := make(chan work) |
| 93 | |
| 94 | var wg sync.WaitGroup |
| 95 | |
| 96 | go func() { |
| 97 | defer close(workCh) |
| 98 | |
| 99 | for b, infos := range contentsByBlob { |
| 100 | if o.shouldPrefetchEntireBlob(infos) { |
| 101 | workCh <- work{blobID: b} |
| 102 | } else { |
| 103 | for _, bi := range infos { |
| 104 | workCh <- work{contentID: bi.ContentID} |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | }() |
| 109 | |
| 110 | for range parallelFetches { |
| 111 | wg.Go(func() { |
| 112 | var tmp gather.WriteBuffer |
| 113 | defer tmp.Close() |
| 114 |
nothing calls this directly
no test coverage detected