Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 67E4A200D35 for ; Tue, 7 Nov 2017 09:25:41 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 664E1160BED; Tue, 7 Nov 2017 08:25:41 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 5D0451609C8 for ; Tue, 7 Nov 2017 09:25:40 +0100 (CET) Received: (qmail 50947 invoked by uid 500); 7 Nov 2017 08:25:39 -0000 Mailing-List: contact dev-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list dev@ignite.apache.org Received: (qmail 50935 invoked by uid 99); 7 Nov 2017 08:25:39 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Nov 2017 08:25:39 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 624CB1A0BD4 for ; Tue, 7 Nov 2017 08:25:38 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 2.479 X-Spam-Level: ** X-Spam-Status: No, score=2.479 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=2, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SORBS_SPAM=0.5, SPF_PASS=-0.001] autolearn=disabled Authentication-Results: spamd2-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gridgain-com.20150623.gappssmtp.com Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id nsUoakOhmHq7 for ; Tue, 7 Nov 2017 08:25:35 +0000 (UTC) Received: from mail-ua0-f169.google.com (mail-ua0-f169.google.com [209.85.217.169]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTPS id B64545F2AD for ; Tue, 7 Nov 2017 08:25:34 +0000 (UTC) Received: by mail-ua0-f169.google.com with SMTP id 65so1101445uaq.8 for ; Tue, 07 Nov 2017 00:25:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gridgain-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=KVnpO3r8miNSGk1aYhMsMCrACBi6hsGeedfQ7KG1Ung=; b=NoB+Jz/Il//SS+Pj9QwUUnSz2dku59RpkKL10MdPNFifZzo1ZYJJH62iouWkSRU5ye UJCpGmGH1FfzzA18P2GbC7fpYnuG0HSYt230IkbW/svPFPAVx6B05Qr5eYGlXGv2oXBK x4zGwBI2l4QAjNEOoMD2IwYlBBFu3OR6Ll8zxU/sFY5l5UPsdCfZ62bxdooZ0+pY44jp IBrHoa9vpT0LaXIVYDS2IaIn2bKoM97aZ942vW60rA59tmT6uaRo2qBy2UQf09lmEHxM weE7Xu4Do02AYOFqSFGpv476IHnl/qy1A2lFD3i6eC0JTBMuWixJhTNIiEgv4QXfH+Gq oqxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=KVnpO3r8miNSGk1aYhMsMCrACBi6hsGeedfQ7KG1Ung=; b=kmN2Ugg3JTVEEUnqWK+c4Rz8jJswVgdXye8nPZ2XhqaowIgF/cxg2gaFVONRUVqRDM 7H58m7E8jj1qEqp8CqnhsZ1WS582z4sjdbEAeKkiamk3MYXNc0lXh6w/RNxhgrDBZ62w ik4UmKmbN8KlkfEYVLAIQoH0VsSDFeypLuOcMtv1P3FforZ+IT8yNRfI9GAyubZm6aU/ qvQrereXXKRp4J4S9KR2lTgFere7kcBJPDHkYVrnF8rJ3xl4+GHwz4NPvrJe7JWKt+AR w9bBLPBmHgasriWFngq5wIDiWJ+b7vus5P80xnz2ldHIHTZowSdTX9FOFLo4IkHJcgnV yi9w== X-Gm-Message-State: AMCzsaWtrYHORQDDycGulTJrLWGPusrQ/gp4Tct/VVN/qQcC324DnZ3M 0sLmIoGlCswaVXx36cs2HnBXalwj2fkMXk26THe0D/kG X-Google-Smtp-Source: ABhQp+SQuIcCEU7N4L7VCGG8xPZfrzqewBtrSJFSZaoPWPOBDuDD46g+PiqW+4rC7gUB1rqM1c56F3V4AIreLYC0KcU= X-Received: by 10.159.59.219 with SMTP id y27mr14079353uah.199.1510043133905; Tue, 07 Nov 2017 00:25:33 -0800 (PST) MIME-Version: 1.0 Received: by 10.176.68.225 with HTTP; Tue, 7 Nov 2017 00:25:33 -0800 (PST) In-Reply-To: References: From: Vladimir Ozerov Date: Tue, 7 Nov 2017 11:25:33 +0300 Message-ID: Subject: Re: Deserialization of BinaryObject's byte arrays To: dev@ignite.apache.org Content-Type: multipart/alternative; boundary="f403045e854697a262055d605040" archived-at: Tue, 07 Nov 2017 08:25:41 -0000 --f403045e854697a262055d605040 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Regarding "sefl-imposed rules": 1) Binary protocol is essentially ignite's type system. It is used in many places: Java, .NET, CPP, SQL (native, JDBC, ODBC), thin client. Of those 5 parties only Java has "ByteBuffer" concept. How other platforms should work with this type? 2) We compare objects using binary representation (BinaryArrayIdentityResolver#equals0). So if one user write data as byte array, and another write the same data as ByteBuffer, resulting objects will not be equal These are clear examples on why type system should be as small as possible - we simply cannot afford extending type system for every minor use case. Binary protocol is internal thing and has nothing to do with user experience. What is worse, ByteBuffer is terrible abstraction as recognized by many millions of Java users - it is stateful. One cannot read data from it without changing it's state. And Ignite gives no guarantees that particular object will be serialized only once per certain operation. One example is BinaryMetadataCollector - Ignite could go through object twice per serialization cycle to collect metadata. How are we going to maintain idempotence in general case? What could improve UX is public interfaces. Raw example of what we can do: 1) Define generic wrappers over our streams that will give users ability to read/write byte arrays as they want. E.g.: interface BinaryArrayWriter { write(byte[] src, int offset, int len); write(ByteBuffer src, ...); } interface BinaryArrayReader { int readLength(); byte[] read(); void read(byte[] dest, int off, int len); void read(ByteBuffer dest); } 2) Then add new methods to reader/writer/builder. E.g.: BinaryWriter.writeByteArray(String name, BiConsumer consumer); // Consumes original field and array writer; BinaryReader.readByteArray(String name, Function consumer); // Takes array reader, produces original field 3) Last, introduce field annotation for user convenience: class MyClass { @BinaryArray(writerClass =3D MyWriterBiConsumer.class, readerClass =3D MyReaderFunction.class) private ByteBuffer buf; } Now all user need to do is to implement write consumer and read function. Vladimir. On Tue, Nov 7, 2017 at 10:16 AM, Vladimir Ozerov wrote: > ByteBuffer is not fundamental data type. It is a thin wrapper over array. > Protocol should contain only fundamental types. > > =D0=B2=D1=82, 7 =D0=BD=D0=BE=D1=8F=D0=B1. 2017 =D0=B3. =D0=B2 10:05, Andr= ey Kornev : > >> Vladimir, >> >> Could you please elaborate as to why adding ByteBuffer to the Binary >> protocol is =E2=80=9Cnot a good idea=E2=80=9D? What is inherently wrong = about it? >> >> As for your suggestion, while I certainly see your point, it comes with >> the inconvenience of implementing Binarylizable for every entity type in= an >> application, which makes me wonder if the self imposed rules such as =E2= =80=9Ctype >> system should be kept as small as possible=E2=80=9D could be relaxed in = the name of >> greater good and user friendliness. Ignite API is not easy to grok as it= is >> already. >> >> Thanks >> Andrey >> _____________________________ >> From: Vladimir Ozerov = > >> Sent: Monday, November 6, 2017 10:22 PM >> Subject: Re: Deserialization of BinaryObject's byte arrays >> To: > >> Cc: Valentin Kulichenko > valentin.kulichenko@gmail.com>> >> >> >> Hi Andrey, >> >> While we deifnitely need to support byte buffers, adding new type to >> protocol is not very good idea. Binary protocol is the heart of our >> ssytem, >> which is used not oly for plain Java, but for other platforms and SQL. A= nd >> ByteBuffer is essentially the same byte array, but with different API. >> What >> you describe is a special case of byte array read/write. For this reason >> our type system should be kept as small as possible and it doesn't requi= re >> new type to be introduced. Instead, we'd better to handle everything on >> API >> level only. For example, we can add new methods to reader/writer/builder= , >> which will handle this. E.g.: >> >> BinaryWriter.writeByteArray(); >> BinaryReader.readByteArray(); >> >> Vladimir. >> >> On Mon, Nov 6, 2017 at 9:25 PM, Andrey Kornev > mailto:andrewkornev@hotmail.com>> >> wrote: >> >> > Will do! Thanks! >> > ________________________________ >> > From: Valentin Kulichenko > valentin.kulichenko@gmail.com>> >> > Sent: Monday, November 6, 2017 9:17 AM >> > To: dev@ignite.apache.org >> > Subject: Re: Deserialization of BinaryObject's byte arrays >> > >> > This use case was discussed couple of times already, so it seems to be >> > pretty important for users. And I like the approach suggested by Andre= y. >> > >> > Andrey, can you create a Jira ticket for this change? Would you like t= o >> > contribute it? >> > >> > -Val >> > >> > On Fri, Nov 3, 2017 at 4:18 PM, Dmitriy Setrakyan < >> dsetrakyan@apache.org> >> > wrote: >> > >> > > This makes sense to me. Sounds like a useful feature. >> > > >> > > Would be nice to hear what others in the community think? >> > > >> > > D. >> > > >> > > On Fri, Nov 3, 2017 at 1:07 PM, Andrey Kornev < >> andrewkornev@hotmail.com> >> > > wrote: >> > > >> > > > Hello, >> > > > >> > > > We store lots of byte arrays (serialized graph-like data >> structures) as >> > > > fields of BinaryObject. Later on, while reading such field, >> > > > BinaryInputStream implementation creates an on-heap array and copi= es >> > the >> > > > bytes from the BinaryObject's internal backing array to the new >> array. >> > > > >> > > > While in general case it works just fine, in our case, a lot of CP= U >> is >> > > > spent on copying of the bytes and significant amount garbage is >> > generated >> > > > as well. >> > > > >> > > > I'd like Ignite Community to consider the following proposal: >> introduce >> > > > support for serialization/deserialization of the ByteBuffer class.= A >> > > > BinaryInputStream implementation would special case ByteBuffer >> fields >> > > same >> > > > way it currently special cases various Java types (collections, >> dates, >> > > > timestamps, enums, etc.) >> > > > >> > > > The application developer would simply call >> > > BinaryObjectBuilder.setField(...) >> > > > passing in an instance of ByteBuffer. During serialization, the >> > > > ByteBuffer's bytes would simply be copied to the backing array >> (similar >> > > to >> > > > how regular byte arrays are serialized today) and in the binary >> > object's >> > > > metadata the field marked as, say, GridBinaryMarshaller.BYTE_ >> BUFFER. >> > > > >> > > > During deserialization of the field, instead of allocating a new >> byte >> > > > array and transferring the bytes from the BinaryObject's backing >> array, >> > > > BinaryInputStream would simply wrap the required sub-array into a >> > > read-only >> > > > instance of ByteBuffer using "public static ByteBuffer wrap(byte[] >> > array, >> > > > int offset, int length)" and return the instance to the applicatio= n. >> > > > >> > > > This approach doesn't require any array allocation/data copying an= d >> is >> > > > faster and significantly reduces pressure on the garbage collector= . >> The >> > > > benefits are especially great when application stores significant >> > amount >> > > of >> > > > its data as byte arrays. >> > > > >> > > > Clearly, this approach equally applies to arrays of other primitiv= e >> > > types. >> > > > >> > > > A minor complication does arise when dealing with off-heap >> > BinaryObjects, >> > > > but nothing that can't solved with a little bit of Java reflection >> > > wizardry >> > > > (or by other means). >> > > > >> > > > Thanks, >> > > > Andrey >> > > > >> > > >> > >> >> >> --f403045e854697a262055d605040--