Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qQsGs-001Fol-Fs for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Aug 2023 16:30:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qQsGq-008GfS-4S for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Aug 2023 16:30:53 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qQsGp-008GfJ-OL for pgsql-hackers@lists.postgresql.org; Tue, 01 Aug 2023 16:30:53 +0000 Received: from mail-lj1-x22d.google.com ([2a00:1450:4864:20::22d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qQsGn-000EQr-UG for pgsql-hackers@postgresql.org; Tue, 01 Aug 2023 16:30:52 +0000 Received: by mail-lj1-x22d.google.com with SMTP id 38308e7fff4ca-2b9fa64db41so13799861fa.1 for ; Tue, 01 Aug 2023 09:30:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1690907449; x=1691512249; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=9gOxxUnzjZtyVIccXyN68vRW7U2uS2wwkER1vc4bQfA=; b=sF0N48txDzJS1wHAdwE35cfcJlYZlw00xkoctXJ5HH6BE2jVQQ8QVrsyUfmvJwGjRK C72UfajzGY+VZKffMe62yMsp1eOe/UyPYl/2du9NQfwjQp1SrfXIuRS9Zt1qZ4Vn0EKI pEUGXGlppv03o4OHmEiXpnki7CMX89r9UdTpKlaxD3jdLcgPCFzS9+xqwjW4n3REtWiB lFbepwnijHCxIT+7rBsgjnE8b/oH7660/98o1+eTHzp3GwALt90O6I30FFESFQDcaCYm P7K91vf9lTwn6NEhkAlh861Mu4WPZ/mICC/3hD62Gk8l+XxQflnwu3VNdIEgpCxKxTAx tbyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690907449; x=1691512249; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9gOxxUnzjZtyVIccXyN68vRW7U2uS2wwkER1vc4bQfA=; b=TB69LnymWVn8NzKZnxnIHEgla9uOyaBzKxxl5enipKsDM5poZxx+A1bE9fumPg7/CL zjgr8MW1J6UGBthvytuK7IT4gxexaOkd2YMDfNe2wEQJ/iUdFRAIlhPlnoXbb06wiO2N p2WB6Aw+PEXJBXtCUrucaxlOeRYvwjDQvoSbzzyavs1pvlR4fvOh8L3TDjUaTJoRHvh+ BhZIltfT9WC/pazHTy4LT4Q+fYFB9xEDOYwjxWEGxdBv+wemFMKzLNdFtjOHtq4GluJS VsTohuVin4dkzeC7JIGZtn6ASwqJOpbRHBBC05sNahIr7NWpBTELI6y9liro5rL2qf0j V6Nw== X-Gm-Message-State: ABy/qLb4ipDX1Hkc7dhULfiQuF9v4r8xGIa17vWkRTHpq+B2Zyld/1SJ VVtTsN5IFrnFwkcdv0+YDw6pSgJI9oDnx6NQ3js= X-Google-Smtp-Source: APBJJlEEfmrCgo2ky7/Dx1wjH2I4VuthYS3HMwMiT30/abxdoIFK+e74/ityzrjKGZcEmlOuimuMY2lS9mWMeyOwd/Y= X-Received: by 2002:a2e:3817:0:b0:2b9:a28d:6495 with SMTP id f23-20020a2e3817000000b002b9a28d6495mr3289149lja.9.1690907448728; Tue, 01 Aug 2023 09:30:48 -0700 (PDT) MIME-Version: 1.0 References: <20230603223824.o7iyochli2dwwi7k@alap3.anarazel.de> In-Reply-To: <20230603223824.o7iyochli2dwwi7k@alap3.anarazel.de> From: Bharath Rupireddy Date: Tue, 1 Aug 2023 22:00:00 +0530 Message-ID: Subject: Re: New Table Access Methods for Multi and Single Inserts To: Andres Freund Cc: Dilip Kumar , Luc Vlaming , Justin Pryzby , PostgreSQL-development , Paul Guo , Jeff Davis , Michael Paquier , Matthias van de Meent Content-Type: multipart/mixed; boundary="000000000000d478c30601df11f9" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000d478c30601df11f9 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Jun 4, 2023 at 4:08=E2=80=AFAM Andres Freund w= rote: > > Hi, > > This patch was referenced in a discussion at pgcon, so I thought I'd give= it a > look, even though Bharat said that he won't have time to drive it forward= ... Thanks. Finally, I started to spend time on this. Just curious - may I know the discussion in/for which this patch is referenced? What was the motive? Is it captured somewhere? > On 2021-04-19 10:21:36 +0530, Bharath Rupireddy wrote: > > + .tuple_insert_begin =3D heap_insert_begin, > > + .tuple_insert_v2 =3D heap_insert_v2, > > + .multi_insert_v2 =3D heap_multi_insert_v2, > > + .multi_insert_flush =3D heap_multi_insert_flush, > > + .tuple_insert_end =3D heap_insert_end, > > I don't think we should have multiple callback for the insertion APIs in > tableam.h. I think it'd be good to continue supporting the old table_*() > functions, but supporting multiple insert APIs in each AM doesn't make mu= ch > sense to me. I named these new functions XXX_v2 for compatibility reasons. Because, it's quite possible for external modules to use existing table_tuple_insert, table_multi_insert functions. If we were to change the existing insert tableams, all the external modules using them would have to change their code, is that okay? > > +/* > > + * GetTupleSize - Compute the tuple size given a table slot. > > +inline Size > > I think this embeds too much knowledge of the set of slot types in core > code. I don't see why it's needed either? The heapam multi-insert implementation needs to know the tuple size from the slot to decide whether or not to flush the tuples from the buffers. I couldn't find a direct way then to know the tuple size from the slot, so added that helper function. With a better understanding now, I think we can rely on the memory allocated for TupleTableSlot's tts_mcxt. While this works for the materialized slots passed in to the insert functions, for non-materialized slots the flushing decision can be solely on the number of tuples stored in the buffers. Another way is to add a get_tuple_size callback to TupleTableSlotOps and let the tuple slot providers give us the tuple size. > > diff --git a/src/include/access/tableam.h b/src/include/access/tableam.= h > > index 414b6b4d57..2a1470a7b6 100644 > > --- a/src/include/access/tableam.h > > +++ b/src/include/access/tableam.h > > @@ -229,6 +229,32 @@ typedef struct TM_IndexDeleteOp > > TM_IndexStatus *status; > > } TM_IndexDeleteOp; > > > > +/* Holds table insert state. */ > > +typedef struct TableInsertState > > I suspect we should design it to be usable for updates and deletes in the > future, and thus name it TableModifyState. There are different parameters that insert/update/delete would want to pass across in the state. So, having Table{Insert/Update/Delete}State may be a better idea than having the unneeded variables lying around or having a union and state_type as INSERT/UPDATE/DELETE, no? Do you have a different thought here? > I think we should instead have a generic TableModifyState, which each AM = then > embeds into an AM specific AM state. Forcing two very related structs to = be > allocated separately doesn't seem wise in this case. The v7 patches have largely changed the way these options and parameters are passed, please have a look. > > +{ > > + Relation rel; > > + /* Bulk insert state if requested, otherwise NULL. */ > > + struct BulkInsertStateData *bistate; > > + CommandId cid; > > Hm - I'm not sure it's a good idea to force the cid to be the same for al= l > inserts done via one TableInsertState. If required, someone can always pass a new CID before every tuple_insert_v2/tuple_multi_insert_v2 call via TableInsertState. Isn't it sufficient? > > @@ -1430,6 +1473,50 @@ table_multi_insert(Relation rel, TupleTableSlot = **slots, int nslots, > > cid, op= tions, bistate); > > } > > > > +static inline TableInsertState* > > +table_insert_begin(Relation rel, CommandId cid, int options, > > + bool alloc_bistate, bool is_multi) > > Why have alloc_bistate and options? "alloc_bistate" is for the caller to specify if they need a bulk insert state or not. "options" is for the caller to specify if they need table_tuple_insert performance options such as TABLE_INSERT_SKIP_FSM, TABLE_INSERT_FROZEN, TABLE_INSERT_NO_LOGICAL. The v7 patches have changed the way these options and parameters are passed, please have a look. > > +static inline void > > +table_insert_end(TableInsertState *state) > > +{ > > + /* Deallocate bulk insert state here, since it's AM independent. = */ > > + if (state->bistate) > > + FreeBulkInsertState(state->bistate); > > + > > + state->rel->rd_tableam->tuple_insert_end(state); > > +} > > Seems like the order in here should be swapped? Right. It looks like BulkInsertState is for heapam, it really doesn't have to be in table_XXX functions, hence it all the way down to heap_insert_XXX functions. I'm attaching the v7 patch set with the above review comments addressed. My initial idea behind these new insert APIs was the ability to re-use the multi insert code in COPY for CTAS and REFRESH MATERIALIZED VIEW. I'm open to more thoughts here. The v7 patches have largely changed the way state structure (heapam specific things are moved all the way down to heapam.c) is defined, the parameters are passed, and simplified the multi insert logic a lot. 0001 - introduces new single and multi insert table AM and heapam implementation of the new AM. 0002 - optimizes CREATE TABLE AS to use the new multi inserts table AM making it faster by 2.13X or 53%. 0003 - optimizes REFRESH MATERIALIZED VIEW to use the new multi inserts table AM making it faster by 1.52X or 34%. 0004 - uses the new multi inserts table AM for COPY FROM - I'm yet to spend time on this, I'll share the patch when ready. Thoughts? -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com --000000000000d478c30601df11f9 Content-Type: application/octet-stream; name="v7-0001-New-table-AMs-for-single-and-multi-inserts.patch" Content-Disposition: attachment; filename="v7-0001-New-table-AMs-for-single-and-multi-inserts.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lksaw7270 RnJvbSA2ODAzNzM2ZTU2OTVhYjBlZjA2ZDI2M2U5YmEyNjBkYjAyZDNiODBjIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBCaGFyYXRoIFJ1cGlyZWRkeSA8YmhhcmF0aC5ydXBpcmVkZHlm b3Jwb3N0Z3Jlc0BnbWFpbC5jb20+CkRhdGU6IFR1ZSwgMSBBdWcgMjAyMyAwOTozODo0NyArMDAw MApTdWJqZWN0OiBbUEFUQ0ggdjddIE5ldyB0YWJsZSBBTXMgZm9yIHNpbmdsZSBhbmQgbXVsdGkg aW5zZXJ0cwoKLS0tCiBzcmMvYmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFwYW0uYyAgICAgICAgIHwg MTgwICsrKysrKysrKysrKysrKysrKysrKysrCiBzcmMvYmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFw YW1faGFuZGxlci5jIHwgICA2ICsKIHNyYy9pbmNsdWRlL2FjY2Vzcy9oZWFwYW0uaCAgICAgICAg ICAgICAgfCAgNDUgKysrKysrCiBzcmMvaW5jbHVkZS9hY2Nlc3MvdGFibGVhbS5oICAgICAgICAg ICAgIHwgMTA3ICsrKysrKysrKysrKysrCiA0IGZpbGVzIGNoYW5nZWQsIDMzOCBpbnNlcnRpb25z KCspCgpkaWZmIC0tZ2l0IGEvc3JjL2JhY2tlbmQvYWNjZXNzL2hlYXAvaGVhcGFtLmMgYi9zcmMv YmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFwYW0uYwppbmRleCA3ZWQ3MmFiZTU5Li5iYTQzNDcwMjZh IDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFwYW0uYworKysgYi9zcmMv YmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFwYW0uYwpAQCAtNjgsNiArNjgsNyBAQAogI2luY2x1ZGUg InV0aWxzL2RhdHVtLmgiCiAjaW5jbHVkZSAidXRpbHMvaW52YWwuaCIKICNpbmNsdWRlICJ1dGls cy9sc3lzY2FjaGUuaCIKKyNpbmNsdWRlICJ1dGlscy9tZW11dGlscy5oIgogI2luY2x1ZGUgInV0 aWxzL3JlbGNhY2hlLmgiCiAjaW5jbHVkZSAidXRpbHMvc25hcG1nci5oIgogI2luY2x1ZGUgInV0 aWxzL3NwY2NhY2hlLmgiCkBAIC03NSw2ICs3Niw3IEBACiAKIHN0YXRpYyBIZWFwVHVwbGUgaGVh cF9wcmVwYXJlX2luc2VydChSZWxhdGlvbiByZWxhdGlvbiwgSGVhcFR1cGxlIHR1cCwKIAkJCQkJ CQkJCSBUcmFuc2FjdGlvbklkIHhpZCwgQ29tbWFuZElkIGNpZCwgaW50IG9wdGlvbnMpOworc3Rh dGljIHZvaWQgaGVhcF9tdWx0aV9pbnNlcnRfZmx1c2goVGFibGVJbnNlcnRTdGF0ZSAqc3RhdGUp Owogc3RhdGljIFhMb2dSZWNQdHIgbG9nX2hlYXBfdXBkYXRlKFJlbGF0aW9uIHJlbG4sIEJ1ZmZl ciBvbGRidWYsCiAJCQkJCQkJCSAgQnVmZmVyIG5ld2J1ZiwgSGVhcFR1cGxlIG9sZHR1cCwKIAkJ CQkJCQkJICBIZWFwVHVwbGUgbmV3dHVwLCBIZWFwVHVwbGUgb2xkX2tleV90dXBsZSwKQEAgLTI0 NDMsNiArMjQ0NSwxODQgQEAgaGVhcF9tdWx0aV9pbnNlcnQoUmVsYXRpb24gcmVsYXRpb24sIFR1 cGxlVGFibGVTbG90ICoqc2xvdHMsIGludCBudHVwbGVzLAogCXBnc3RhdF9jb3VudF9oZWFwX2lu c2VydChyZWxhdGlvbiwgbnR1cGxlcyk7CiB9CiAKKy8qCisgKiBJbml0aWFsaXplIHN0YXRlIHJl cXVpcmVkIGZvciBhbiBpbnNlcnQgYSBzaW5nbGUgdHVwbGUgb3IgbXVsdGlwbGUgdHVwbGVzCisg KiBpbnRvIGEgaGVhcC4KKyAqLworVGFibGVJbnNlcnRTdGF0ZSAqCitoZWFwX2luc2VydF9iZWdp bihSZWxhdGlvbiByZWwsIENvbW1hbmRJZCBjaWQsIGludCB0YWJsZV9hbV9mbGFncywKKwkJCQkg IGludCB0YWJsZV9pbnNlcnRfZmxhZ3MpCit7CisJVGFibGVJbnNlcnRTdGF0ZSAqdGlzdGF0ZTsK KworCXRpc3RhdGUgPSAoVGFibGVJbnNlcnRTdGF0ZSAqKSBwYWxsb2MwKHNpemVvZihUYWJsZUlu c2VydFN0YXRlKSk7CisJdGlzdGF0ZS0+cmVsID0gcmVsOworCXRpc3RhdGUtPmNpZCA9IGNpZDsK Kwl0aXN0YXRlLT50YWJsZV9hbV9mbGFncyA9IHRhYmxlX2FtX2ZsYWdzOworCXRpc3RhdGUtPnRh YmxlX2luc2VydF9mbGFncyA9IHRhYmxlX2luc2VydF9mbGFnczsKKworCWlmICgodGFibGVfYW1f ZmxhZ3MgJiBUQUJMRUFNX1VTRV9NVUxUSV9JTlNFUlRTKSAhPSAwIHx8CisJCSh0YWJsZV9hbV9m bGFncyAmIFRBQkxFQU1fVVNFX0JVTEtXUklURV9CVUZGRVJfQUNDRVNTX1NUUkFURUdZKSkKKwl7 CisJCXRpc3RhdGUtPnRhYmxlX2FtX2RhdGEgPQorCQkJKEhlYXBJbnNlcnRTdGF0ZSAqKSBwYWxs b2MwKHNpemVvZihIZWFwSW5zZXJ0U3RhdGUpKTsKKwl9CisKKwlpZiAoKHRhYmxlX2FtX2ZsYWdz ICYgVEFCTEVBTV9VU0VfTVVMVElfSU5TRVJUUykgIT0gMCkKKwl7CisJCSgoSGVhcEluc2VydFN0 YXRlICopIHRpc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5taXN0YXRlID0KKwkJCShIZWFwTXVsdGlJ bnNlcnRTdGF0ZSAqKSBwYWxsb2MwKHNpemVvZihIZWFwTXVsdGlJbnNlcnRTdGF0ZSkpOworCisJ CSgoSGVhcEluc2VydFN0YXRlICopIHRpc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5taXN0YXRlLT5z bG90cyA9CisJCQkJcGFsbG9jMChzaXplb2YoVHVwbGVUYWJsZVNsb3QgKikgKiBIRUFQX01BWF9C VUZGRVJFRF9TTE9UUyk7CisKKwkJKChIZWFwSW5zZXJ0U3RhdGUgKikgdGlzdGF0ZS0+dGFibGVf YW1fZGF0YSktPm1pc3RhdGUtPmNvbnRleHQgPQorCQkJCUFsbG9jU2V0Q29udGV4dENyZWF0ZShD dXJyZW50TWVtb3J5Q29udGV4dCwKKwkJCQkJCQkJCSAgImhlYXBfbXVsdGlfaW5zZXJ0X3YyIG1l bW9yeSBjb250ZXh0IiwKKwkJCQkJCQkJCSAgQUxMT0NTRVRfREVGQVVMVF9TSVpFUyk7CisJfQor CisJaWYgKCh0YWJsZV9hbV9mbGFncyAmIFRBQkxFQU1fVVNFX0JVTEtXUklURV9CVUZGRVJfQUND RVNTX1NUUkFURUdZKSAhPSAwKQorCQkoKEhlYXBJbnNlcnRTdGF0ZSAqKSB0aXN0YXRlLT50YWJs ZV9hbV9kYXRhKS0+YmlzdGF0ZSA9IEdldEJ1bGtJbnNlcnRTdGF0ZSgpOworCisJcmV0dXJuIHRp c3RhdGU7Cit9CisKKy8qCisgKiBJbnNlcnQgYSBzaW5nbGUgdHVwbGUgaW50byBhIGhlYXAuCisg Ki8KK3ZvaWQKK2hlYXBfaW5zZXJ0X3YyKFRhYmxlSW5zZXJ0U3RhdGUgKnN0YXRlLCBUdXBsZVRh YmxlU2xvdCAqc2xvdCkKK3sKKwlib29sCQlzaG91bGRGcmVlID0gdHJ1ZTsKKwlIZWFwVHVwbGUJ dHVwbGUgPSBFeGVjRmV0Y2hTbG90SGVhcFR1cGxlKHNsb3QsIHRydWUsICZzaG91bGRGcmVlKTsK KwlCdWxrSW5zZXJ0U3RhdGUgYmlzdGF0ZSA9IE5VTEw7CisKKwkvKiBVcGRhdGUgdHVwbGUgd2l0 aCB0YWJsZSBvaWQgKi8KKwlzbG90LT50dHNfdGFibGVPaWQgPSBSZWxhdGlvbkdldFJlbGlkKHN0 YXRlLT5yZWwpOworCXR1cGxlLT50X3RhYmxlT2lkID0gc2xvdC0+dHRzX3RhYmxlT2lkOworCisJ aWYgKHN0YXRlLT50YWJsZV9hbV9kYXRhICE9IE5VTEwgJiYKKwkJKChIZWFwSW5zZXJ0U3RhdGUg Kikgc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5iaXN0YXRlICE9IE5VTEwpCisJeworCQliaXN0YXRl ID0gKChIZWFwSW5zZXJ0U3RhdGUgKikgc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5iaXN0YXRlOwor CX0KKworCS8qIFBlcmZvcm0gaW5zZXJ0aW9uLCBhbmQgY29weSB0aGUgcmVzdWx0aW5nIEl0ZW1Q b2ludGVyICovCisJaGVhcF9pbnNlcnQoc3RhdGUtPnJlbCwgdHVwbGUsIHN0YXRlLT5jaWQsIHN0 YXRlLT50YWJsZV9pbnNlcnRfZmxhZ3MsCisJCQkJYmlzdGF0ZSk7CisJSXRlbVBvaW50ZXJDb3B5 KCZ0dXBsZS0+dF9zZWxmLCAmc2xvdC0+dHRzX3RpZCk7CisKKwlpZiAoc2hvdWxkRnJlZSkKKwkJ cGZyZWUodHVwbGUpOworfQorCisvKgorICogU3RvcmUgcGFzc2VkLWluIHR1cGxlIGludG8gaW4t bWVtb3J5IGJ1ZmZlcmVkIHNsb3RzLiBXaGVuIGZ1bGwsIGluc2VydAorICogbXVsdGlwbGUgdHVw bGVzIGZyb20gdGhlIGJ1ZmZlcnMgaW50byBoZWFwLgorICovCit2b2lkCitoZWFwX211bHRpX2lu c2VydF92MihUYWJsZUluc2VydFN0YXRlICpzdGF0ZSwgVHVwbGVUYWJsZVNsb3QgKnNsb3QpCit7 CisJVHVwbGVUYWJsZVNsb3QgICpkc3RzbG90OworCUhlYXBNdWx0aUluc2VydFN0YXRlICptaXN0 YXRlOworCisJQXNzZXJ0KHN0YXRlLT50YWJsZV9hbV9kYXRhICE9IE5VTEwgJiYKKwkJICAgKChI ZWFwSW5zZXJ0U3RhdGUgKikgc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5taXN0YXRlICE9IE5VTEwp OworCisJbWlzdGF0ZSA9ICgoSGVhcEluc2VydFN0YXRlICopIHN0YXRlLT50YWJsZV9hbV9kYXRh KS0+bWlzdGF0ZTsKKwlkc3RzbG90ID0gbWlzdGF0ZS0+c2xvdHNbbWlzdGF0ZS0+Y3VyX3Nsb3Rz XTsKKworCWlmIChkc3RzbG90ID09IE5VTEwpCisJeworCQlkc3RzbG90ID0gdGFibGVfc2xvdF9j cmVhdGUoc3RhdGUtPnJlbCwgTlVMTCk7CisJCW1pc3RhdGUtPnNsb3RzW21pc3RhdGUtPmN1cl9z bG90c10gPSBkc3RzbG90OworCX0KKworCUV4ZWNDbGVhclR1cGxlKGRzdHNsb3QpOworCUV4ZWND b3B5U2xvdChkc3RzbG90LCBzbG90KTsKKwltaXN0YXRlLT5jdXJfc2xvdHMrKzsKKworCS8qCisJ ICogV2hlbiBwYXNzZWQtaW4gc2xvdCBpcyBhbHJlYWR5IG1hdGVyaWFsaXplZCwgbWVtb3J5IGFs bG9jYXRlZCBpbiBzbG90J3MKKwkgKiBtZW1vcnkgY29udGV4dCBpcyBhIGNsb3NlIGFwcHJveGlt YXRpb24gZm9yIHVzIHRvIHRyYWNrIHRoZSByZXF1aXJlZAorCSAqIHNwYWNlIGZvciB0aGUgdHVw bGUgaW4gc2xvdC4KKwkgKgorCSAqIEZvciBub24tbWF0ZXJpYWxpemVkIHNsb3RzLCB0aGUgZmx1 c2hpbmcgZGVjaXNpb24gaGFwcGVucyBzb2xlbHkgb24gdGhlCisJICogbnVtYmVyIG9mIHR1cGxl cyBzdG9yZWQgaW4gdGhlIGJ1ZmZlci4KKwkgKi8KKwlpZiAoVFRTX1NIT1VMREZSRUUoc2xvdCkp CisJCW1pc3RhdGUtPmN1cl9zaXplICs9IE1lbW9yeUNvbnRleHRNZW1BbGxvY2F0ZWQoc2xvdC0+ dHRzX21jeHQsIGZhbHNlKTsKKworCWlmIChtaXN0YXRlLT5jdXJfc2xvdHMgPj0gSEVBUF9NQVhf QlVGRkVSRURfU0xPVFMgfHwKKwkJbWlzdGF0ZS0+Y3VyX3NpemUgPj0gSEVBUF9NQVhfQlVGRkVS RURfQllURVMpCisJCWhlYXBfbXVsdGlfaW5zZXJ0X2ZsdXNoKHN0YXRlKTsKK30KKworLyoKKyAq IENsZWFuIHVwIHN0YXRlIHVzZWQgdG8gaW5zZXJ0IGEgc2luZ2xlIG9yIG11bHRpcGxlIHR1cGxl cyBpbnRvIGEgaGVhcC4KKyAqLwordm9pZAoraGVhcF9pbnNlcnRfZW5kKFRhYmxlSW5zZXJ0U3Rh dGUgKnN0YXRlKQoreworCWlmIChzdGF0ZS0+dGFibGVfYW1fZGF0YSAhPSBOVUxMICYmCisJCSgo SGVhcEluc2VydFN0YXRlICopIHN0YXRlLT50YWJsZV9hbV9kYXRhKS0+bWlzdGF0ZSAhPSBOVUxM KQorCXsKKwkJSGVhcE11bHRpSW5zZXJ0U3RhdGUgKm1pc3RhdGUgPQorCQkJKChIZWFwSW5zZXJ0 U3RhdGUgKikgc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5taXN0YXRlOworCisJCS8qIEluc2VydCBy ZW1haW5pbmcgdHVwbGVzIGZyb20gbXVsdGktaW5zZXJ0IGJ1ZmZlcnMgKi8KKwkJaWYgKG1pc3Rh dGUtPmN1cl9zbG90cyA+IDAgfHwgbWlzdGF0ZS0+Y3VyX3NpemUgPiAwKQorCQkJaGVhcF9tdWx0 aV9pbnNlcnRfZmx1c2goc3RhdGUpOworCisJCU1lbW9yeUNvbnRleHREZWxldGUobWlzdGF0ZS0+ Y29udGV4dCk7CisKKwkJZm9yIChpbnQgaSA9IDA7IGkgPCBIRUFQX01BWF9CVUZGRVJFRF9TTE9U UyAmJiBtaXN0YXRlLT5zbG90c1tpXSAhPSBOVUxMOyBpKyspCisJCQlFeGVjRHJvcFNpbmdsZVR1 cGxlVGFibGVTbG90KG1pc3RhdGUtPnNsb3RzW2ldKTsKKworCQlwZnJlZShtaXN0YXRlKTsKKwkJ KChIZWFwSW5zZXJ0U3RhdGUgKikgc3RhdGUtPnRhYmxlX2FtX2RhdGEpLT5taXN0YXRlID0gTlVM TDsKKwl9CisKKwlpZiAoc3RhdGUtPnRhYmxlX2FtX2RhdGEgIT0gTlVMTCAmJgorCQkoKEhlYXBJ bnNlcnRTdGF0ZSAqKSBzdGF0ZS0+dGFibGVfYW1fZGF0YSktPmJpc3RhdGUgIT0gTlVMTCkKKwl7 CisJCUZyZWVCdWxrSW5zZXJ0U3RhdGUoKChIZWFwSW5zZXJ0U3RhdGUgKikgc3RhdGUtPnRhYmxl X2FtX2RhdGEpLT5iaXN0YXRlKTsKKwl9CisKKwlwZnJlZShzdGF0ZS0+dGFibGVfYW1fZGF0YSk7 CisJc3RhdGUtPnRhYmxlX2FtX2RhdGEgPSBOVUxMOworCXBmcmVlKHN0YXRlKTsKK30KKworLyoK KyAqIEluc2VydCBtdWx0aXBsZSB0dXBsZXMgZnJvbSBpbi1tZW1vcnkgYnVmZmVyZWQgc2xvdHMg aW50byBoZWFwLgorICovCitzdGF0aWMgdm9pZAoraGVhcF9tdWx0aV9pbnNlcnRfZmx1c2goVGFi bGVJbnNlcnRTdGF0ZSAqc3RhdGUpCit7CisJSGVhcE11bHRpSW5zZXJ0U3RhdGUgKm1pc3RhdGU7 CisJQnVsa0luc2VydFN0YXRlIGJpc3RhdGUgPSBOVUxMOworCU1lbW9yeUNvbnRleHQgb2xkY29u dGV4dDsKKworCW1pc3RhdGUgPSAoKEhlYXBJbnNlcnRTdGF0ZSAqKSBzdGF0ZS0+dGFibGVfYW1f ZGF0YSktPm1pc3RhdGU7CisKKwlpZiAoc3RhdGUtPnRhYmxlX2FtX2RhdGEgIT0gTlVMTCAmJgor CQkoKEhlYXBJbnNlcnRTdGF0ZSAqKSBzdGF0ZS0+dGFibGVfYW1fZGF0YSktPmJpc3RhdGUgIT0g TlVMTCkKKwl7CisJCWJpc3RhdGUgPSAoKEhlYXBJbnNlcnRTdGF0ZSAqKSBzdGF0ZS0+dGFibGVf YW1fZGF0YSktPmJpc3RhdGU7CisJfQorCisJb2xkY29udGV4dCA9IE1lbW9yeUNvbnRleHRTd2l0 Y2hUbyhtaXN0YXRlLT5jb250ZXh0KTsKKwloZWFwX211bHRpX2luc2VydChzdGF0ZS0+cmVsLCBt aXN0YXRlLT5zbG90cywgbWlzdGF0ZS0+Y3VyX3Nsb3RzLAorCQkJCQkgIHN0YXRlLT5jaWQsIHN0 YXRlLT50YWJsZV9pbnNlcnRfZmxhZ3MsIGJpc3RhdGUpOworCU1lbW9yeUNvbnRleHRTd2l0Y2hU byhvbGRjb250ZXh0KTsKKwlNZW1vcnlDb250ZXh0UmVzZXQobWlzdGF0ZS0+Y29udGV4dCk7CisK KwltaXN0YXRlLT5jdXJfc2xvdHMgPSAwOworCW1pc3RhdGUtPmN1cl9zaXplID0gMDsKK30KKwog LyoKICAqCXNpbXBsZV9oZWFwX2luc2VydCAtIGluc2VydCBhIHR1cGxlCiAgKgpkaWZmIC0tZ2l0 IGEvc3JjL2JhY2tlbmQvYWNjZXNzL2hlYXAvaGVhcGFtX2hhbmRsZXIuYyBiL3NyYy9iYWNrZW5k L2FjY2Vzcy9oZWFwL2hlYXBhbV9oYW5kbGVyLmMKaW5kZXggNWExNzExMmM5MS4uNmYxNDRkODhk ZCAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvYWNjZXNzL2hlYXAvaGVhcGFtX2hhbmRsZXIuYwor KysgYi9zcmMvYmFja2VuZC9hY2Nlc3MvaGVhcC9oZWFwYW1faGFuZGxlci5jCkBAIC0yNTY4LDYg KzI1NjgsMTIgQEAgc3RhdGljIGNvbnN0IFRhYmxlQW1Sb3V0aW5lIGhlYXBhbV9tZXRob2RzID0g ewogCS50dXBsZV9pbnNlcnRfc3BlY3VsYXRpdmUgPSBoZWFwYW1fdHVwbGVfaW5zZXJ0X3NwZWN1 bGF0aXZlLAogCS50dXBsZV9jb21wbGV0ZV9zcGVjdWxhdGl2ZSA9IGhlYXBhbV90dXBsZV9jb21w bGV0ZV9zcGVjdWxhdGl2ZSwKIAkubXVsdGlfaW5zZXJ0ID0gaGVhcF9tdWx0aV9pbnNlcnQsCisK KwkudHVwbGVfaW5zZXJ0X2JlZ2luID0gaGVhcF9pbnNlcnRfYmVnaW4sCisJLnR1cGxlX2luc2Vy dF92MiA9IGhlYXBfaW5zZXJ0X3YyLAorCS50dXBsZV9tdWx0aV9pbnNlcnRfdjIgPSBoZWFwX211 bHRpX2luc2VydF92MiwKKwkudHVwbGVfaW5zZXJ0X2VuZCA9IGhlYXBfaW5zZXJ0X2VuZCwKKwog CS50dXBsZV9kZWxldGUgPSBoZWFwYW1fdHVwbGVfZGVsZXRlLAogCS50dXBsZV91cGRhdGUgPSBo ZWFwYW1fdHVwbGVfdXBkYXRlLAogCS50dXBsZV9sb2NrID0gaGVhcGFtX3R1cGxlX2xvY2ssCmRp ZmYgLS1naXQgYS9zcmMvaW5jbHVkZS9hY2Nlc3MvaGVhcGFtLmggYi9zcmMvaW5jbHVkZS9hY2Nl c3MvaGVhcGFtLmgKaW5kZXggZmFmNTAyNjUxOS4uYTFlYTI2Y2JkNiAxMDA2NDQKLS0tIGEvc3Jj L2luY2x1ZGUvYWNjZXNzL2hlYXBhbS5oCisrKyBiL3NyYy9pbmNsdWRlL2FjY2Vzcy9oZWFwYW0u aApAQCAtMTkxLDYgKzE5MSw0MCBAQCB0eXBlZGVmIHN0cnVjdCBIZWFwUGFnZUZyZWV6ZQogCiB9 IEhlYXBQYWdlRnJlZXplOwogCisvKgorICogTWF4aW11bSBudW1iZXIgb2Ygc2xvdHMgdGhhdCBt dWx0aS1pbnNlcnQgYnVmZmVycyBjYW4gaG9sZC4KKyAqCisgKiBDYXV0aW9uOiBEb24ndCBtYWtl IHRoaXMgdG9vIGJpZywgYXMgd2UgY291bGQgZW5kIHVwIHdpdGggdGhpcyBtYW55IHR1cGxlcwor ICogc3RvcmVkIGluIG11bHRpIGluc2VydCBidWZmZXIuIEZvciBpbnN0YW5jZSwgaW5jcmVhc2lu ZyB0aGlzIGNhbiBjYXVzZQorICogcXVhZHJhdGljIGdyb3d0aCBpbiBtZW1vcnkgcmVxdWlyZW1l bnRzIGR1cmluZyBjb3BpZXMgaW50byBwYXJ0aXRpb25lZAorICogdGFibGVzIHdpdGggYSBsYXJn ZSBudW1iZXIgb2YgcGFydGl0aW9ucy4KKyAqLworI2RlZmluZSBIRUFQX01BWF9CVUZGRVJFRF9T TE9UUwkJMTAwMAorCisvKiBNYXhpbXVtIHNpemUgb2YgYWxsIHR1cGxlcyB0aGF0IG11bHRpLWlu c2VydCBidWZmZXJzIGNhbiBob2xkICovCisjZGVmaW5lIEhFQVBfTUFYX0JVRkZFUkVEX0JZVEVT CQk2NTUzNQorCit0eXBlZGVmIHN0cnVjdCBIZWFwTXVsdGlJbnNlcnRTdGF0ZQoreworCS8qIE1l bW9yeSBjb250ZXh0IHRvIHVzZSBmb3IgZmx1c2hpbmcgbXVsdGktaW5zZXJ0IGJ1ZmZlcnMgKi8K KwlNZW1vcnlDb250ZXh0CWNvbnRleHQ7CisKKwkvKiBBcnJheSBvZiBidWZmZXJlZCBzbG90cyAq LworCVR1cGxlVGFibGVTbG90CSoqc2xvdHM7CisKKwkvKiBOdW1iZXIgb2Ygc2xvdHMgdGhhdCBt dWx0aS1pbnNlcnQgYnVmZmVycyBjdXJyZW50bHkgaG9sZCAqLworCWludAkJY3VyX3Nsb3RzOwor CisJLyogU2l6ZSBvZiBhbGwgdHVwbGVzIHRoYXQgbXVsdGktaW5zZXJ0IGJ1ZmZlcnMgY3VycmVu dGx5IGhvbGQgKi8KKwlTaXplCWN1cl9zaXplOworfSBIZWFwTXVsdGlJbnNlcnRTdGF0ZTsKKwor dHlwZWRlZiBzdHJ1Y3QgSGVhcEluc2VydFN0YXRlCit7CisJc3RydWN0IEJ1bGtJbnNlcnRTdGF0 ZURhdGEJKmJpc3RhdGU7CisJSGVhcE11bHRpSW5zZXJ0U3RhdGUJKm1pc3RhdGU7Cit9IEhlYXBJ bnNlcnRTdGF0ZTsKKwogLyogLS0tLS0tLS0tLS0tLS0tLQogICoJCWZ1bmN0aW9uIHByb3RvdHlw ZXMgZm9yIGhlYXAgYWNjZXNzIG1ldGhvZAogICoKQEAgLTI0MSw2ICsyNzUsMTcgQEAgZXh0ZXJu IHZvaWQgaGVhcF9pbnNlcnQoUmVsYXRpb24gcmVsYXRpb24sIEhlYXBUdXBsZSB0dXAsIENvbW1h bmRJZCBjaWQsCiBleHRlcm4gdm9pZCBoZWFwX211bHRpX2luc2VydChSZWxhdGlvbiByZWxhdGlv biwgc3RydWN0IFR1cGxlVGFibGVTbG90ICoqc2xvdHMsCiAJCQkJCQkJICBpbnQgbnR1cGxlcywg Q29tbWFuZElkIGNpZCwgaW50IG9wdGlvbnMsCiAJCQkJCQkJICBCdWxrSW5zZXJ0U3RhdGUgYmlz dGF0ZSk7CisKK2V4dGVybiBUYWJsZUluc2VydFN0YXRlKiBoZWFwX2luc2VydF9iZWdpbihSZWxh dGlvbiByZWwsCisJCQkJCQkJCQkJICAgQ29tbWFuZElkIGNpZCwKKwkJCQkJCQkJCQkgICBpbnQg dGFibGVfYW1fZmxhZ3MsCisJCQkJCQkJCQkJICAgaW50IHRhYmxlX2luc2VydF9mbGFncyk7Citl eHRlcm4gdm9pZCBoZWFwX2luc2VydF92MihUYWJsZUluc2VydFN0YXRlICpzdGF0ZSwKKwkJCQkJ CSAgIFR1cGxlVGFibGVTbG90ICpzbG90KTsKK2V4dGVybiB2b2lkIGhlYXBfbXVsdGlfaW5zZXJ0 X3YyKFRhYmxlSW5zZXJ0U3RhdGUgKnN0YXRlLAorCQkJCQkJCQkgVHVwbGVUYWJsZVNsb3QgKnNs b3QpOworZXh0ZXJuIHZvaWQgaGVhcF9pbnNlcnRfZW5kKFRhYmxlSW5zZXJ0U3RhdGUgKnN0YXRl KTsKKwogZXh0ZXJuIFRNX1Jlc3VsdCBoZWFwX2RlbGV0ZShSZWxhdGlvbiByZWxhdGlvbiwgSXRl bVBvaW50ZXIgdGlkLAogCQkJCQkJCSBDb21tYW5kSWQgY2lkLCBTbmFwc2hvdCBjcm9zc2NoZWNr LCBib29sIHdhaXQsCiAJCQkJCQkJIHN0cnVjdCBUTV9GYWlsdXJlRGF0YSAqdG1mZCwgYm9vbCBj aGFuZ2luZ1BhcnQpOwpkaWZmIC0tZ2l0IGEvc3JjL2luY2x1ZGUvYWNjZXNzL3RhYmxlYW0uaCBi L3NyYy9pbmNsdWRlL2FjY2Vzcy90YWJsZWFtLmgKaW5kZXggMjMwYmMzOWNjMC4uNWVhM2VlZWU4 YSAxMDA2NDQKLS0tIGEvc3JjL2luY2x1ZGUvYWNjZXNzL3RhYmxlYW0uaAorKysgYi9zcmMvaW5j bHVkZS9hY2Nlc3MvdGFibGVhbS5oCkBAIC0yNDcsNiArMjQ3LDM1IEBAIHR5cGVkZWYgc3RydWN0 IFRNX0luZGV4RGVsZXRlT3AKIAlUTV9JbmRleFN0YXR1cyAqc3RhdHVzOwogfSBUTV9JbmRleERl bGV0ZU9wOwogCisvKiBVc2UgbXVsdGkgKGJ1ZmZlciBtdWx0aXBsZSB0dXBsZXMgYW5kIGluc2Vy dCB0aGVtIGF0IG9uY2UpIGluc2VydHMgKi8KKyNkZWZpbmUgVEFCTEVBTV9VU0VfTVVMVElfSU5T RVJUUyAweDAwMDAwMQorCisvKiBVc2UgQkFTX0JVTEtXUklURSBidWZmZXIgYWNjZXNzIHN0cmF0 ZWd5ICovCisjZGVmaW5lIFRBQkxFQU1fVVNFX0JVTEtXUklURV9CVUZGRVJfQUNDRVNTX1NUUkFU RUdZIDB4MDAwMDAyCisKKworLyogSG9sZHMgdGFibGUgaW5zZXJ0IHN0YXRlLiAqLwordHlwZWRl ZiBzdHJ1Y3QgVGFibGVJbnNlcnRTdGF0ZQoreworCS8qIFRhYmxlIEFNLWFnbm9zdGljIGRhdGEg c3RhcnRzIGhlcmUgKi8KKwlSZWxhdGlvbglyZWw7CS8qIFRhcmdldCByZWxhdGlvbiAqLworCisJ LyoKKwkgKiBDb21tYW5kIElEIGZvciB0aGlzIGluc2VydGlvbi4gSWYgcmVxdWlyZWQsIGNoYW5n ZSB0aGlzIGZvciBlYWNoIHBhc3Mgb2YKKwkgKiBpbnNlcnQgZnVuY3Rpb25zLgorCSAqLworCUNv bW1hbmRJZAljaWQ7CisKKwkvKiBUYWJsZSBBTSBvcHRpb25zIChUQUJMRUFNX1hYWCBtYWNyb3Mp ICovCisJaW50CXRhYmxlX2FtX2ZsYWdzOworCisJLyogdGFibGVfdHVwbGVfaW5zZXJ0IHBlcmZv cm1hbmNlIG9wdGlvbnMgKFRBQkxFX0lOU0VSVF9YWFggbWFjcm9zKSAqLworCWludAkJdGFibGVf aW5zZXJ0X2ZsYWdzOworCisJLyogVGFibGUgQU0gc3BlY2lmaWMgZGF0YSBzdGFydHMgaGVyZSAq LworCXZvaWQJKnRhYmxlX2FtX2RhdGE7Cit9IFRhYmxlSW5zZXJ0U3RhdGU7CisKIC8qICJvcHRp b25zIiBmbGFnIGJpdHMgZm9yIHRhYmxlX3R1cGxlX2luc2VydCAqLwogLyogVEFCTEVfSU5TRVJU X1NLSVBfV0FMIHdhcyAweDAwMDE7IFJlbGF0aW9uTmVlZHNXQUwoKSBub3cgZ292ZXJucyAqLwog I2RlZmluZSBUQUJMRV9JTlNFUlRfU0tJUF9GU00JCTB4MDAwMgpAQCAtNTIyLDYgKzU1MSwxOSBA QCB0eXBlZGVmIHN0cnVjdCBUYWJsZUFtUm91dGluZQogCXZvaWQJCSgqbXVsdGlfaW5zZXJ0KSAo UmVsYXRpb24gcmVsLCBUdXBsZVRhYmxlU2xvdCAqKnNsb3RzLCBpbnQgbnNsb3RzLAogCQkJCQkJ CQkgQ29tbWFuZElkIGNpZCwgaW50IG9wdGlvbnMsIHN0cnVjdCBCdWxrSW5zZXJ0U3RhdGVEYXRh ICpiaXN0YXRlKTsKIAorCVRhYmxlSW5zZXJ0U3RhdGUgKigqdHVwbGVfaW5zZXJ0X2JlZ2luKSAo UmVsYXRpb24gcmVsLAorCQkJCQkJCQkJCQkgQ29tbWFuZElkIGNpZCwKKwkJCQkJCQkJCQkJIGlu dCB0YWJsZV9hbV9mbGFncywKKwkJCQkJCQkJCQkJIGludCB0YWJsZV9pbnNlcnRfZmxhZ3MpOwor CisJdm9pZCAoKnR1cGxlX2luc2VydF92MikgKFRhYmxlSW5zZXJ0U3RhdGUgKnN0YXRlLAorCQkJ CQkJCSBUdXBsZVRhYmxlU2xvdCAqc2xvdCk7CisKKwl2b2lkICgqdHVwbGVfbXVsdGlfaW5zZXJ0 X3YyKSAoVGFibGVJbnNlcnRTdGF0ZSAqc3RhdGUsCisJCQkJCQkJCSAgIFR1cGxlVGFibGVTbG90 ICpzbG90KTsKKworCXZvaWQgKCp0dXBsZV9pbnNlcnRfZW5kKSAoVGFibGVJbnNlcnRTdGF0ZSAq c3RhdGUpOworCiAJLyogc2VlIHRhYmxlX3R1cGxlX2RlbGV0ZSgpIGZvciByZWZlcmVuY2UgYWJv dXQgcGFyYW1ldGVycyAqLwogCVRNX1Jlc3VsdAkoKnR1cGxlX2RlbGV0ZSkgKFJlbGF0aW9uIHJl bCwKIAkJCQkJCQkJIEl0ZW1Qb2ludGVyIHRpZCwKQEAgLTE0NTYsNiArMTQ5OCw3MSBAQCB0YWJs ZV9tdWx0aV9pbnNlcnQoUmVsYXRpb24gcmVsLCBUdXBsZVRhYmxlU2xvdCAqKnNsb3RzLCBpbnQg bnNsb3RzLAogCQkJCQkJCQkgIGNpZCwgb3B0aW9ucywgYmlzdGF0ZSk7CiB9CiAKK3N0YXRpYyBp bmxpbmUgVGFibGVJbnNlcnRTdGF0ZSAqCit0YWJsZV9pbnNlcnRfYmVnaW4oUmVsYXRpb24gcmVs LCBDb21tYW5kSWQgY2lkLCBpbnQgdGFibGVfYW1fZmxhZ3MsCisJCQkJICAgaW50IHRhYmxlX2lu c2VydF9mbGFncykKK3sKKwkvKiBYWFg6IFJlYWxseSBpdCBkb2Vzbid0IGhhdmUgdG8gYmUgYW4g b3B0aW9uYWwgY2FsbGJhY2sgKi8KKwlpZiAocmVsLT5yZF90YWJsZWFtICYmIHJlbC0+cmRfdGFi bGVhbS0+dHVwbGVfaW5zZXJ0X2JlZ2luKQorCXsKKwkJcmV0dXJuIHJlbC0+cmRfdGFibGVhbS0+ dHVwbGVfaW5zZXJ0X2JlZ2luKHJlbCwgY2lkLCB0YWJsZV9hbV9mbGFncywKKwkJCQkJCQkJCQkJ CSAgIHRhYmxlX2luc2VydF9mbGFncyk7CisJfQorCWVsc2UKKwkJZXJlcG9ydChFUlJPUiwKKwkJ CQllcnJjb2RlKEVSUkNPREVfRkVBVFVSRV9OT1RfU1VQUE9SVEVEKSwKKwkJCQkgZXJybXNnKCJ0 YWJsZV9pbnNlcnRfYmVnaW4gYWNjZXNzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIHJl bGF0aW9uIFwiJXNcIiIsCisJCQkJCQlSZWxhdGlvbkdldFJlbGF0aW9uTmFtZShyZWwpKSk7Cit9 CisKK3N0YXRpYyBpbmxpbmUgdm9pZAordGFibGVfdHVwbGVfaW5zZXJ0X3YyKFRhYmxlSW5zZXJ0 U3RhdGUgKnN0YXRlLCBUdXBsZVRhYmxlU2xvdCAqc2xvdCkKK3sKKwkvKiBYWFg6IFJlYWxseSBp dCBkb2Vzbid0IGhhdmUgdG8gYmUgYW4gb3B0aW9uYWwgY2FsbGJhY2sgKi8KKwlpZiAoc3RhdGUt PnJlbC0+cmRfdGFibGVhbSAmJgorCQlzdGF0ZS0+cmVsLT5yZF90YWJsZWFtLT50dXBsZV9pbnNl cnRfYmVnaW4pCisJeworCQlyZXR1cm4gc3RhdGUtPnJlbC0+cmRfdGFibGVhbS0+dHVwbGVfaW5z ZXJ0X3YyKHN0YXRlLCBzbG90KTsKKwl9CisJZWxzZQorCQllcmVwb3J0KEVSUk9SLAorCQkJCWVy cmNvZGUoRVJSQ09ERV9GRUFUVVJFX05PVF9TVVBQT1JURUQpLAorCQkJCSBlcnJtc2coInRhYmxl X3R1cGxlX2luc2VydF92MiBhY2Nlc3MgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgcmVs YXRpb24gXCIlc1wiIiwKKwkJCQkJCVJlbGF0aW9uR2V0UmVsYXRpb25OYW1lKHN0YXRlLT5yZWwp KSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZAordGFibGVfbXVsdGlfaW5zZXJ0X3YyKFRhYmxl SW5zZXJ0U3RhdGUgKnN0YXRlLCBUdXBsZVRhYmxlU2xvdCAqc2xvdCkKK3sKKwkvKiBYWFg6IFJl YWxseSBpdCBkb2Vzbid0IGhhdmUgdG8gYmUgYW4gb3B0aW9uYWwgY2FsbGJhY2sgKi8KKwlpZiAo c3RhdGUtPnJlbC0+cmRfdGFibGVhbSAmJgorCQlzdGF0ZS0+cmVsLT5yZF90YWJsZWFtLT50dXBs ZV9pbnNlcnRfYmVnaW4pCisJeworCQlyZXR1cm4gc3RhdGUtPnJlbC0+cmRfdGFibGVhbS0+dHVw bGVfbXVsdGlfaW5zZXJ0X3YyKHN0YXRlLCBzbG90KTsKKwl9CisJZWxzZQorCQllcmVwb3J0KEVS Uk9SLAorCQkJCWVycmNvZGUoRVJSQ09ERV9GRUFUVVJFX05PVF9TVVBQT1JURUQpLAorCQkJCSBl cnJtc2coInRhYmxlX211bHRpX2luc2VydF92MiBhY2Nlc3MgbWV0aG9kIGlzIG5vdCBpbXBsZW1l bnRlZCBmb3IgcmVsYXRpb24gXCIlc1wiIiwKKwkJCQkJCVJlbGF0aW9uR2V0UmVsYXRpb25OYW1l KHN0YXRlLT5yZWwpKSk7Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZAordGFibGVfaW5zZXJ0X2Vu ZChUYWJsZUluc2VydFN0YXRlICpzdGF0ZSkKK3sKKwkvKiBYWFg6IFJlYWxseSBpdCBkb2Vzbid0 IGhhdmUgdG8gYmUgYW4gb3B0aW9uYWwgY2FsbGJhY2sgKi8KKwlpZiAoc3RhdGUtPnJlbC0+cmRf dGFibGVhbSAmJgorCQlzdGF0ZS0+cmVsLT5yZF90YWJsZWFtLT50dXBsZV9pbnNlcnRfYmVnaW4p CisJeworCQlyZXR1cm4gc3RhdGUtPnJlbC0+cmRfdGFibGVhbS0+dHVwbGVfaW5zZXJ0X2VuZChz dGF0ZSk7CisJfQorCWVsc2UKKwkJZXJlcG9ydChFUlJPUiwKKwkJCQllcnJjb2RlKEVSUkNPREVf RkVBVFVSRV9OT1RfU1VQUE9SVEVEKSwKKwkJCQkgZXJybXNnKCJ0YWJsZV9pbnNlcnRfZW5kIGFj Y2VzcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGZvciByZWxhdGlvbiBcIiVzXCIiLAorCQkJ CQkJUmVsYXRpb25HZXRSZWxhdGlvbk5hbWUoc3RhdGUtPnJlbCkpKTsKK30KKwogLyoKICAqIERl bGV0ZSBhIHR1cGxlLgogICoKLS0gCjIuMzQuMQoK --000000000000d478c30601df11f9 Content-Type: application/octet-stream; name="v7-0002-Optimize-CTAS-with-multi-inserts.patch" Content-Disposition: attachment; filename="v7-0002-Optimize-CTAS-with-multi-inserts.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lksaw8tg1 RnJvbSBkOTk5YjNlMTEyNzJmNDRiOGNiZTc1ZmI0ZDVkNGM1MThhYjQzMzI0IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBCaGFyYXRoIFJ1cGlyZWRkeSA8YmhhcmF0aC5ydXBpcmVkZHlm b3Jwb3N0Z3Jlc0BnbWFpbC5jb20+CkRhdGU6IFR1ZSwgMSBBdWcgMjAyMyAwOTozNzoyMiArMDAw MApTdWJqZWN0OiBbUEFUQ0ggdjddIE9wdGltaXplIENUQVMgd2l0aCBtdWx0aSBpbnNlcnRzCgot LS0KIHNyYy9iYWNrZW5kL2NvbW1hbmRzL2NyZWF0ZWFzLmMgfCAzMCArKysrKysrKysrKysrKy0t LS0tLS0tLS0tLS0tLS0KIDEgZmlsZSBjaGFuZ2VkLCAxNCBpbnNlcnRpb25zKCspLCAxNiBkZWxl dGlvbnMoLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC9jb21tYW5kcy9jcmVhdGVhcy5jIGIv c3JjL2JhY2tlbmQvY29tbWFuZHMvY3JlYXRlYXMuYwppbmRleCBlOTE5MjBjYTE0Li5hYzMwOTA2 Mjg4IDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC9jb21tYW5kcy9jcmVhdGVhcy5jCisrKyBiL3Ny Yy9iYWNrZW5kL2NvbW1hbmRzL2NyZWF0ZWFzLmMKQEAgLTU4LDkgKzU4LDcgQEAgdHlwZWRlZiBz dHJ1Y3QKIAkvKiBUaGVzZSBmaWVsZHMgYXJlIGZpbGxlZCBieSBpbnRvcmVsX3N0YXJ0dXA6ICov CiAJUmVsYXRpb24JcmVsOwkJCS8qIHJlbGF0aW9uIHRvIHdyaXRlIHRvICovCiAJT2JqZWN0QWRk cmVzcyByZWxhZGRyOwkJLyogYWRkcmVzcyBvZiByZWwsIGZvciBFeGVjQ3JlYXRlVGFibGVBcyAq LwotCUNvbW1hbmRJZAlvdXRwdXRfY2lkOwkJLyogY21pbiB0byBpbnNlcnQgaW4gb3V0cHV0IHR1 cGxlcyAqLwotCWludAkJCXRpX29wdGlvbnM7CQkvKiB0YWJsZV90dXBsZV9pbnNlcnQgcGVyZm9y bWFuY2Ugb3B0aW9ucyAqLwotCUJ1bGtJbnNlcnRTdGF0ZSBiaXN0YXRlOwkvKiBidWxrIGluc2Vy dCBzdGF0ZSAqLworCVRhYmxlSW5zZXJ0U3RhdGUgKnRpX3N0YXRlOwkvKiAgdGFibGUgaW5zZXJ0 IHN0YXRlICovCiB9IERSX2ludG9yZWw7CiAKIC8qIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBDVEFT IGRlZmluaXRpb24gY3JlYXRpb24gKi8KQEAgLTU1NywxNyArNTU1LDI0IEBAIGludG9yZWxfc3Rh cnR1cChEZXN0UmVjZWl2ZXIgKnNlbGYsIGludCBvcGVyYXRpb24sIFR1cGxlRGVzYyB0eXBlaW5m bykKIAkgKi8KIAlteVN0YXRlLT5yZWwgPSBpbnRvUmVsYXRpb25EZXNjOwogCW15U3RhdGUtPnJl bGFkZHIgPSBpbnRvUmVsYXRpb25BZGRyOwotCW15U3RhdGUtPm91dHB1dF9jaWQgPSBHZXRDdXJy ZW50Q29tbWFuZElkKHRydWUpOwotCW15U3RhdGUtPnRpX29wdGlvbnMgPSBUQUJMRV9JTlNFUlRf U0tJUF9GU007CiAKIAkvKgogCSAqIElmIFdJVEggTk8gREFUQSBpcyBzcGVjaWZpZWQsIHRoZXJl IGlzIG5vIG5lZWQgdG8gc2V0IHVwIHRoZSBzdGF0ZSBmb3IKIAkgKiBidWxrIGluc2VydHMgYXMg dGhlcmUgYXJlIG5vIHR1cGxlcyB0byBpbnNlcnQuCiAJICovCiAJaWYgKCFpbnRvLT5za2lwRGF0 YSkKLQkJbXlTdGF0ZS0+YmlzdGF0ZSA9IEdldEJ1bGtJbnNlcnRTdGF0ZSgpOworCXsKKwkJaW50 CXRhYmxlX2FtX2ZsYWdzID0gVEFCTEVBTV9VU0VfTVVMVElfSU5TRVJUUyB8CisJCQlUQUJMRUFN X1VTRV9CVUxLV1JJVEVfQlVGRkVSX0FDQ0VTU19TVFJBVEVHWTsKKwkJaW50CXRhYmxlX2luc2Vy dF9mbGFncyA9IFRBQkxFX0lOU0VSVF9TS0lQX0ZTTTsKKworCQlteVN0YXRlLT50aV9zdGF0ZSA9 IHRhYmxlX2luc2VydF9iZWdpbihpbnRvUmVsYXRpb25EZXNjLAorCQkJCQkJCQkJCQkgICBHZXRD dXJyZW50Q29tbWFuZElkKHRydWUpLAorCQkJCQkJCQkJCQkgICB0YWJsZV9hbV9mbGFncywKKwkJ CQkJCQkJCQkJICAgdGFibGVfaW5zZXJ0X2ZsYWdzKTsKKwl9CiAJZWxzZQotCQlteVN0YXRlLT5i aXN0YXRlID0gTlVMTDsKKwkJbXlTdGF0ZS0+dGlfc3RhdGUgPSBOVUxMOwogCiAJLyoKIAkgKiBW YWxpZCBzbWdyX3RhcmdibG9jayBpbXBsaWVzIHNvbWV0aGluZyBhbHJlYWR5IHdyb3RlIHRvIHRo ZSByZWxhdGlvbi4KQEAgLTU5NSwxMSArNjAwLDcgQEAgaW50b3JlbF9yZWNlaXZlKFR1cGxlVGFi bGVTbG90ICpzbG90LCBEZXN0UmVjZWl2ZXIgKnNlbGYpCiAJCSAqIHdvdWxkIG5vdCBiZSBjaGVh cCBlaXRoZXIuIFRoaXMgYWxzbyBkb2Vzbid0IGFsbG93IGFjY2Vzc2luZyBwZXItQU0KIAkJICog ZGF0YSAoc2F5IGEgdHVwbGUncyB4bWluKSwgYnV0IHNpbmNlIHdlIGRvbid0IGRvIHRoYXQgaGVy ZS4uLgogCQkgKi8KLQkJdGFibGVfdHVwbGVfaW5zZXJ0KG15U3RhdGUtPnJlbCwKLQkJCQkJCSAg IHNsb3QsCi0JCQkJCQkgICBteVN0YXRlLT5vdXRwdXRfY2lkLAotCQkJCQkJICAgbXlTdGF0ZS0+ dGlfb3B0aW9ucywKLQkJCQkJCSAgIG15U3RhdGUtPmJpc3RhdGUpOworCQl0YWJsZV9tdWx0aV9p bnNlcnRfdjIobXlTdGF0ZS0+dGlfc3RhdGUsIHNsb3QpOwogCX0KIAogCS8qIFdlIGtub3cgdGhp cyBpcyBhIG5ld2x5IGNyZWF0ZWQgcmVsYXRpb24sIHNvIHRoZXJlIGFyZSBubyBpbmRleGVzICov CkBAIC02MTcsMTAgKzYxOCw3IEBAIGludG9yZWxfc2h1dGRvd24oRGVzdFJlY2VpdmVyICpzZWxm KQogCUludG9DbGF1c2UgKmludG8gPSBteVN0YXRlLT5pbnRvOwogCiAJaWYgKCFpbnRvLT5za2lw RGF0YSkKLQl7Ci0JCUZyZWVCdWxrSW5zZXJ0U3RhdGUobXlTdGF0ZS0+YmlzdGF0ZSk7Ci0JCXRh YmxlX2ZpbmlzaF9idWxrX2luc2VydChteVN0YXRlLT5yZWwsIG15U3RhdGUtPnRpX29wdGlvbnMp OwotCX0KKwkJdGFibGVfaW5zZXJ0X2VuZChteVN0YXRlLT50aV9zdGF0ZSk7CiAKIAkvKiBjbG9z ZSByZWwsIGJ1dCBrZWVwIGxvY2sgdW50aWwgY29tbWl0ICovCiAJdGFibGVfY2xvc2UobXlTdGF0 ZS0+cmVsLCBOb0xvY2spOwotLSAKMi4zNC4xCgo= --000000000000d478c30601df11f9 Content-Type: application/octet-stream; name="v7-0003-Optimize-RMV-with-multi-inserts.patch" Content-Disposition: attachment; filename="v7-0003-Optimize-RMV-with-multi-inserts.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lksawaw52 RnJvbSBjZWI4ZjQzNjg3ZGQwYmFmODZmYWMzYTA5NmQ5ODEzNGUwNmJjZWM4IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBCaGFyYXRoIFJ1cGlyZWRkeSA8YmhhcmF0aC5ydXBpcmVkZHlm b3Jwb3N0Z3Jlc0BnbWFpbC5jb20+CkRhdGU6IFR1ZSwgMSBBdWcgMjAyMyAwOTo1MDoyMCArMDAw MApTdWJqZWN0OiBbUEFUQ0ggdjddIE9wdGltaXplIFJNViB3aXRoIG11bHRpIGluc2VydHMKCi0t LQogc3JjL2JhY2tlbmQvY29tbWFuZHMvbWF0dmlldy5jIHwgMzYgKysrKysrKysrKysrKy0tLS0t LS0tLS0tLS0tLS0tLS0tLQogMSBmaWxlIGNoYW5nZWQsIDE0IGluc2VydGlvbnMoKyksIDIyIGRl bGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL2NvbW1hbmRzL21hdHZpZXcuYyBi L3NyYy9iYWNrZW5kL2NvbW1hbmRzL21hdHZpZXcuYwppbmRleCBhYzJlNzRmYTNmLi5jN2FiMmQx ZjQ0IDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC9jb21tYW5kcy9tYXR2aWV3LmMKKysrIGIvc3Jj L2JhY2tlbmQvY29tbWFuZHMvbWF0dmlldy5jCkBAIC01MiwxMCArNTIsNyBAQCB0eXBlZGVmIHN0 cnVjdAogCURlc3RSZWNlaXZlciBwdWI7CQkJLyogcHVibGljbHkta25vd24gZnVuY3Rpb24gcG9p bnRlcnMgKi8KIAlPaWQJCQl0cmFuc2llbnRvaWQ7CS8qIE9JRCBvZiBuZXcgaGVhcCBpbnRvIHdo aWNoIHRvIHN0b3JlICovCiAJLyogVGhlc2UgZmllbGRzIGFyZSBmaWxsZWQgYnkgdHJhbnNpZW50 cmVsX3N0YXJ0dXA6ICovCi0JUmVsYXRpb24JdHJhbnNpZW50cmVsOwkvKiByZWxhdGlvbiB0byB3 cml0ZSB0byAqLwotCUNvbW1hbmRJZAlvdXRwdXRfY2lkOwkJLyogY21pbiB0byBpbnNlcnQgaW4g b3V0cHV0IHR1cGxlcyAqLwotCWludAkJCXRpX29wdGlvbnM7CQkvKiB0YWJsZV90dXBsZV9pbnNl cnQgcGVyZm9ybWFuY2Ugb3B0aW9ucyAqLwotCUJ1bGtJbnNlcnRTdGF0ZSBiaXN0YXRlOwkvKiBi dWxrIGluc2VydCBzdGF0ZSAqLworCVRhYmxlSW5zZXJ0U3RhdGUgKnRpX3N0YXRlOwkvKiAgdGFi bGUgaW5zZXJ0IHN0YXRlICovCiB9IERSX3RyYW5zaWVudHJlbDsKIAogc3RhdGljIGludAltYXR2 aWV3X21haW50ZW5hbmNlX2RlcHRoID0gMDsKQEAgLTQ1NCwxNiArNDUxLDE4IEBAIHRyYW5zaWVu dHJlbF9zdGFydHVwKERlc3RSZWNlaXZlciAqc2VsZiwgaW50IG9wZXJhdGlvbiwgVHVwbGVEZXNj IHR5cGVpbmZvKQogewogCURSX3RyYW5zaWVudHJlbCAqbXlTdGF0ZSA9IChEUl90cmFuc2llbnRy ZWwgKikgc2VsZjsKIAlSZWxhdGlvbgl0cmFuc2llbnRyZWw7CisJaW50CXRhYmxlX2FtX2ZsYWdz ID0gVEFCTEVBTV9VU0VfTVVMVElfSU5TRVJUUyB8CisJCQlUQUJMRUFNX1VTRV9CVUxLV1JJVEVf QlVGRkVSX0FDQ0VTU19TVFJBVEVHWTsKKwlpbnQJdGFibGVfaW5zZXJ0X2ZsYWdzID0gVEFCTEVf SU5TRVJUX1NLSVBfRlNNIHwKKwkJCVRBQkxFX0lOU0VSVF9GUk9aRU47CiAKIAl0cmFuc2llbnRy ZWwgPSB0YWJsZV9vcGVuKG15U3RhdGUtPnRyYW5zaWVudG9pZCwgTm9Mb2NrKTsKIAotCS8qCi0J ICogRmlsbCBwcml2YXRlIGZpZWxkcyBvZiBteVN0YXRlIGZvciB1c2UgYnkgbGF0ZXIgcm91dGlu ZXMKLQkgKi8KLQlteVN0YXRlLT50cmFuc2llbnRyZWwgPSB0cmFuc2llbnRyZWw7Ci0JbXlTdGF0 ZS0+b3V0cHV0X2NpZCA9IEdldEN1cnJlbnRDb21tYW5kSWQodHJ1ZSk7Ci0JbXlTdGF0ZS0+dGlf b3B0aW9ucyA9IFRBQkxFX0lOU0VSVF9TS0lQX0ZTTSB8IFRBQkxFX0lOU0VSVF9GUk9aRU47Ci0J bXlTdGF0ZS0+YmlzdGF0ZSA9IEdldEJ1bGtJbnNlcnRTdGF0ZSgpOworCS8qIEZpbGwgcHJpdmF0 ZSBmaWVsZHMgb2YgbXlTdGF0ZSBmb3IgdXNlIGJ5IGxhdGVyIHJvdXRpbmVzICovCisJbXlTdGF0 ZS0+dGlfc3RhdGUgPSB0YWJsZV9pbnNlcnRfYmVnaW4odHJhbnNpZW50cmVsLAorCQkJCQkJCQkJ CSAgIEdldEN1cnJlbnRDb21tYW5kSWQodHJ1ZSksCisJCQkJCQkJCQkJICAgdGFibGVfYW1fZmxh Z3MsCisJCQkJCQkJCQkJICAgdGFibGVfaW5zZXJ0X2ZsYWdzKTsKIAogCS8qCiAJICogVmFsaWQg c21ncl90YXJnYmxvY2sgaW1wbGllcyBzb21ldGhpbmcgYWxyZWFkeSB3cm90ZSB0byB0aGUgcmVs YXRpb24uCkBAIC00ODgsMTIgKzQ4Nyw3IEBAIHRyYW5zaWVudHJlbF9yZWNlaXZlKFR1cGxlVGFi bGVTbG90ICpzbG90LCBEZXN0UmVjZWl2ZXIgKnNlbGYpCiAJICogY2hlYXAgZWl0aGVyLiBUaGlz IGFsc28gZG9lc24ndCBhbGxvdyBhY2Nlc3NpbmcgcGVyLUFNIGRhdGEgKHNheSBhCiAJICogdHVw bGUncyB4bWluKSwgYnV0IHNpbmNlIHdlIGRvbid0IGRvIHRoYXQgaGVyZS4uLgogCSAqLwotCi0J dGFibGVfdHVwbGVfaW5zZXJ0KG15U3RhdGUtPnRyYW5zaWVudHJlbCwKLQkJCQkJICAgc2xvdCwK LQkJCQkJICAgbXlTdGF0ZS0+b3V0cHV0X2NpZCwKLQkJCQkJICAgbXlTdGF0ZS0+dGlfb3B0aW9u cywKLQkJCQkJICAgbXlTdGF0ZS0+YmlzdGF0ZSk7CisJdGFibGVfbXVsdGlfaW5zZXJ0X3YyKG15 U3RhdGUtPnRpX3N0YXRlLCBzbG90KTsKIAogCS8qIFdlIGtub3cgdGhpcyBpcyBhIG5ld2x5IGNy ZWF0ZWQgcmVsYXRpb24sIHNvIHRoZXJlIGFyZSBubyBpbmRleGVzICovCiAKQEAgLTUwNywxNCAr NTAxLDEyIEBAIHN0YXRpYyB2b2lkCiB0cmFuc2llbnRyZWxfc2h1dGRvd24oRGVzdFJlY2VpdmVy ICpzZWxmKQogewogCURSX3RyYW5zaWVudHJlbCAqbXlTdGF0ZSA9IChEUl90cmFuc2llbnRyZWwg Kikgc2VsZjsKKwlSZWxhdGlvbiB0cmFuc2llbnRyZWwgPSBteVN0YXRlLT50aV9zdGF0ZS0+cmVs OwogCi0JRnJlZUJ1bGtJbnNlcnRTdGF0ZShteVN0YXRlLT5iaXN0YXRlKTsKLQotCXRhYmxlX2Zp bmlzaF9idWxrX2luc2VydChteVN0YXRlLT50cmFuc2llbnRyZWwsIG15U3RhdGUtPnRpX29wdGlv bnMpOworCXRhYmxlX2luc2VydF9lbmQobXlTdGF0ZS0+dGlfc3RhdGUpOwogCiAJLyogY2xvc2Ug dHJhbnNpZW50cmVsLCBidXQga2VlcCBsb2NrIHVudGlsIGNvbW1pdCAqLwotCXRhYmxlX2Nsb3Nl KG15U3RhdGUtPnRyYW5zaWVudHJlbCwgTm9Mb2NrKTsKLQlteVN0YXRlLT50cmFuc2llbnRyZWwg PSBOVUxMOworCXRhYmxlX2Nsb3NlKHRyYW5zaWVudHJlbCwgTm9Mb2NrKTsKIH0KIAogLyoKLS0g CjIuMzQuMQoK --000000000000d478c30601df11f9--