I did just manage to use BinarySerializer and registered it as a custom 
serializer, it seems to work pending some more tests. Again, curious to hear if 
this approach is appropriate for the use case. Here's the Clojure version:

(defn roaring-serializer []
  (reify BinarySerializer
    (writeBinary [this o binaryWriter]
      ; o contains our object.
      (let [byte-stream (ByteArrayOutputStream.)]
        (with-open [out-stream (DataOutputStream. byte-stream)]
          (.serialize ^RoaringBitmap o out-stream))
        (.writeByteArray binaryWriter "val" (.toByteArray byte-stream))))

    (readBinary [this o binaryReader]
      ; o contains an empty object
      (let [raw-bytes (.readByteArray binaryReader "val")
            byte-stream (ByteArrayInputStream. raw-bytes)]
        (with-open [in-stream (DataInputStream. byte-stream)]
          (.deserialize ^RoaringBitmap o in-stream))))))




> On Mar 15, 2017, at 10:34 AM, Luke Burton <[email protected]> wrote:
> 
> 
> Hi there,
> 
> I'm storing RoaringBitmaps in Ignite and have encountered an odd 
> serialization issue. Please forgive the samples below being in Clojure, I've 
> written a small wrapper around most Ignite APIs that I can use. I think you 
> can catch the gist of what I'm doing, I hope :)
> 
> (let [inst (i/instance "attribute_bitmaps")
>        bmp (doto (RoaringBitmap.)
>              (.add 9999999))
>        srz (fn [it]
>              (let [b (ByteArrayOutputStream.)]
>                (with-open [o (DataOutputStream. b)]
>                  (.serialize it o))
>                (.toByteArray b)))]
> 
>    (doto inst
>      (i/clear)
>      (i/put "test" bmp))
> 
>    (byte-streams/print-bytes (srz bmp))
>    (byte-streams/print-bytes (srz (i/get inst "test"))))
> 
> Here I'm just creating a bitmap and storing it in a cache. I'm then just 
> printing the bytes of the thing I stored, as well as what it looks like 
> coming back out of Ignite.
> 
> I get the following warning in the logs:
> 
> 10:16:45.730 [djura.local ~ nREPL-worker-3 ~ 
> o.a.i.internal.binary.BinaryContext] Class "org.roaringbitmap.RoaringBitmap" 
> cannot be serialized using BinaryMarshaller because it either implements 
> Externalizable interface or have writeObject/readObject methods. 
> OptimizedMarshaller will be used instead and class instances will be 
> deserialized on the server. Please ensure that all nodes have this class in 
> classpath. To enable binary serialization either implement Binarylizable 
> interface or set explicit serializer using 
> BinaryTypeConfiguration.setSerializer() method. 
> 
> And really strangely, I get the same number of bytes back but some of them at 
> the end have been zero'd out (first one is correct, second one went through 
> Ignite):
> 
> 3A 30 00 00 01 00 00 00  98 00 00 00 10 00 00 00      .0..............
> 7F 96                                                  ..
> 3A 30 00 00 01 00 00 00  98 00 00 00 10 00 00 00      .0..............
> 00 00                                                  ..
> 
> The resulting object is still a valid RoaringBitmap, except all the values in 
> the bitmap are wrong! 
> 
> I'm guessing from this and the logs, that OptimizedMarshaller is being used 
> instead of BinaryMarshaller, and OptimizedMarshaller is not copying the 
> internal fields of the class correctly.
> 
> Would the recommended approach here be to create a custom class that extends 
> RoaringBitmap and implements Binarylizable? I'm not sure if Binarylizable is 
> a suitable approach for this situation where I don't control the source for 
> the class in question. I have no knowledge of the internal fields of this 
> class and really just want to ensure it survives the roundtrip through Ignite 
> by using its own internal serialization mechanism.
> 
> Luke.
> 

Reply via email to