summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go')
-rw-r--r--vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go b/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
new file mode 100644
index 0000000000..c1d3ad3046
--- /dev/null
+++ b/vendor/github.com/RoaringBitmap/roaring/serialization_littleendian.go
@@ -0,0 +1,113 @@
+// +build 386 amd64,!appengine
+
+package roaring
+
+import (
+ "io"
+ "reflect"
+ "unsafe"
+)
+
+func (ac *arrayContainer) writeTo(stream io.Writer) (int, error) {
+ buf := uint16SliceAsByteSlice(ac.content)
+ return stream.Write(buf)
+}
+
+func (bc *bitmapContainer) writeTo(stream io.Writer) (int, error) {
+ buf := uint64SliceAsByteSlice(bc.bitmap)
+ return stream.Write(buf)
+}
+
+// readFrom reads an arrayContainer from stream.
+// PRE-REQUISITE: you must size the arrayContainer correctly (allocate b.content)
+// *before* you call readFrom. We can't guess the size in the stream
+// by this point.
+func (ac *arrayContainer) readFrom(stream io.Reader) (int, error) {
+ buf := uint16SliceAsByteSlice(ac.content)
+ return io.ReadFull(stream, buf)
+}
+
+func (bc *bitmapContainer) readFrom(stream io.Reader) (int, error) {
+ buf := uint64SliceAsByteSlice(bc.bitmap)
+ n, err := io.ReadFull(stream, buf)
+ bc.computeCardinality()
+ return n, err
+}
+
+func uint64SliceAsByteSlice(slice []uint64) []byte {
+ // make a new slice header
+ header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
+
+ // update its capacity and length
+ header.Len *= 8
+ header.Cap *= 8
+
+ // return it
+ return *(*[]byte)(unsafe.Pointer(&header))
+}
+
+func uint16SliceAsByteSlice(slice []uint16) []byte {
+ // make a new slice header
+ header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
+
+ // update its capacity and length
+ header.Len *= 2
+ header.Cap *= 2
+
+ // return it
+ return *(*[]byte)(unsafe.Pointer(&header))
+}
+
+func (bc *bitmapContainer) asLittleEndianByteSlice() []byte {
+ return uint64SliceAsByteSlice(bc.bitmap)
+}
+
+// Deserialization code follows
+
+func byteSliceAsUint16Slice(slice []byte) []uint16 {
+ if len(slice)%2 != 0 {
+ panic("Slice size should be divisible by 2")
+ }
+
+ // make a new slice header
+ header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
+
+ // update its capacity and length
+ header.Len /= 2
+ header.Cap /= 2
+
+ // return it
+ return *(*[]uint16)(unsafe.Pointer(&header))
+}
+
+func byteSliceAsUint64Slice(slice []byte) []uint64 {
+ if len(slice)%8 != 0 {
+ panic("Slice size should be divisible by 8")
+ }
+
+ // make a new slice header
+ header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
+
+ // update its capacity and length
+ header.Len /= 8
+ header.Cap /= 8
+
+ // return it
+ return *(*[]uint64)(unsafe.Pointer(&header))
+}
+
+func byteSliceAsInterval16Slice(slice []byte) []interval16 {
+ if len(slice)%4 != 0 {
+ panic("Slice size should be divisible by 4")
+ }
+
+ // make a new slice header
+ header := *(*reflect.SliceHeader)(unsafe.Pointer(&slice))
+
+ // update its capacity and length
+ header.Len /= 4
+ header.Cap /= 4
+
+ // return it
+ return *(*[]interval16)(unsafe.Pointer(&header))
+}