You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
2.9 KiB

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