append writes the provided blob to the current data file.
(br blob.SizedRef, r io.Reader)
| 662 | |
| 663 | // append writes the provided blob to the current data file. |
| 664 | func (s *storage) append(br blob.SizedRef, r io.Reader) error { |
| 665 | s.mu.Lock() |
| 666 | defer s.mu.Unlock() |
| 667 | if s.closed { |
| 668 | return errors.New("diskpacked: write to closed storage") |
| 669 | } |
| 670 | |
| 671 | // to be able to undo the append |
| 672 | origOffset := s.size |
| 673 | |
| 674 | fn := s.writer.Name() |
| 675 | n, err := fmt.Fprintf(s.writer, "[%v %v]", br.Ref.String(), br.Size) |
| 676 | s.size += int64(n) |
| 677 | writeVar.Add(fn, int64(n)) |
| 678 | writeTotVar.Add(s.root, int64(n)) |
| 679 | if err != nil { |
| 680 | return err |
| 681 | } |
| 682 | |
| 683 | // TODO(adg): remove this seek and the offset check once confident |
| 684 | offset, err := s.writer.Seek(0, io.SeekCurrent) |
| 685 | if err != nil { |
| 686 | return err |
| 687 | } |
| 688 | if offset != s.size { |
| 689 | return fmt.Errorf("diskpacked: seek says offset = %d, we think %d", |
| 690 | offset, s.size) |
| 691 | } |
| 692 | offset = s.size // make this a declaration once the above is removed |
| 693 | |
| 694 | n2, err := io.Copy(s.writer, r) |
| 695 | s.size += n2 |
| 696 | writeVar.Add(fn, int64(n)) |
| 697 | writeTotVar.Add(s.root, int64(n)) |
| 698 | if err != nil { |
| 699 | return err |
| 700 | } |
| 701 | if n2 != int64(br.Size) { |
| 702 | return fmt.Errorf("diskpacked: written blob size %d didn't match size %d", n, br.Size) |
| 703 | } |
| 704 | if err = s.writer.Sync(); err != nil { |
| 705 | return err |
| 706 | } |
| 707 | |
| 708 | packIdx := len(s.fds) - 1 |
| 709 | if s.size > s.maxFileSize { |
| 710 | if err := s.nextPack(); err != nil { |
| 711 | return err |
| 712 | } |
| 713 | } |
| 714 | err = s.index.Set(br.Ref.String(), blobMeta{packIdx, offset, br.Size}.String()) |
| 715 | if err != nil { |
| 716 | if _, seekErr := s.writer.Seek(origOffset, io.SeekStart); seekErr != nil { |
| 717 | log.Printf("ERROR seeking back to the original offset: %v", seekErr) |
| 718 | } else if truncErr := s.writer.Truncate(origOffset); truncErr != nil { |
| 719 | log.Printf("ERROR truncating file after index error: %v", truncErr) |
| 720 | } else { |
| 721 | s.size = origOffset |
no test coverage detected