roaring icon indicating copy to clipboard operation
roaring copied to clipboard

Support for json encoding

Open AshKash opened this issue 7 years ago • 11 comments

When *roaring.Bitmap is part of a struct that is serialized to JSON, it is empty {} and everything silently fails. Could this patch be included:

@@ -9,6 +9,7 @@ import (
 	"bufio"
 	"bytes"
 	"encoding/base64"
+	"encoding/json"
 	"fmt"
 	"io"
 	"strconv"
@@ -124,6 +125,14 @@ func (rb *Bitmap) MarshalBinary() ([]byte, error) {
 	return buf.Bytes(), nil
 }
 
+func (rb *Bitmap) MarshalJSON() ([]byte, error) {
+	b, err := rb.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	return json.Marshal(b)
+}
+
 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for the bitmap
 func (rb *Bitmap) UnmarshalBinary(data []byte) error {
 	var buf bytes.Buffer
@@ -136,6 +145,15 @@ func (rb *Bitmap) UnmarshalBinary(data []byte) error {
 	return err
 }
 
+func (rb *Bitmap) UnmarshalJSON(data []byte) error {
+	var b []byte
+	err := json.Unmarshal(data, &b)
+	if err != nil {
+		return err
+	}
+	return rb.UnmarshalBinary(b)
+}
+
 // NewBitmap creates a new empty Bitmap (see also New)
 func NewBitmap() *Bitmap {
 	return &Bitmap{}

AshKash avatar Sep 01 '18 04:09 AshKash

Help needed to review this.

cc @maciej and others.

lemire avatar Sep 01 '18 06:09 lemire

@AshKash what would be the serialisation format? Would the bitmap be serialised to a JSON Array of numbers?

maciej avatar Sep 11 '18 13:09 maciej

@maciej Go's JSON encoder serializes []byte to base64 encoded strings. This should be identical to calling rb.ToBas64() and encoding as string. This should be more compact than storing array of ints.

AshKash avatar Sep 11 '18 18:09 AshKash

It does not look harmful. I honestly did not know about the Go JSON encoder, but it looks sensible.

Can you create a pull request or do you want us to apply the patch...? We will need some tests.

lemire avatar Sep 11 '18 19:09 lemire

I agree. If that's what users would expect – I'm in favour.

maciej avatar Sep 12 '18 19:09 maciej

Ok... waiting for the pull request.

lemire avatar Sep 12 '18 21:09 lemire

Opened PR #205

AshKash avatar Sep 13 '18 16:09 AshKash

It does not look harmful. I honestly did not know about the Go JSON encoder, but it looks sensible.

Can you create a pull request or do you want us to apply the patch...? We will need some tests.

i need this support,because i need to serialize bitmap to save it in redis

abusizhishen avatar Jun 04 '19 12:06 abusizhishen

@abusizhishen Do you want to help out with the PR? The code has been written, but we won't merge it until someone has written tests for it.

Regarding Redis, there is a Roaring module for it... https://github.com/aviggiano/redis-roaring

lemire avatar Jun 04 '19 19:06 lemire

@abusizhishen you can use any of the existing serialisation: the default binary format (with https://godoc.org/github.com/RoaringBitmap/roaring#Bitmap.ToBytes) or base64 (https://godoc.org/github.com/RoaringBitmap/roaring#Bitmap.ToBase64). Redis accepts binary data.

maciej avatar Jun 05 '19 11:06 maciej

To add to what @maciej wrote, performance is going to be better if you ingest binary data. Going through JSON is almost surely slower.

(Though you can parse JSON very quickly, I doubt that Redis uses such optimizations.)

lemire avatar Jun 05 '19 13:06 lemire