summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/RoaringBitmap/roaring/serialization_generic.go
blob: 7fcef7691b9fcb3426cab1228df1faaba4f39200 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// +build !amd64,!386 appengine

package roaring

import (
	"encoding/binary"
	"io"
)

func (b *arrayContainer) writeTo(stream io.Writer) (int, error) {
	buf := make([]byte, 2*len(b.content))
	for i, v := range b.content {
		base := i * 2
		buf[base] = byte(v)
		buf[base+1] = byte(v >> 8)
	}
	return stream.Write(buf)
}

func (b *arrayContainer) readFrom(stream io.Reader) (int, error) {
	err := binary.Read(stream, binary.LittleEndian, b.content)
	if err != nil {
		return 0, err
	}
	return 2 * len(b.content), nil
}

func (b *bitmapContainer) writeTo(stream io.Writer) (int, error) {
	// Write set
	buf := make([]byte, 8*len(b.bitmap))
	for i, v := range b.bitmap {
		base := i * 8
		buf[base] = byte(v)
		buf[base+1] = byte(v >> 8)
		buf[base+2] = byte(v >> 16)
		buf[base+3] = byte(v >> 24)
		buf[base+4] = byte(v >> 32)
		buf[base+5] = byte(v >> 40)
		buf[base+6] = byte(v >> 48)
		buf[base+7] = byte(v >> 56)
	}
	return stream.Write(buf)
}

func (b *bitmapContainer) readFrom(stream io.Reader) (int, error) {
	err := binary.Read(stream, binary.LittleEndian, b.bitmap)
	if err != nil {
		return 0, err
	}
	b.computeCardinality()
	return 8 * len(b.bitmap), nil
}

func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
	by := make([]byte, len(bc.bitmap)*8)
	for i := range bc.bitmap {
		binary.LittleEndian.PutUint64(by[i*8:], bc.bitmap[i])
	}
	return by
}

func uint64SliceAsByteSlice(slice []uint64) []byte {
	by := make([]byte, len(slice)*8)

	for i, v := range slice {
		binary.LittleEndian.PutUint64(by[i*8:], v)
	}

	return by
}

func byteSliceAsUint16Slice(slice []byte) []uint16 {
	if len(slice)%2 != 0 {
		panic("Slice size should be divisible by 2")
	}

	b := make([]uint16, len(slice)/2)

	for i := range b {
		b[i] = binary.LittleEndian.Uint16(slice[2*i:])
	}

	return b
}

func byteSliceAsUint64Slice(slice []byte) []uint64 {
	if len(slice)%8 != 0 {
		panic("Slice size should be divisible by 8")
	}

	b := make([]uint64, len(slice)/8)

	for i := range b {
		b[i] = binary.LittleEndian.Uint64(slice[8*i:])
	}

	return b
}

// Converts a byte slice to a interval16 slice.
// The function assumes that the slice byte buffer is run container data
// encoded according to Roaring Format Spec
func byteSliceAsInterval16Slice(byteSlice []byte) []interval16 {
	if len(byteSlice)%4 != 0 {
		panic("Slice size should be divisible by 4")
	}

	intervalSlice := make([]interval16, len(byteSlice)/4)

	for i := range intervalSlice {
		intervalSlice[i] = interval16{
			start:  binary.LittleEndian.Uint16(byteSlice[i*4:]),
			length: binary.LittleEndian.Uint16(byteSlice[i*4+2:]),
		}
	}

	return intervalSlice
}