(ctx context.Context, br blob.Ref, source io.Reader)
| 132 | } |
| 133 | |
| 134 | func (s *Storage) ReceiveBlob(ctx context.Context, br blob.Ref, source io.Reader) (blob.SizedRef, error) { |
| 135 | sb := blob.SizedRef{} |
| 136 | h := br.Hash() |
| 137 | if h == nil { |
| 138 | return sb, fmt.Errorf("Unsupported blobref hash for %s", br) |
| 139 | } |
| 140 | all, err := io.ReadAll(io.TeeReader(source, h)) |
| 141 | if err != nil { |
| 142 | return sb, err |
| 143 | } |
| 144 | if !br.HashMatches(h) { |
| 145 | // This is a somewhat redundant check, since |
| 146 | // blobserver.Receive now does it. But for testing code, |
| 147 | // it's worth the cost. |
| 148 | return sb, fmt.Errorf("Hash mismatch receiving blob %s", br) |
| 149 | } |
| 150 | s.mu.Lock() |
| 151 | defer s.mu.Unlock() |
| 152 | if s.m == nil { |
| 153 | s.m = make(map[blob.Ref][]byte) |
| 154 | } |
| 155 | _, had := s.m[br] |
| 156 | if !had { |
| 157 | s.m[br] = all |
| 158 | if s.lru != nil { |
| 159 | s.lru.Add(br.String(), nil) |
| 160 | } |
| 161 | s.size += int64(len(all)) |
| 162 | for s.maxSize != 0 && s.size > s.maxSize { |
| 163 | if key, _ := s.lru.RemoveOldest(); key != "" { |
| 164 | s.removeBlobLocked(blob.MustParse(key)) |
| 165 | } else { |
| 166 | break // shouldn't happen |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | return blob.SizedRef{Ref: br, Size: uint32(len(all))}, nil |
| 171 | } |
| 172 | |
| 173 | func (s *Storage) StatBlobs(ctx context.Context, blobs []blob.Ref, fn func(blob.SizedRef) error) error { |
| 174 | for _, br := range blobs { |
no test coverage detected