serialization_generic.go 3.3 KB

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