Read reads the segement r, uncompresses it if necessary, and stores it in the first s.MemLength bytes of b. If the length of b is less than s.MemLength, Read returns [io.ErrShortBuffer].
(r io.ReaderAt, b []byte)
| 30 | // first s.MemLength bytes of b. If the length of b is less than s.MemLength, |
| 31 | // Read returns [io.ErrShortBuffer]. |
| 32 | func (s *Segment) Read(r io.ReaderAt, b []byte) error { |
| 33 | if s.Length == 0 { |
| 34 | return nil |
| 35 | } |
| 36 | if len(b) < int(s.MemLength) { |
| 37 | return fmt.Errorf("csup: segment read: %w", io.ErrShortBuffer) |
| 38 | } |
| 39 | b = b[:s.MemLength] |
| 40 | switch s.CompressionFormat { |
| 41 | case CompressionFormatNone: |
| 42 | _, err := r.ReadAt(b, int64(s.Offset)) |
| 43 | return err |
| 44 | case CompressionFormatLZ4: |
| 45 | zbuf := zbufPool.Get().(*[]byte) |
| 46 | defer zbufPool.Put(zbuf) |
| 47 | *zbuf = slices.Grow((*zbuf)[:0], int(s.Length))[:s.Length] |
| 48 | if _, err := r.ReadAt(*zbuf, int64(s.Offset)); err != nil { |
| 49 | return err |
| 50 | } |
| 51 | n, err := lz4.UncompressBlock(*zbuf, b) |
| 52 | if err != nil { |
| 53 | return err |
| 54 | } |
| 55 | if n != int(s.MemLength) { |
| 56 | return fmt.Errorf("csup: got %d uncompressed bytes, expected %d", n, s.MemLength) |
| 57 | } |
| 58 | return nil |
| 59 | default: |
| 60 | return fmt.Errorf("csup: unknown compression format 0x%x", s.CompressionFormat) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | // XXX for now we always compress, we should add a config option to |
| 65 | // avoid compression when local storage is fast compared to compute |