MCPcopy Create free account
hub / github.com/blobcache/blobcache / Copy

Method Copy

src/bccore/txapi.go:162–233  ·  view source on GitHub ↗
(ctx context.Context, txh blobcache.Handle, srcTxns []blobcache.Handle, cids []blobcache.CID, out *blobcache.BitMap)

Source from the content-addressed store, hash-verified

160}
161
162func (sys *System) Copy(ctx context.Context, txh blobcache.Handle, srcTxns []blobcache.Handle, cids []blobcache.CID, out *blobcache.BitMap) error {
163 logctx.Debug(ctx, "begin", zap.String("method", "Copy"), zap.Stringer("oid", txh.OID))
164 defer logctx.Debug(ctx, "done", zap.String("method", "Copy"), zap.Stringer("oid", txh.OID))
165 dstTx, err := sys.resolveTx(txh, true, blobcache.Action_TX_COPY_TO)
166 if err != nil {
167 return err
168 }
169 if p := dstTx.backend.Params(); !p.Modify {
170 return blobcache.ErrTxReadOnly{Tx: txh.OID, Op: "COPY"}
171 }
172
173 type srcTxn struct {
174 oid blobcache.OID
175 tx transaction
176 }
177 resolvedSrcs := make([]srcTxn, len(srcTxns))
178 for i, srcH := range srcTxns {
179 src, err := sys.resolveTx(srcH, true, blobcache.Action_TX_COPY_FROM)
180 if err != nil {
181 return err
182 }
183 resolvedSrcs[i] = srcTxn{oid: srcH.OID, tx: src}
184 }
185
186 var buf []byte
187 var exists blobcache.BitMap
188 for i, cid := range cids {
189 if len(resolvedSrcs) == 0 {
190 continue
191 }
192 start := int(cid[0]) % len(resolvedSrcs)
193 for j := range resolvedSrcs {
194 src := resolvedSrcs[(start+j)%len(resolvedSrcs)]
195 exists = exists[:0]
196 if err := src.tx.backend.Exists(ctx, []blobcache.CID{cid}, &exists); err != nil {
197 return fmt.Errorf("copy from tx %v: %w", src.oid, err)
198 }
199 if !exists.IsSet(0) {
200 continue
201 }
202 srcMax := src.tx.backend.MaxSize()
203 if cap(buf) < srcMax {
204 buf = make([]byte, srcMax)
205 }
206 n, err := src.tx.backend.Get(ctx, cid, buf[:srcMax], blobcache.GetOpts{})
207 if err != nil {
208 if blobcache.IsErrNotFound(err) {
209 continue
210 }
211 return fmt.Errorf("copy from tx %v: %w", src.oid, err)
212 }
213 data := buf[:n]
214 if dstTx.backend.HashAlgo().Hash(data) != cid {
215 continue
216 }
217 cid2, err := dstTx.backend.Post(ctx, data, blobcache.PostOpts{})
218 if err != nil {
219 var eTooLarge blobcache.ErrTooLarge

Callers

nothing calls this directly

Calls 13

resolveTxMethod · 0.95
IsSetMethod · 0.95
IsErrNotFoundFunction · 0.92
setErrTxOIDFunction · 0.85
StringMethod · 0.65
ParamsMethod · 0.65
ExistsMethod · 0.65
MaxSizeMethod · 0.65
GetMethod · 0.65
HashMethod · 0.65
HashAlgoMethod · 0.65
PostMethod · 0.65

Tested by

no test coverage detected