github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/roaring/serialization_generic.go (about)

     1  //go:build (!amd64 && !386 && !arm && !arm64 && !ppc64le && !mipsle && !mips64le && !mips64p32le && !wasm) || appengine
     2  // +build !amd64,!386,!arm,!arm64,!ppc64le,!mipsle,!mips64le,!mips64p32le,!wasm appengine
     3  
     4  package roaring
     5  
     6  import (
     7  	"encoding/binary"
     8  	"errors"
     9  	"io"
    10  )
    11  
    12  func (b *arrayContainer) writeTo(stream io.Writer) (int, error) {
    13  	buf := make([]byte, 2*len(b.content))
    14  	for i, v := range b.content {
    15  		base := i * 2
    16  		buf[base] = byte(v)
    17  		buf[base+1] = byte(v >> 8)
    18  	}
    19  	return stream.Write(buf)
    20  }
    21  
    22  func (b *arrayContainer) readFrom(stream io.Reader) (int, error) {
    23  	err := binary.Read(stream, binary.LittleEndian, b.content)
    24  	if err != nil {
    25  		return 0, err
    26  	}
    27  	return 2 * len(b.content), nil
    28  }
    29  
    30  func (b *bitmapContainer) writeTo(stream io.Writer) (int, error) {
    31  	if b.cardinality <= arrayDefaultMaxSize {
    32  		return 0, errors.New("refusing to write bitmap container with cardinality of array container")
    33  	}
    34  
    35  	// Write set
    36  	buf := make([]byte, 8*len(b.bitmap))
    37  	for i, v := range b.bitmap {
    38  		base := i * 8
    39  		buf[base] = byte(v)
    40  		buf[base+1] = byte(v >> 8)
    41  		buf[base+2] = byte(v >> 16)
    42  		buf[base+3] = byte(v >> 24)
    43  		buf[base+4] = byte(v >> 32)
    44  		buf[base+5] = byte(v >> 40)
    45  		buf[base+6] = byte(v >> 48)
    46  		buf[base+7] = byte(v >> 56)
    47  	}
    48  	return stream.Write(buf)
    49  }
    50  
    51  func (b *bitmapContainer) readFrom(stream io.Reader) (int, error) {
    52  	err := binary.Read(stream, binary.LittleEndian, b.bitmap)
    53  	if err != nil {
    54  		return 0, err
    55  	}
    56  	b.computeCardinality()
    57  	return 8 * len(b.bitmap), nil
    58  }
    59  
    60  func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
    61  	by := make([]byte, len(bc.bitmap)*8)
    62  	for i := range bc.bitmap {
    63  		binary.LittleEndian.PutUint64(by[i*8:], bc.bitmap[i])
    64  	}
    65  	return by
    66  }
    67  
    68  func uint64SliceAsByteSlice(slice []uint64) []byte {
    69  	by := make([]byte, len(slice)*8)
    70  
    71  	for i, v := range slice {
    72  		binary.LittleEndian.PutUint64(by[i*8:], v)
    73  	}
    74  
    75  	return by
    76  }
    77  
    78  func uint16SliceAsByteSlice(slice []uint16) []byte {
    79  	by := make([]byte, len(slice)*2)
    80  
    81  	for i, v := range slice {
    82  		binary.LittleEndian.PutUint16(by[i*2:], v)
    83  	}
    84  
    85  	return by
    86  }
    87  
    88  func interval16SliceAsByteSlice(slice []interval16) []byte {
    89  	by := make([]byte, len(slice)*4)
    90  
    91  	for i, v := range slice {
    92  		binary.LittleEndian.PutUint16(by[i*2:], v.start)
    93  		binary.LittleEndian.PutUint16(by[i*2+2:], v.length)
    94  	}
    95  
    96  	return by
    97  }
    98  
    99  func byteSliceAsUint16Slice(slice []byte) []uint16 {
   100  	if len(slice)%2 != 0 {
   101  		panic("Slice size should be divisible by 2")
   102  	}
   103  
   104  	b := make([]uint16, len(slice)/2)
   105  
   106  	for i := range b {
   107  		b[i] = binary.LittleEndian.Uint16(slice[2*i:])
   108  	}
   109  
   110  	return b
   111  }
   112  
   113  func byteSliceAsUint64Slice(slice []byte) []uint64 {
   114  	if len(slice)%8 != 0 {
   115  		panic("Slice size should be divisible by 8")
   116  	}
   117  
   118  	b := make([]uint64, len(slice)/8)
   119  
   120  	for i := range b {
   121  		b[i] = binary.LittleEndian.Uint64(slice[8*i:])
   122  	}
   123  
   124  	return b
   125  }
   126  
   127  // Converts a byte slice to a interval16 slice.
   128  // The function assumes that the slice byte buffer is run container data
   129  // encoded according to Roaring Format Spec
   130  func byteSliceAsInterval16Slice(byteSlice []byte) []interval16 {
   131  	if len(byteSlice)%4 != 0 {
   132  		panic("Slice size should be divisible by 4")
   133  	}
   134  
   135  	intervalSlice := make([]interval16, len(byteSlice)/4)
   136  
   137  	for i := range intervalSlice {
   138  		intervalSlice[i] = interval16{
   139  			start:  binary.LittleEndian.Uint16(byteSlice[i*4:]),
   140  			length: binary.LittleEndian.Uint16(byteSlice[i*4+2:]),
   141  		}
   142  	}
   143  
   144  	return intervalSlice
   145  }