storj.io/uplink@v1.13.0/private/eestream/unsafe_rs.go (about) 1 // Copyright (C) 2019 Storj Labs, Inc. 2 // See LICENSE for copying information. 3 4 package eestream 5 6 import ( 7 "storj.io/common/sync2/race2" 8 "storj.io/infectious" 9 ) 10 11 type unsafeRSScheme struct { 12 fc *infectious.FEC 13 erasureShareSize int 14 } 15 16 // NewUnsafeRSScheme returns a Reed-Solomon-based ErasureScheme without error correction. 17 func NewUnsafeRSScheme(fc *infectious.FEC, erasureShareSize int) ErasureScheme { 18 return &unsafeRSScheme{fc: fc, erasureShareSize: erasureShareSize} 19 } 20 21 func (s *unsafeRSScheme) EncodeSingle(input, output []byte, num int) (err error) { 22 return s.fc.EncodeSingle(input, output, num) 23 } 24 25 func (s *unsafeRSScheme) Encode(input []byte, output func(num int, data []byte)) ( 26 err error) { 27 return s.fc.Encode(input, func(s infectious.Share) { 28 output(s.Number, s.Data) 29 }) 30 } 31 32 func (s *unsafeRSScheme) Decode(out []byte, in []infectious.Share) ([]byte, error) { 33 for _, share := range in { 34 race2.ReadSlice(share.Data) 35 } 36 37 race2.WriteSlice(out) 38 expectedCap := s.RequiredCount() * s.ErasureShareSize() 39 if cap(out) < expectedCap { 40 out = make([]byte, expectedCap) 41 } else { 42 out = out[:expectedCap] 43 } 44 err := s.fc.Rebuild(in, func(share infectious.Share) { 45 copy(out[share.Number*s.ErasureShareSize():], share.Data) 46 }) 47 if err != nil { 48 return nil, err 49 } 50 51 return out, nil 52 } 53 54 func (s *unsafeRSScheme) Rebuild(in []infectious.Share, out func(infectious.Share)) error { 55 for _, v := range in { 56 race2.ReadSlice(v.Data) 57 } 58 return s.fc.Rebuild(in, out) 59 } 60 61 func (s *unsafeRSScheme) ErasureShareSize() int { 62 return s.erasureShareSize 63 } 64 65 func (s *unsafeRSScheme) StripeSize() int { 66 return s.erasureShareSize * s.fc.Required() 67 } 68 69 func (s *unsafeRSScheme) TotalCount() int { 70 return s.fc.Total() 71 } 72 73 func (s *unsafeRSScheme) RequiredCount() int { 74 return s.fc.Required() 75 }