func signFile(sctx *wsync.Context, fileIndex int, reader io.Reader, writeHash wsync.SignatureWriter, errs chan error, done chan bool) { err := sctx.CreateSignature(int64(fileIndex), reader, writeHash) if err != nil { errs <- errors.Wrap(err, 1) } done <- true }
func diffFile(sctx *wsync.Context, dctx *DiffContext, blockLibrary *wsync.BlockLibrary, reader io.Reader, opsWriter wsync.OperationWriter, preferredFileIndex int64, errs chan error, done chan bool) { err := sctx.ComputeDiff(reader, blockLibrary, opsWriter, preferredFileIndex) if err != nil { errs <- errors.Wrap(err, 1) } done <- true }
func (actx *ApplyContext) lazilyPatchFile(sctx *wsync.Context, targetContainer *tlc.Container, targetPool wsync.Pool, outputContainer *tlc.Container, outputPool wsync.WritablePool, fileIndex int64, onSourceWrite counter.CountCallback, ops chan wsync.Operation, inplace bool) (written int64, transposition *Transposition, err error) { var writer io.WriteCloser defer func() { if writer != nil { cErr := writer.Close() if cErr != nil && err == nil { err = cErr } } }() var realops chan wsync.Operation errs := make(chan error, 1) first := true for op := range ops { if first { first = false // if the first operation is a blockrange that copies an // entire file from target into a file from source that has // the same name and size, then it's a no-op! if inplace && op.Type == wsync.OpBlockRange && op.BlockIndex == 0 { outputFile := outputContainer.Files[fileIndex] targetFile := targetContainer.Files[op.FileIndex] numOutputBlocks := ComputeNumBlocks(outputFile.Size) if op.BlockSpan == numOutputBlocks && outputFile.Size == targetFile.Size { transposition = &Transposition{ TargetPath: targetFile.Path, OutputPath: outputFile.Path, } } } if transposition != nil { errs <- nil } else { realops = make(chan wsync.Operation) writer, err = outputPool.GetWriter(fileIndex) if err != nil { return 0, nil, errors.Wrap(err, 1) } writeCounter := counter.NewWriterCallback(onSourceWrite, writer) go func() { failFast := true if actx.WoundsConsumer != nil { failFast = false } applyErr := sctx.ApplyPatchFull(writeCounter, targetPool, realops, failFast) if applyErr != nil { errs <- applyErr return } written = writeCounter.Count() errs <- nil }() } } // if not a transposition, relay errors if transposition == nil { select { case cErr := <-errs: // if we get an error here, ApplyPatch failed so we no longer need to close realops if cErr != nil { return 0, nil, errors.Wrap(cErr, 1) } case realops <- op: // muffin } } } if transposition == nil { // realops may be nil if the file was empty (0 ops) if realops != nil { close(realops) } else { // if we had 0 ops, signal no errors occured errs <- nil } } err = <-errs if err != nil { return 0, nil, errors.Wrap(err, 1) } return }