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 }