github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/encoding/bytestreamsplit/bytestreamsplit.go (about)

     1  package bytestreamsplit
     2  
     3  import (
     4  	"github.com/segmentio/parquet-go/encoding"
     5  	"github.com/segmentio/parquet-go/format"
     6  	"github.com/segmentio/parquet-go/internal/unsafecast"
     7  )
     8  
     9  // This encoder implements a version of the Byte Stream Split encoding as described
    10  // in https://github.com/apache/parquet-format/blob/master/Encodings.md#byte-stream-split-byte_stream_split--9
    11  type Encoding struct {
    12  	encoding.NotSupported
    13  }
    14  
    15  func (e *Encoding) String() string {
    16  	return "BYTE_STREAM_SPLIT"
    17  }
    18  
    19  func (e *Encoding) Encoding() format.Encoding {
    20  	return format.ByteStreamSplit
    21  }
    22  
    23  func (e *Encoding) EncodeFloat(dst []byte, src []float32) ([]byte, error) {
    24  	dst = resize(dst, 4*len(src))
    25  	encodeFloat(dst, unsafecast.Float32ToBytes(src))
    26  	return dst, nil
    27  }
    28  
    29  func (e *Encoding) EncodeDouble(dst []byte, src []float64) ([]byte, error) {
    30  	dst = resize(dst, 8*len(src))
    31  	encodeDouble(dst, unsafecast.Float64ToBytes(src))
    32  	return dst, nil
    33  }
    34  
    35  func (e *Encoding) DecodeFloat(dst []float32, src []byte) ([]float32, error) {
    36  	if (len(src) % 4) != 0 {
    37  		return dst, encoding.ErrDecodeInvalidInputSize(e, "FLOAT", len(src))
    38  	}
    39  	buf := resize(unsafecast.Float32ToBytes(dst), len(src))
    40  	decodeFloat(buf, src)
    41  	return unsafecast.BytesToFloat32(buf), nil
    42  }
    43  
    44  func (e *Encoding) DecodeDouble(dst []float64, src []byte) ([]float64, error) {
    45  	if (len(src) % 8) != 0 {
    46  		return dst, encoding.ErrDecodeInvalidInputSize(e, "DOUBLE", len(src))
    47  	}
    48  	buf := resize(unsafecast.Float64ToBytes(dst), len(src))
    49  	decodeDouble(buf, src)
    50  	return unsafecast.BytesToFloat64(buf), nil
    51  }
    52  
    53  func resize(buf []byte, size int) []byte {
    54  	if cap(buf) < size {
    55  		buf = make([]byte, size, 2*size)
    56  	} else {
    57  		buf = buf[:size]
    58  	}
    59  	return buf
    60  }