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.96) (envelope-from ) id 1vvNe3-00GXmT-0j for pgsql-hackers@arkaria.postgresql.org; Wed, 25 Feb 2026 22:46:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vvNe2-008tSP-0I for pgsql-hackers@arkaria.postgresql.org; Wed, 25 Feb 2026 22:46:14 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vvNe1-008tSG-0l for pgsql-hackers@lists.postgresql.org; Wed, 25 Feb 2026 22:46:13 +0000 Received: from forward500b.mail.yandex.net ([178.154.239.144]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vvNdt-00000001Br6-2tWZ for pgsql-hackers@lists.postgresql.org; Wed, 25 Feb 2026 22:46:12 +0000 Received: from mail-nwsmtp-smtp-production-main-73.sas.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-73.sas.yp-c.yandex.net [IPv6:2a02:6b8:c16:1e9b:0:640:1479:0]) by forward500b.mail.yandex.net (Yandex) with ESMTPS id 0B426C26D8; Thu, 26 Feb 2026 01:46:03 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-73.sas.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id 0kquM53Gwa60-YtKhb64x; Thu, 26 Feb 2026 01:46:02 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tantorlabs.com; s=mail; t=1772059562; bh=emLulS1/nN6iAKNfYWzZ5fs01uhZ6FRjK1xsQ7xeL2g=; h=In-Reply-To:Cc:Date:References:To:Subject:Message-ID:From; b=mTOGKFedO5hAr7I7PNGkIH7yMAMJiEq8fhybTkx6roM0byuFrafvIHRP2XIa+xWU7 IAAPmK0YSQwiGZH/Rt6yaqS0pdaBtfjuvIJAs9jCS97sCeG6Xabk8LcQhl7ebTKJg1 axhBhUGbBy60NHF9M8wAnFBSrZFV1Bnnjor9oQHo= Authentication-Results: mail-nwsmtp-smtp-production-main-73.sas.yp-c.yandex.net; dkim=pass header.i=@tantorlabs.com Content-Type: multipart/mixed; boundary="------------ve0uhGe6VpGttmkBJPT93NhW" Message-ID: <9067a807-f130-4631-8df4-076c6d7e43b6@tantorlabs.com> Date: Thu, 26 Feb 2026 01:45:44 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Hash-based MCV matching for large IN-lists To: Zsolt Parragi Cc: Tatsuya Kawata , David Geier , Chengpeng Yan , "pgsql-hackers@lists.postgresql.org" References: <7db341e0-fbc6-4ec5-922c-11fdafe7be12@tantorlabs.com> <988e3168-6096-488a-bb42-787e1e8c21a4@tantorlabs.com> <21FF6A0B-886F-4132-B6A6-0F4E934B4CEE@Outlook.com> <8ee9d903-bb13-434c-8145-b3769bf2b3cb@tantorlabs.com> <9e3054ae-1c5d-46dd-9b6a-7fb67764b076@tantorlabs.com> Content-Language: en-US From: Ilia Evdokimov In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------ve0uhGe6VpGttmkBJPT93NhW Content-Type: multipart/alternative; boundary="------------8xVaLi0Z06r7CLOWmVWJwxQI" --------------8xVaLi0Z06r7CLOWmVWJwxQI Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit I've addressed the review comments mentioned above. David made a very good observation: for unique columns, where each iteration effectively returns the same per-element selectivity, there is no need to iterate at all. In such cases we can reduce the computation to a closed-form expression, i.e. O(1) instead of running the loop O(N). I applied this idea to unique columns and cases falling back to DEFAULT_EQ_SEL. In both cases the loop can be replaced with a closed-from formula implemented in calculate_combined_selectivity(). The formula mirros the existing independent/disjoint probability model: ANY (sel = 1 - (1 - s) ^ length or length * s ), ALL (sel = s ^ length or 1 - length*(1 - s)). It would be good to carefully review that this is fully equivalent to the current accumulation logic. I also exprimented with applying the same idea to elements that are not found in MCV, are not Const, and effectively found in MCV with more than one count. Those cases can still be accumulated using accum_scalararray_prob(), but potentially grouped to reduce repeated work. Overall, the optimization work can be logically split into three parts: 1. Degenerate NULL case O(N) -> O(1) [0] 2. Identical non-NULL per-element selectivity O(N) -> O(1) (can be split into a separate thread if prederred) 3. MCV matching via hashing O(M*N) -> O(M+N) (current thread) Feedback on how to best structure or split this work would be appreciated. About op_is_reserved. It seems we should assign op_is_reserved = true, because we don't reverse types like eqjoinsel_semi(). If IN-list smaller than MCV-list we reverse it by fmgr_info(hash_mcv ? hashLeft : hashRight, &hash_proc). Thanks for this remark. Thoughts? -- Best regards, Ilia Evdokimov, Tantor Labs LLC, https://tantorlabs.com/ --------------8xVaLi0Z06r7CLOWmVWJwxQI Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

I've addressed the review comments mentioned above.

David made a very good observation: for unique columns, where each iteration effectively returns the same per-element selectivity, there is no need to iterate at all. In such cases we can reduce the computation to a closed-form expression, i.e. O(1) instead of running the loop O(N).

I applied this idea to unique columns and cases falling back to DEFAULT_EQ_SEL. In both cases the loop can be replaced with a closed-from formula implemented in calculate_combined_selectivity(). The formula mirros the existing independent/disjoint probability model: ANY (sel = 1 - (1 - s) ^ length or length * s ), ALL (sel = s ^ length or 1 - length*(1 - s)). It would be good to carefully review that this is fully equivalent to the current accumulation logic.

I also exprimented with applying the same idea to elements that are not found in MCV, are not Const, and effectively found in MCV with more than one count. Those cases can still be accumulated using accum_scalararray_prob(), but potentially grouped to reduce repeated work.

Overall, the optimization work can be logically split into three parts:

  1. Degenerate NULL case O(N) -> O(1) [0]
  2. Identical non-NULL per-element selectivity O(N) -> O(1) (can be split into a separate thread if prederred)
  3. MCV matching via hashing O(M*N) -> O(M+N) (current thread)

Feedback on how to best structure or split this work would be appreciated.

About op_is_reserved. It seems we should assign op_is_reserved = true, because we don't reverse types like eqjoinsel_semi(). If IN-list smaller than MCV-list we reverse it by fmgr_info(hash_mcv ? hashLeft : hashRight, &hash_proc). Thanks for this remark.

Thoughts?

-- 
Best regards, 
Ilia Evdokimov,
Tantor Labs LLC,
https://tantorlabs.com/

--------------8xVaLi0Z06r7CLOWmVWJwxQI-- --------------ve0uhGe6VpGttmkBJPT93NhW Content-Type: text/x-patch; charset=UTF-8; name="v6-0003-Use-hash-based-MCV-matching-for-ScalarArrayOpExpr.patch" Content-Disposition: attachment; filename*0="v6-0003-Use-hash-based-MCV-matching-for-ScalarArrayOpExpr.pa"; filename*1="tch" Content-Transfer-Encoding: base64 RnJvbSA2MDZkMjlkYmIzZTMxNjc5NmRmM2E1ODE4MTFjYTZjOThhYzViM2E2IE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBFdmRva2ltb3YgSWxpYSA8aWx5YS5ldmRva2ltb3ZA dGFudG9ybGFicy5jb20+CkRhdGU6IFdlZCwgMjUgRmViIDIwMjYgMjM6MzQ6MzcgKzAzMDAK U3ViamVjdDogW1BBVENIIHY2IDMvM10gVXNlIGhhc2gtYmFzZWQgTUNWIG1hdGNoaW5nIGZv ciBTY2FsYXJBcnJheU9wRXhwciAKIHNlbGVjdGl2aXR5CgpXaGVuIGVzdGltYXRpbmcgc2Vs ZWN0aXZpdHkgZm9yIFNjYWxhckFycmF5T3BFeHByIChJTiAvIEFOWSAvIEFMTCkgd2l0aAph dmFpbGFibGUgTUNWIHN0YXRpc3RpY3MsIHRoZSBwbGFubmVyIGN1cnJlbnRseSBtYXRjaGVz IElOLWxpc3QgZWxlbWVudHMKYWdhaW5zdCB0aGUgTUNWIGFycmF5IHVzaW5nIG5lc3RlZCBs b29wcy4gRm9yIGxhcmdlIElOLWxpc3RzIGFuZC9vciBsYXJnZQpNQ1YgbGlzdHMgdGhpcyBs ZWFkcyB0byBPKE4qTSkgcGxhbm5pbmctdGltZSBiZWhhdmlvci4KClRoaXMgcGF0Y2ggYWRk cyBhIGhhc2gtYmFzZWQgbWF0Y2hpbmcgc3RyYXRlZ3ksIHNpbWlsYXIgdG8gdGhlIG9uZSB1 c2VkCmluIGpvaW4gc2VsZWN0aXZpdHkgZXN0aW1hdGlvbi4gV2hlbiBNQ1Ygc3RhdGlzdGlj cyBhcmUgYXZhaWxhYmxlIGFuZCB0aGUKb3BlcmF0b3Igc3VwcG9ydHMgaGFzaGluZywgdGhl IHNtYWxsZXIgb2YgdGhlIHR3byBpbnB1dHMgKE1DViBsaXN0IG9yCklOLWxpc3QgY29uc3Rh bnQgZWxlbWVudHMpIGlzIGNob3NlbiBhcyB0aGUgaGFzaCB0YWJsZSBidWlsZCBzaWRlLCBh bmQKdGhlIG90aGVyIHNpZGUgaXMgc2Nhbm5lZCBvbmNlLCByZWR1Y2luZyBjb21wbGV4aXR5 IHRvIE8oTitNKS4KClRoZSBoYXNoLWJhc2VkIHBhdGggaXMgcmVzdHJpY3RlZCB0byBlcXVh bGl0eSBhbmQgaW5lcXVhbGl0eSBvcGVyYXRvcnMKdGhhdCB1c2UgZXFzZWwoKS9uZXFzZWwo KSwgYW5kIGlzIGFwcGxpZWQgb25seSB3aGVuIHN1aXRhYmxlIGhhc2gKZnVuY3Rpb25zIGFu ZCBNQ1Ygc3RhdGlzdGljcyBhcmUgYXZhaWxhYmxlLgotLS0KIHNyYy9iYWNrZW5kL3V0aWxz L2FkdC9zZWxmdW5jcy5jIHwgNDUwICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0K IDEgZmlsZSBjaGFuZ2VkLCA0NDAgaW5zZXJ0aW9ucygrKSwgMTAgZGVsZXRpb25zKC0pCgpk aWZmIC0tZ2l0IGEvc3JjL2JhY2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMgYi9zcmMvYmFj a2VuZC91dGlscy9hZHQvc2VsZnVuY3MuYwppbmRleCBmNjA5MWE1NzZkOC4uYjZhOWNmNzg0 NGYgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jCisrKyBi L3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jCkBAIC0xNDYsMjMgKzE0NiwyNyBA QAogLyoKICAqIEluIHByb2R1Y3Rpb24gYnVpbGRzLCBzd2l0Y2ggdG8gaGFzaC1iYXNlZCBN Q1YgbWF0Y2hpbmcgd2hlbiB0aGUgbGlzdHMgYXJlCiAgKiBsYXJnZSBlbm91Z2ggdG8gYW1v cnRpemUgaGFzaCBzZXR1cCBjb3N0LiAgKFRoaXMgdGhyZXNob2xkIGlzIGNvbXBhcmVkIHRv Ci0gKiB0aGUgc3VtIG9mIHRoZSBsZW5ndGhzIG9mIHRoZSB0d28gTUNWIGxpc3RzLiAgVGhp cyBpcyBzaW1wbGlzdGljIGJ1dCBzZWVtcworICogdGhlIHN1bSBvZiB0aGUgbGVuZ3RocyBv ZiB0aGUgdHdvIGxpc3RzLiAgVGhpcyBpcyBzaW1wbGlzdGljIGJ1dCBzZWVtcwogICogdG8g d29yayB3ZWxsIGVub3VnaC4pICBJbiBkZWJ1ZyBidWlsZHMsIHdlIHVzZSBhIHNtYWxsZXIg dGhyZXNob2xkIHNvIHRoYXQKICAqIHRoZSByZWdyZXNzaW9uIHRlc3RzIGNvdmVyIGJvdGgg cGF0aHMgd2VsbC4KICAqLwogI2lmbmRlZiBVU0VfQVNTRVJUX0NIRUNLSU5HCi0jZGVmaW5l IEVRSk9JTlNFTF9NQ1ZfSEFTSF9USFJFU0hPTEQgMjAwCisjZGVmaW5lIE1DVl9IQVNIX1RI UkVTSE9MRCAyMDAKICNlbHNlCi0jZGVmaW5lIEVRSk9JTlNFTF9NQ1ZfSEFTSF9USFJFU0hP TEQgMjAKKyNkZWZpbmUgTUNWX0hBU0hfVEhSRVNIT0xEIDIwCiAjZW5kaWYKIAotLyogRW50 cmllcyBpbiB0aGUgc2ltcGxlaGFzaCBoYXNoIHRhYmxlIHVzZWQgYnkgZXFqb2luc2VsX2Zp bmRfbWF0Y2hlcyAqLworLyoKKyAqIEVudHJpZXMgaW4gdGhlIHNpbXBsZWhhc2ggaGFzaCB0 YWJsZSB1c2VkIGJ5CisgKiBlcWpvaW5zZWxfZmluZF9tYXRjaGVzIGFuZCBzY2FsYXJhcnJh eV9tY3ZfaGFzaF9tYXRjaAorICovCiB0eXBlZGVmIHN0cnVjdCBNQ1ZIYXNoRW50cnkKIHsK IAlEYXR1bQkJdmFsdWU7CQkJLyogdGhlIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoaXMgZW50 cnkgKi8KIAlpbnQJCQlpbmRleDsJCQkvKiBpdHMgaW5kZXggaW4gdGhlIHJlbGV2YW50IEF0 dFN0YXRzU2xvdCAqLwogCXVpbnQzMgkJaGFzaDsJCQkvKiBoYXNoIGNvZGUgZm9yIHRoZSBE YXR1bSAqLwogCWNoYXIJCXN0YXR1czsJCQkvKiBzdGF0dXMgY29kZSB1c2VkIGJ5IHNpbXBs ZWhhc2guaCAqLworCWludAkJCWNvdW50OwkJCS8qIG51bWJlciBvZiBvY2N1cnJlbmNlcyBv ZiBjdXJyZW50IHZhbHVlIGluICovCiB9IE1DVkhhc2hFbnRyeTsKIAogLyogcHJpdmF0ZV9k YXRhIGZvciB0aGUgc2ltcGxlaGFzaCBoYXNoIHRhYmxlICovCkBAIC0xODQsNiArMTg4LDE1 IEBAIGdldF9yZWxhdGlvbl9zdGF0c19ob29rX3R5cGUgZ2V0X3JlbGF0aW9uX3N0YXRzX2hv b2sgPSBOVUxMOwogZ2V0X2luZGV4X3N0YXRzX2hvb2tfdHlwZSBnZXRfaW5kZXhfc3RhdHNf aG9vayA9IE5VTEw7CiAKIHN0YXRpYyBkb3VibGUgZXFzZWxfaW50ZXJuYWwoUEdfRlVOQ1RJ T05fQVJHUywgYm9vbCBuZWdhdGUpOworc3RhdGljIGRvdWJsZSBzY2FsYXJhcnJheV9tY3Zf aGFzaF9tYXRjaChWYXJpYWJsZVN0YXREYXRhICp2YXJkYXRhLCBPaWQgb3BlcmF0b3IsIE9p ZCBjb2xsYXRpb24sCisJCQkJCQkJCQkJIFNlbGVjdGl2aXR5IHMyLCBEYXR1bSAqZWxlbV92 YWx1ZXMsCisJCQkJCQkJCQkJIGJvb2wgKmVsZW1fbnVsbHMsIGludCBudW1fZWxlbXMsIGJv b2wgKmVsZW1fY29uc3QsCisJCQkJCQkJCQkJIE9pZCBub21pbmFsX2VsZW1lbnRfdHlwZSwg Ym9vbCB1c2VPciwgYm9vbCBpc0VxdWFsaXR5LAorCQkJCQkJCQkJCSBib29sIGlzSW5lcXVh bGl0eSk7CitzdGF0aWMgdm9pZCBhY2N1bV9zY2FsYXJhcnJheV9wcm9iKGRvdWJsZSBpbmRp dmlkdWFsX3MsIGludCBjb3VudCwKKwkJCQkJCQkJCWJvb2wgdXNlT3IsIGJvb2wgaXNFcXVh bGl0eSwKKwkJCQkJCQkJCWJvb2wgaXNJbmVxdWFsaXR5LCBkb3VibGUgbnVsbGZyYWMsCisJ CQkJCQkJCQlkb3VibGUgKnNlbGVjLCBkb3VibGUgKnMxZGlzam9pbnQpOwogc3RhdGljIFNl bGVjdGl2aXR5IGNhbGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShTZWxlY3Rpdml0eSBz MiwgaW50IG51bV9lbGVtcywKIAkJCQkJCQkgIGJvb2wgdXNlT3IsCiAJCQkJCQkJICBib29s IGlzRXF1YWxpdHksIGJvb2wgaXNJbmVxdWFsaXR5KTsKQEAgLTE5NTEsNiArMTk2NCwzNiBA QCBjYWxjdWxhdGVfY29tYmluZWRfc2VsZWN0aXZpdHkoU2VsZWN0aXZpdHkgczIsIGludCBu dW1fZWxlbXMsIGJvb2wgdXNlT3IsIGJvb2wgaQogCXJldHVybiBzMTsKIH0KIAorLyoKKyAq IEFjY3VtdWxhdGUgdGhlIHNlbGVjdGl2aXR5IGNvbnRyaWJ1dGlvbiBvZiBhIHNpbmdsZSBh cnJheSBlbGVtZW50CisgKiBpbnRvIHRoZSBydW5uaW5nIFNjYWxhckFycmF5T3BFeHByIHNl bGVjdGl2aXR5IGVzdGltYXRlLgorICovCitzdGF0aWMgdm9pZAorYWNjdW1fc2NhbGFyYXJy YXlfcHJvYihkb3VibGUgaW5kaXZpZHVhbF9zLCBpbnQgY291bnQsIGJvb2wgdXNlT3IsIGJv b2wgaXNFcXVhbGl0eSwKKwkJCQkJCWJvb2wgaXNJbmVxdWFsaXR5LCBkb3VibGUgbnVsbGZy YWMsIGRvdWJsZSAqc2VsZWMsIGRvdWJsZSAqczFkaXNqb2ludCkKK3sKKwlpZiAoY291bnQg PD0gMCkKKwkJcmV0dXJuOworCisJaWYgKGlzSW5lcXVhbGl0eSkKKwkJaW5kaXZpZHVhbF9z ID0gMS4wIC0gaW5kaXZpZHVhbF9zIC0gbnVsbGZyYWM7CisKKwlDTEFNUF9QUk9CQUJJTElU WShpbmRpdmlkdWFsX3MpOworCisJaWYgKHVzZU9yKQorCXsKKwkJKnNlbGVjID0gMS4wIC0g KDEuMCAtICpzZWxlYykgKiBwb3coMS4wIC0gaW5kaXZpZHVhbF9zLCBjb3VudCk7CisJCWlm IChpc0VxdWFsaXR5KQorCQkJKnMxZGlzam9pbnQgKz0gaW5kaXZpZHVhbF9zICogY291bnQ7 CisJfQorCWVsc2UKKwl7CisJCSpzZWxlYyA9ICgqc2VsZWMpICogcG93KGluZGl2aWR1YWxf cywgY291bnQpOworCQlpZiAoaXNJbmVxdWFsaXR5KQorCQkJKnMxZGlzam9pbnQgKz0gY291 bnQgKiAoaW5kaXZpZHVhbF9zIC0gMS4wKTsKKwl9Cit9CisKIC8qCiAgKgkJc2NhbGFyYXJy YXlzZWwJCS0gU2VsZWN0aXZpdHkgb2YgU2NhbGFyQXJyYXlPcEV4cHIgTm9kZS4KICAqLwpA QCAtMjEwMiw2ICsyMTQ1LDcgQEAgc2NhbGFyYXJyYXlzZWwoUGxhbm5lckluZm8gKnJvb3Qs CiAJCQlTZWxlY3Rpdml0eSBzMiA9IC0xLjA7CiAJCQlOb2RlICAgICAgICpvdGhlcl9vcCA9 IE5VTEw7CiAJCQlib29sICAgICAgICB2YXJfb25fbGVmdDsKKwkJCWJvb2wJICAgKmVsZW1f Y29uc3QgPSBOVUxMOwogCiAJCQkvKgogCQkJICogSWYgdGhlIGNsYXVzZSBpcyBvZiB0aGUg Zm9ybSAidmFyIE9QIHNvbWV0aGluZyIgb3IKQEAgLTIxMzQsMTYgKzIxNzgsMjUgQEAgc2Nh bGFyYXJyYXlzZWwoUGxhbm5lckluZm8gKnJvb3QsCiAJCQkJCQlzMiA9IDEuMCAtIERFRkFV TFRfRVFfU0VMOwogCQkJCX0KIAotCQkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRhdGEp OwotCiAJCQkJaWYgKHMyID49IDAuMCkKIAkJCQl7CiAJCQkJCUNMQU1QX1BST0JBQklMSVRZ KHMyKTsKIAogCQkJCQlzMSA9IGNhbGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShzMiwg bnVtX2VsZW1zLCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5KTsKIAorCQkJCQlS ZWxlYXNlVmFyaWFibGVTdGF0cyh2YXJkYXRhKTsKKwogCQkJCQlyZXR1cm4gczE7CiAJCQkJ fQorCisJCQkJczEgPSBzY2FsYXJhcnJheV9tY3ZfaGFzaF9tYXRjaCgmdmFyZGF0YSwgb3Bl cmF0b3IsIGNsYXVzZS0+aW5wdXRjb2xsaWQsIHMyLAorCQkJCQkJCQkJCQkJZWxlbV92YWx1 ZXMsIGVsZW1fbnVsbHMsIG51bV9lbGVtcywgZWxlbV9jb25zdCwKKwkJCQkJCQkJCQkJCW5v bWluYWxfZWxlbWVudF90eXBlLCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5KTsK KworCQkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRhdGEpOworCisJCQkJaWYgKHMxID49 IDAuMCkKKwkJCQkJcmV0dXJuIHMxOwogCQkJfQogCQkJZWxzZQogCQkJewpAQCAtMjI1MCwx NiArMjMwMyw3OCBAQCBzY2FsYXJhcnJheXNlbChQbGFubmVySW5mbyAqcm9vdCwKIAkJCSAq IHZhcmlhYmxlLCB0aGVuIGZhbGwgYmFjayB0byBkZWZhdWx0IGNvZGUgcGF0aCB0byBjb21w dXRlCiAJCQkgKiBkZWZhdWx0IHNlbGVjdGl2aXR5LgogCQkJICovCi0JCQlpZiAoIWdldF9y ZXN0cmljdGlvbl92YXJpYWJsZShyb290LCBjbGF1c2UtPmFyZ3MsIHZhclJlbGlkLAorCQkJ aWYgKGdldF9yZXN0cmljdGlvbl92YXJpYWJsZShyb290LCBjbGF1c2UtPmFyZ3MsIHZhclJl bGlkLAogCQkJCQkJCQkJCSAmdmFyZGF0YSwgJm90aGVyX29wLCAmdmFyX29uX2xlZnQpKQor CQkJeworCQkJCURhdHVtCSAgICplbGVtX3ZhbHVlczsKKwkJCQlib29sCSAgICplbGVtX251 bGxzOworCQkJCWJvb2wJICAgKmVsZW1fY29uc3Q7CisJCQkJTGlzdENlbGwgICAqbGM7CisK KwkJCQllbGVtX3ZhbHVlcyA9IHBhbGxvY19hcnJheShEYXR1bSwgbnVtX2VsZW1zKTsKKwkJ CQllbGVtX251bGxzID0gcGFsbG9jMF9hcnJheShib29sLCBudW1fZWxlbXMpOworCQkJCWVs ZW1fY29uc3QgPSBwYWxsb2MwX2FycmF5KGJvb2wsIG51bV9lbGVtcyk7CisKKwkJCQkvKgor CQkJCSAqIEJ1aWxkIGFycmF5cyBkZXNjcmliaW5nIEFSUkFZW10gZWxlbWVudHM6CisJCQkJ ICogLSBlbGVtX3ZhbHVlczogRGF0dW0gdmFsdWUgZm9yIENvbnN0IGVsZW1lbnRzCisJCQkJ ICogLSBlbGVtX251bGxzOiB3aGV0aGVyIGVsZW1lbnQgaXMgTlVMTAorCQkJCSAqIC0gZWxl bV9jb25zdDogd2hldGhlciBlbGVtZW50IGlzIGEgQ29uc3Qgbm9kZQorCQkJCSAqLworCQkJ CWZvcmVhY2gobGMsIGFycmF5ZXhwci0+ZWxlbWVudHMpCisJCQkJeworCQkJCQlOb2RlCSpl bGVtX3ZhbHVlID0gKE5vZGUgKikgbGZpcnN0KGxjKTsKKwkJCQkJaW50CQlpID0gZm9yZWFj aF9jdXJyZW50X2luZGV4KGxjKTsKKworCQkJCQlpZiAoSXNBKGVsZW1fdmFsdWUsIENvbnN0 KSkKKwkJCQkJeworCQkJCQkJZWxlbV92YWx1ZXNbaV0gPSAoKENvbnN0ICopIGVsZW1fdmFs dWUpLT5jb25zdHZhbHVlOworCQkJCQkJZWxlbV9udWxsc1tpXSA9ICgoQ29uc3QgKikgZWxl bV92YWx1ZSktPmNvbnN0aXNudWxsOworCQkJCQkJZWxlbV9jb25zdFtpXSA9IHRydWU7CisJ CQkJCX0KKwkJCQkJZWxzZQorCQkJCQl7CisJCQkJCQllbGVtX251bGxzW2ldID0gZmFsc2U7 CisJCQkJCQllbGVtX2NvbnN0W2ldID0gZmFsc2U7CisJCQkJCX0KKworCQkJCQkvKiBTZWxl Y3Rpdml0eSBvZiAiV0hFUkUgeCBOT1QgSU4gKE5VTEwsIC4uLiApIiBpcyBhbHdheXMgMCAq LworCQkJCQlpZiAoIXVzZU9yICYmIGVsZW1fbnVsbHNbaV0pCisJCQkJCXsKKwkJCQkJCXBm cmVlKGVsZW1fdmFsdWVzKTsKKwkJCQkJCXBmcmVlKGVsZW1fbnVsbHMpOworCQkJCQkJcGZy ZWUoZWxlbV9jb25zdCk7CisKKwkJCQkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRhdGEp OworCisJCQkJCQlyZXR1cm4gKFNlbGVjdGl2aXR5KSAwLjA7CisJCQkJCX0KKwkJCQl9CisK KwkJCQkvKiBDb21wdXRlIHBlci1lbGVtZW50IHNlbGVjdGl2aXR5IHZpYSBlcXNlbCgpL25l cXNlbCBzZW1hbnRpY3MuICovCisJCQkJczIgPSB2YXJfZXFfbm9uX2NvbnN0KCZ2YXJkYXRh LCBvcGVyYXRvciwgY2xhdXNlLT5pbnB1dGNvbGxpZCwKKwkJCQkJCQkJCQkJICBvdGhlcl9v cCwgdmFyX29uX2xlZnQsIGlzSW5lcXVhbGl0eSk7CisKKwkJCQlzMSA9IHNjYWxhcmFycmF5 X21jdl9oYXNoX21hdGNoKCZ2YXJkYXRhLCBvcGVyYXRvciwgY2xhdXNlLT5pbnB1dGNvbGxp ZCwgczIsCisJCQkJCQkJCQkJCQllbGVtX3ZhbHVlcywgZWxlbV9udWxscywgbnVtX2VsZW1z LCBlbGVtX2NvbnN0LAorCQkJCQkJCQkJCQkJbm9taW5hbF9lbGVtZW50X3R5cGUsIHVzZU9y LCBpc0VxdWFsaXR5LCBpc0luZXF1YWxpdHkpOworCisJCQkJcGZyZWUoZWxlbV92YWx1ZXMp OworCQkJCXBmcmVlKGVsZW1fbnVsbHMpOworCQkJCXBmcmVlKGVsZW1fY29uc3QpOworCisJ CQkJUmVsZWFzZVZhcmlhYmxlU3RhdHModmFyZGF0YSk7CisKKwkJCQlpZiAoczEgPj0gMC4w KQorCQkJCQlyZXR1cm4gczE7CisJCQl9CisJCQllbHNlCiAJCQl7CiAJCQkJczIgPSAoaXNJ bmVxdWFsaXR5KSA/ICgxLjAgLSBERUZBVUxUX0VRX1NFTCkgOiBERUZBVUxUX0VRX1NFTDsK IAkJCQlzMSA9IGNhbGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShzMiwgbnVtX2VsZW1z LCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5KTsKIAogCQkJCXJldHVybiBzMTsK IAkJCX0KLQkJCWVsc2UKLQkJCQlSZWxlYXNlVmFyaWFibGVTdGF0cyh2YXJkYXRhKTsKIAkJ fQogCiAJCS8qCkBAIC0yMzc2LDYgKzI0OTEsMzIxIEBAIHNjYWxhcmFycmF5c2VsKFBsYW5u ZXJJbmZvICpyb290LAogCXJldHVybiBzMTsKIH0KIAorLyoKKyAqIEVzdGltYXRlIHNlbGVj dGl2aXR5IG9mIGEgU2NhbGFyQXJyYXlPcEV4cHIgKEFOWS9BTEwpIHVzaW5nIE1DViBzdGF0 aXN0aWNzCisgKiB3aXRoIGhhc2gtYmFzZWQgbWF0Y2hpbmcuCisgKgorICogVGhpcyBmdW5j dGlvbiBmb2xsb3dzIHRoZSBzYW1lIHByb2JhYmlsaXR5IG1vZGVsIGFzIHRoZSBnZW5lcmlj CisgKiBTY2FsYXJBcnJheU9wRXhwciBzZWxlY3Rpdml0eSBjb2RlIChpbmRlcGVuZGVudCBv ciBkaXNqb2ludCBwcm9iYWJpbGl0aWVzCisgKiBmb3IgT1IvQU5EIGNvbWJpbmF0aW9ucyks IGJ1dCBhdHRlbXB0cyB0byBzcGVlZCB1cCBtYXRjaGluZyBiZXR3ZWVuCisgKiBJTi1saXN0 IGVsZW1lbnRzIGFuZCB0aGUgY29sdW1uJ3MgbW9zdC1jb21tb24tdmFsdWVzIChNQ1YpIHN0 YXRpc3RpY3MgYnkKKyAqIHVzaW5nIGhhc2hpbmcgaW5zdGVhZCBvZiBuZXN0ZWQgbG9vcHMu CisgKgorICogTUNWIHN0YXRpc3RpY3MgYXJlIHVzZWQgb25seSB0byBvYnRhaW4gcGVyLXZh bHVlIHNlbGVjdGl2aXRpZXMgZm9yCisgKiBjb25zdGFudHMgdGhhdCBtYXRjaCBNQ1YgZW50 cmllcy4gIEFsbCBwcm9iYWJpbGl0aWVzIGFyZSBjb21iaW5lZCB1c2luZworICogdGhlIHN0 YW5kYXJkIEFOWS9BTEwgZm9ybXVsYXMsIGV4YWN0bHkgYXMgaW4gdGhlIGdlbmVyaWMgZXN0 aW1hdG9yLgorICoKKyAqIFRoZSBmdW5jdGlvbiBtYXkgcmV0dXJuIC0xLjAgdG8gaW5kaWNh dGUgdGhhdCBoYXNoLWJhc2VkIE1DViBlc3RpbWF0aW9uCisgKiBpcyBub3QgYXBwbGljYWJs ZSAoZm9yIGV4YW1wbGUsIG1pc3Npbmcgc3RhdGlzdGljcywgdW5zdXBwb3J0ZWQgb3BlcmF0 b3IsCisgKiBvciB1bmF2YWlsYWJsZSBoYXNoIGZ1bmN0aW9ucyksIGluIHdoaWNoIGNhc2Ug dGhlIGNhbGxlciBzaG91bGQgZmFsbCBiYWNrCisgKiB0byB0aGUgZ2VuZXJpYyBTY2FsYXJB cnJheU9wRXhwciBzZWxlY3Rpdml0eSBlc3RpbWF0aW9uLgorICoKKyAqIElucHV0czoKKyAq CXZhcmRhdGE6IHN0YXRpc3RpY3MgYW5kIG1ldGFkYXRhIGZvciB0aGUgdmFyaWFibGUgYmVp bmcgZXN0aW1hdGVkCisgKglvcGVyYXRvcjogZXF1YWxpdHkgb3IgaW5lcXVhbGl0eSBvcGVy YXRvciB0byBhcHBseQorICoJY29sbGF0aW9uOiBPSUQgb2YgY29sbGF0aW9uIHRvIHVzZQor ICogIG5vbmNvbnN0X3NlbDogc2VsZWN0aXZpdHkgb2Ygbm9uLWNvbnN0IGVsZW1lbnQKKyAq CWVsZW1fdmFsdWVzOiBhcnJheSBvZiBJTi1saXN0IGVsZW1lbnQgdmFsdWVzCisgKgllbGVt X251bGxzOiBhcnJheSBpbmRpY2F0aW5nIHdoaWNoIElOLWxpc3QgZWxlbWVudHMgYXJlIE5V TEwKKyAqCWVsZW1fY29uc3Q6IGFycmF5IGluZGljYXRpbmcgd2hpY2ggSU4tbGlzdCBlbGVt ZW50cyBhcmUgQ29uc3Qgbm9kZXMuCisgKiAgICAgICAgICAgICAgYXJyYXkgaXMgTlVMTCBp ZiBhbGwgZWxlbW5ldHMgYXJlIGNvbnN0LgorICoJbnVtX2VsZW1zOiBudW1iZXIgb2YgSU4t bGlzdCBlbGVtZW50cworICoJbm9taW5hbF9lbGVtZW50X3R5cGU6IHR5cGUgb2YgSU4tbGlz dCBlbGVtZW50cworICoJdXNlT3I6IHRydWUgaWYgZWxlbWVudHMgYXJlIGNvbWJpbmVkIHVz aW5nIE9SIHNlbWFudGljcywgZmFsc2UgZm9yIEFORAorICoJaXNFcXVhbGl0eTogdHJ1ZSBp ZiB0aGUgb3BlcmF0b3IgYmVoYXZlcyBsaWtlIGVxdWFsaXR5CisgKglpc0luZXF1YWxpdHk6 IHRydWUgaWYgdGhlIG9wZXJhdG9yIGJlaGF2ZXMgbGlrZSBpbmVxdWFsaXR5CisgKgorICog UmVzdWx0OgorICoJU2VsZWN0aXZpdHkgZXN0aW1hdGUgaW4gdGhlIHJhbmdlIFswLjAsIDEu MF0sIG9yIC0xLjAgaWYgbm8gZXN0aW1hdGUKKyAqCWNvdWxkIGJlIHByb2R1Y2VkIGJ5IHRo aXMgZnVuY3Rpb24uCisgKgorICogTm90ZToKKyAqCVRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0 aGF0IHRoZSBvcGVyYXRvcuKAmXMgc2VsZWN0aXZpdHkgYmVoYXZpb3IgbWF0Y2hlcworICoJ ZXFzZWwoKS9uZXFzZWwgc2VtYW50aWNzLiAgSXQgbXVzdCBub3QgYmUgdXNlZCBmb3Igb3Bl cmF0b3JzIHdpdGggY3VzdG9tCisgKglvciBub24tc3RhbmRhcmQgc2VsZWN0aXZpdHkgYmVo YXZpb3IuCisgKi8KK3N0YXRpYyBkb3VibGUKK3NjYWxhcmFycmF5X21jdl9oYXNoX21hdGNo KFZhcmlhYmxlU3RhdERhdGEgKnZhcmRhdGEsIE9pZCBvcGVyYXRvciwgT2lkIGNvbGxhdGlv biwgU2VsZWN0aXZpdHkgbm9uY29uc3Rfc2VsLAorCQkJCQkJICAgRGF0dW0gKmVsZW1fdmFs dWVzLCBib29sICplbGVtX251bGxzLCBpbnQgbnVtX2VsZW1zLCBib29sICplbGVtX2NvbnN0 LAorCQkJCQkJICAgT2lkIG5vbWluYWxfZWxlbWVudF90eXBlLCBib29sIHVzZU9yLCBib29s IGlzRXF1YWxpdHksCisJCQkJCQkgICBib29sIGlzSW5lcXVhbGl0eSkKK3sKKwlGb3JtX3Bn X3N0YXRpc3RpYyBzdGF0czsKKwlBdHRTdGF0c1Nsb3Qgc3Nsb3Q7CisJRm1nckluZm8JZXFw cm9jOworCWRvdWJsZQkJc2VsZWMgPSAtMS4wLAorCQkJCXMxZGlzam9pbnQsCisJCQkJbnVs bGZyYWMgPSAwLjA7CisJT2lkCQkJaGFzaExlZnQgPSBJbnZhbGlkT2lkLAorCQkJCWhhc2hS aWdodCA9IEludmFsaWRPaWQsCisJCQkJb3BmdW5jb2lkOworCWJvb2wJCWhhdmVfbWN2cyA9 IGZhbHNlOworCisJb3BmdW5jb2lkID0gZ2V0X29wY29kZShvcGVyYXRvcik7CisJbWVtc2V0 KCZzc2xvdCwgMCwgc2l6ZW9mKHNzbG90KSk7CisKKwlpZiAoSGVhcFR1cGxlSXNWYWxpZCh2 YXJkYXRhLT5zdGF0c1R1cGxlKSkKKwl7CisJCWlmIChzdGF0aXN0aWNfcHJvY19zZWN1cml0 eV9jaGVjayh2YXJkYXRhLCBvcGZ1bmNvaWQpKQorCQkJaGF2ZV9tY3ZzID0gZ2V0X2F0dHN0 YXRzc2xvdCgmc3Nsb3QsIHZhcmRhdGEtPnN0YXRzVHVwbGUsCisJCQkJCQkJCQkJIFNUQVRJ U1RJQ19LSU5EX01DViwgSW52YWxpZE9pZCwKKwkJCQkJCQkJCQkgQVRUU1RBVFNTTE9UX1ZB TFVFUyB8IEFUVFNUQVRTU0xPVF9OVU1CRVJTKTsKKwl9CisKKwlpZiAoaGF2ZV9tY3ZzKQor CXsKKwkJLyoKKwkJICogSWYgdGhlIE1DViBsaXN0IGFuZCBJTi1saXN0IGFyZSBsYXJnZSBl bm91Z2gsIGFuZCB0aGUgb3BlcmF0b3IKKwkJICogc3VwcG9ydHMgaGFzaGluZywgYXR0ZW1w dCB0byB1c2UgaGFzaCBmdW5jdGlvbnMgc28gdGhhdCBNQ1bigJNJTgorCQkgKiBtYXRjaGlu ZyBjYW4gYmUgZG9uZSBpbiBPKE4rTSkgaW5zdGVhZCBvZiBPKE7Dl00pLgorCQkgKi8KKwkJ aWYgKHNzbG90Lm52YWx1ZXMgKyBudW1fZWxlbXMgPj0gTUNWX0hBU0hfVEhSRVNIT0xEKQor CQl7CisJCQlmbWdyX2luZm8ob3BmdW5jb2lkLCAmZXFwcm9jKTsKKwkJCSh2b2lkKSBnZXRf b3BfaGFzaF9mdW5jdGlvbnMob3BlcmF0b3IsICZoYXNoTGVmdCwgJmhhc2hSaWdodCk7CisJ CX0KKwl9CisKKwlpZiAoaGF2ZV9tY3ZzICYmIE9pZElzVmFsaWQoaGFzaExlZnQpICYmIE9p ZElzVmFsaWQoaGFzaFJpZ2h0KSkKKwl7CisJCS8qIFVzZSBhIGhhc2ggdGFibGUgdG8gc3Bl ZWQgdXAgdGhlIG1hdGNoaW5nICovCisJCUxPQ0FMX0ZDSU5GTyhmY2luZm8sIDIpOworCQlM T0NBTF9GQ0lORk8oaGFzaF9mY2luZm8sIDEpOworCQlNQ1ZIYXNoVGFibGVfaGFzaCAqaGFz aFRhYmxlOworCQlGbWdySW5mbwloYXNoX3Byb2M7CisJCU1DVkhhc2hDb250ZXh0IGhhc2hD b250ZXh0OworCQlkb3VibGUJCXN1bWFsbGNvbW1vbiA9IDAuMCwKKwkJCQkJbm9ubWN2X3Nl bGVjID0gMC4wOworCQlib29sCQlpc2RlZmF1bHQ7CisJCWJvb2wJCWhhc2hfbWN2OworCQlk b3VibGUJCW90aGVyZGlzdGluY3Q7CisJCURhdHVtCSAgICphcnJheUhhc2g7CisJCURhdHVt CSAgICphcnJheVByb2JlOworCQlpbnQJCQludmFsdWVzSGFzaDsKKwkJaW50CQkJbnZhbHVl c1Byb2JlOworCQlpbnQJCQlub25tY3ZfY250ID0gbnVtX2VsZW1zOworCQlpbnQJCQlub25j b25zdF9jbnQgPSAwOworCisJCS8qIEdyYWIgdGhlIG51bGxmcmFjIGZvciB1c2UgYmVsb3cu ICovCisJCXN0YXRzID0gKEZvcm1fcGdfc3RhdGlzdGljKSBHRVRTVFJVQ1QodmFyZGF0YS0+ c3RhdHNUdXBsZSk7CisJCW51bGxmcmFjID0gc3RhdHMtPnN0YW51bGxmcmFjOworCisJCXNl bGVjID0gczFkaXNqb2ludCA9ICh1c2VPciA/IDAuMCA6IDEuMCk7CisKKwkJSW5pdEZ1bmN0 aW9uQ2FsbEluZm9EYXRhKCpmY2luZm8sICZlcXByb2MsIDIsIGNvbGxhdGlvbiwKKwkJCQkJ CQkJIE5VTEwsIE5VTEwpOworCQlmY2luZm8tPmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7CisJ CWZjaW5mby0+YXJnc1sxXS5pc251bGwgPSBmYWxzZTsKKworCQlmb3IgKGludCBpID0gMDsg aSA8IHNzbG90Lm52YWx1ZXM7IGkrKykKKwkJCXN1bWFsbGNvbW1vbiArPSBzc2xvdC5udW1i ZXJzW2ldOworCisJCS8qCisJCSAqIENvbXB1dGUgdGhlIHRvdGFsIHByb2JhYmlsaXR5IG1h c3Mgb2YgYWxsIG5vbi1NQ1YgdmFsdWVzLiBUaGlzIGlzCisJCSAqIHRoZSBwYXJ0IG9mIHRo ZSBjb2x1bW4gZGlzdHJpYnV0aW9uIG5vdCBjb3ZlcmVkIGJ5IE1DVnMuCisJCSAqLworCQlu b25tY3Zfc2VsZWMgPSAxLjAgLSBzdW1hbGxjb21tb24gLSBudWxsZnJhYzsKKwkJQ0xBTVBf UFJPQkFCSUxJVFkobm9ubWN2X3NlbGVjKTsKKworCQkvKgorCQkgKiBBcHByb3hpbWF0ZSB0 aGUgcGVyLXZhbHVlIHByb2JhYmlsaXR5IG9mIGEgbm9uLU1DViBjb25zdGFudCBieQorCQkg KiBkaXZpZGluZyB0aGUgcmVtYWluaW5nIHByb2JhYmlsaXR5IG1hc3MgYnkgdGhlIG51bWJl ciBvZiBvdGhlcgorCQkgKiBkaXN0aW5jdCB2YWx1ZXMuCisJCSAqLworCQlvdGhlcmRpc3Rp bmN0ID0gZ2V0X3ZhcmlhYmxlX251bWRpc3RpbmN0KHZhcmRhdGEsICZpc2RlZmF1bHQpIC0g c3Nsb3Qubm51bWJlcnM7CisJCWlmIChvdGhlcmRpc3RpbmN0ID4gMSkKKwkJCW5vbm1jdl9z ZWxlYyAvPSBvdGhlcmRpc3RpbmN0OworCisJCWlmIChzc2xvdC5ubnVtYmVycyA+IDAgJiYg bm9ubWN2X3NlbGVjID4gc3Nsb3QubnVtYmVyc1tzc2xvdC5ubnVtYmVycyAtIDFdKQorCQkJ bm9ubWN2X3NlbGVjID0gc3Nsb3QubnVtYmVyc1tzc2xvdC5ubnVtYmVycyAtIDFdOworCisJ CS8qIE1ha2Ugc3VyZSB3ZSBidWlsZCB0aGUgaGFzaCB0YWJsZSBvbiB0aGUgc21hbGxlciBh cnJheS4gKi8KKwkJaWYgKHNzbG90Lm52YWx1ZXMgPD0gbnVtX2VsZW1zKQorCQl7CisJCQlo YXNoX21jdiA9IHRydWU7CisJCQludmFsdWVzSGFzaCA9IHNzbG90Lm52YWx1ZXM7CisJCQlu dmFsdWVzUHJvYmUgPSBudW1fZWxlbXM7CisJCQlhcnJheUhhc2ggPSBzc2xvdC52YWx1ZXM7 CisJCQlhcnJheVByb2JlID0gZWxlbV92YWx1ZXM7CisJCX0KKwkJZWxzZQorCQl7CisJCQlo YXNoX21jdiA9IGZhbHNlOworCQkJbnZhbHVlc0hhc2ggPSBudW1fZWxlbXM7CisJCQludmFs dWVzUHJvYmUgPSBzc2xvdC5udmFsdWVzOworCQkJYXJyYXlIYXNoID0gZWxlbV92YWx1ZXM7 CisJCQlhcnJheVByb2JlID0gc3Nsb3QudmFsdWVzOworCQl9CisKKwkJZm1ncl9pbmZvKGhh c2hfbWN2ID8gaGFzaExlZnQgOiBoYXNoUmlnaHQsICZoYXNoX3Byb2MpOworCQlJbml0RnVu Y3Rpb25DYWxsSW5mb0RhdGEoKmhhc2hfZmNpbmZvLCAmaGFzaF9wcm9jLCAxLCBjb2xsYXRp b24sCisJCQkJCQkJCSBOVUxMLCBOVUxMKTsKKwkJaGFzaF9mY2luZm8tPmFyZ3NbMF0uaXNu dWxsID0gZmFsc2U7CisKKwkJaGFzaENvbnRleHQuZXF1YWxfZmNpbmZvID0gZmNpbmZvOwor CQloYXNoQ29udGV4dC5oYXNoX2ZjaW5mbyA9IGhhc2hfZmNpbmZvOworCQloYXNoQ29udGV4 dC5vcF9pc19yZXZlcnNlZCA9IHRydWU7CisJCWhhc2hDb250ZXh0Lmluc2VydF9tb2RlID0g dHJ1ZTsKKworCQlnZXRfdHlwbGVuYnl2YWwoaGFzaF9tY3YgPyBzc2xvdC52YWx1ZXR5cGUg OiBub21pbmFsX2VsZW1lbnRfdHlwZSwKKwkJCQkJCSZoYXNoQ29udGV4dC5oYXNoX3R5cGxl biwKKwkJCQkJCSZoYXNoQ29udGV4dC5oYXNoX3R5cGJ5dmFsKTsKKworCQloYXNoVGFibGUg PSBNQ1ZIYXNoVGFibGVfY3JlYXRlKEN1cnJlbnRNZW1vcnlDb250ZXh0LAorCQkJCQkJCQkJ CW52YWx1ZXNIYXNoLAorCQkJCQkJCQkJCSZoYXNoQ29udGV4dCk7CisKKwkJLyogQnVpbGQg YSBoYXNoIHRhYmxlIG92ZXIgdGhlIHNtYWxsZXIgaW5wdXQgc2lkZS4gKi8KKwkJZm9yIChp bnQgaSA9IDA7IGkgPCBudmFsdWVzSGFzaDsgaSsrKQorCQl7CisJCQlib29sCQlmb3VuZCA9 IGZhbHNlOworCQkJTUNWSGFzaEVudHJ5ICplbnRyeTsKKworCQkJLyoKKwkJCSAqIFdoZW4g aGFzaGluZyBJTi1saXN0IHZhbHVlcyAoaGFzaF9tY3YgPT0gZmFsc2UpLCB3ZSBvbmx5IGlu c2VydAorCQkJICogY29uc3RhbnQsIG5vbi1OVUxMIGVsZW1lbnRzLiAgTlVMTCBhbmQgbm9u LUNvbnN0IGVsZW1lbnRzIGFyZQorCQkJICogY291bnRlZCBzZXBhcmF0ZWx5LCBiZWNhdXNl IHRoZXkgY2Fubm90IHBhcnRpY2lwYXRlIGluIE1DVgorCQkJICogbWF0Y2hpbmcgYW5kIG11 c3QgYmUgaGFuZGxlZCBsYXRlciB1c2luZyBnZW5lcmljIHNlbGVjdGl2aXR5CisJCQkgKiBl c3RpbWF0aW9uLgorCQkJICovCisJCQlpZiAoIWhhc2hfbWN2KQorCQkJeworCQkJCWlmIChl bGVtX251bGxzW2ldKQorCQkJCXsKKwkJCQkJbm9ubWN2X2NudC0tOworCQkJCQljb250aW51 ZTsKKwkJCQl9CisKKwkJCQlpZiAoZWxlbV9jb25zdCAhPSBOVUxMICYmICFlbGVtX2NvbnN0 W2ldKQorCQkJCXsKKwkJCQkJbm9ubWN2X2NudC0tOworCQkJCQlub25jb25zdF9jbnQrKzsK KwkJCQkJY29udGludWU7CisJCQkJfQorCQkJfQorCisJCQllbnRyeSA9IE1DVkhhc2hUYWJs ZV9pbnNlcnQoaGFzaFRhYmxlLCBhcnJheUhhc2hbaV0sICZmb3VuZCk7CisKKwkJCS8qCisJ CQkgKiBlbnRyeS0+Y291bnQgdHJhY2tzIGhvdyBtYW55IHRpbWVzIHRoZSBzYW1lIHZhbHVl IGFwcGVhcnMsIHNvCisJCQkgKiB0aGF0IGR1cGxpY2F0ZSBJTi1saXN0IGVsZW1lbnRzIGNh biBiZSBmb2xkZWQgaW50byB0aGUKKwkJCSAqIHByb2JhYmlsaXR5IGNhbGN1bGF0aW9uLgor CQkJICovCisJCQlpZiAobGlrZWx5KCFmb3VuZCkpCisJCQl7CisJCQkJZW50cnktPmluZGV4 ID0gaTsKKwkJCQllbnRyeS0+Y291bnQgPSAxOworCQkJfQorCQkJZWxzZQorCQkJCWVudHJ5 LT5jb3VudCsrOworCQl9CisKKwkJaGFzaENvbnRleHQuaW5zZXJ0X21vZGUgPSBmYWxzZTsK KwkJaWYgKGhhc2hMZWZ0ICE9IGhhc2hSaWdodCkKKwkJeworCQkJZm1ncl9pbmZvKGhhc2hf bWN2ID8gaGFzaFJpZ2h0IDogaGFzaExlZnQsICZoYXNoX3Byb2MpOworCQkJLyogUmVzZXR0 aW5nIGhhc2hfZmNpbmZvIGlzIHByb2JhYmx5IHVubmVjZXNzYXJ5LCBidXQgYmUgc2FmZSAq LworCQkJSW5pdEZ1bmN0aW9uQ2FsbEluZm9EYXRhKCpoYXNoX2ZjaW5mbywgJmhhc2hfcHJv YywgMSwgY29sbGF0aW9uLAorCQkJCQkJCQkJIE5VTEwsIE5VTEwpOworCQkJaGFzaF9mY2lu Zm8tPmFyZ3NbMF0uaXNudWxsID0gZmFsc2U7CisJCX0KKworCQlmb3IgKGludCBpID0gMDsg aSA8IG52YWx1ZXNQcm9iZTsgaSsrKQorCQl7CisJCQlNQ1ZIYXNoRW50cnkgKmVudHJ5Owor CQkJU2VsZWN0aXZpdHkgczE7CisJCQlpbnQJCQludmFsdWVzbWN2OworCisJCQkvKgorCQkJ ICogV2hlbiBwcm9iaW5nIHdpdGggSU4tbGlzdCBlbGVtZW50cywgaWdub3JlIE5VTExzIGFu ZCBub24tQ29uc3QKKwkJCSAqIGV4cHJlc3Npb25zOiB0aGV5IGNhbm5vdCBiZSBtYXRjaGVk IGFnYWluc3QgTUNWcyBhbmQgd2lsbCBiZQorCQkJICogYWNjb3VudGVkIGZvciBsYXRlciBi eSBnZW5lcmljIGVzdGltYXRpb24uCisJCQkgKi8KKwkJCWlmIChoYXNoX21jdikKKwkJCXsK KwkJCQlpZiAoZWxlbV9udWxsc1tpXSkKKwkJCQl7CisJCQkJCW5vbm1jdl9jbnQtLTsKKwkJ CQkJY29udGludWU7CisJCQkJfQorCisJCQkJaWYgKGVsZW1fY29uc3QgIT0gTlVMTCAmJiAh ZWxlbV9jb25zdFtpXSkKKwkJCQl7CisJCQkJCW5vbm1jdl9jbnQtLTsKKwkJCQkJbm9uY29u c3RfY250Kys7CisJCQkJCWNvbnRpbnVlOworCQkJCX0KKwkJCX0KKworCQkJZW50cnkgPSBN Q1ZIYXNoVGFibGVfbG9va3VwKGhhc2hUYWJsZSwgYXJyYXlQcm9iZVtpXSk7CisKKwkJCS8q CisJCQkgKiBJZiBmb3VuZCwgb2J0YWluIGl0cyBNQ1YgZnJlcXVlbmN5IGFuZCByZW1lbWJl ciBob3cgbWFueSB2YWx1ZXMKKwkJCSAqIG9uIHRoZSBoYXNoZWQgc2lkZSBtYXAgdG8gdGhp cyBlbnRyeS4KKwkJCSAqLworCQkJaWYgKGVudHJ5ICE9IE5VTEwpCisJCQl7CisJCQkJczEg PSBoYXNoX21jdiA/IHNzbG90Lm51bWJlcnNbZW50cnktPmluZGV4XQorCQkJCQk6IHNzbG90 Lm51bWJlcnNbaV07CisKKwkJCQludmFsdWVzbWN2ID0gZW50cnktPmNvdW50OworCisJCQkJ YWNjdW1fc2NhbGFyYXJyYXlfcHJvYihzMSwgbnZhbHVlc21jdiwgdXNlT3IsIGlzRXF1YWxp dHksIGlzSW5lcXVhbGl0eSwKKwkJCQkJCQkJCQludWxsZnJhYywgJnNlbGVjLCAmczFkaXNq b2ludCk7CisKKwkJCQkvKiBNYXRjaGVkIHZhbHVlcyBhcmUgbm8gbG9uZ2VyIGNvbnNpZGVy ZWQgbm9uLU1DViAqLworCQkJCW5vbm1jdl9jbnQgLT0gbnZhbHVlc21jdjsKKwkJCX0KKwkJ fQorCisJCS8qCisJCSAqIEFjY291bnQgZm9yIGNvbnN0YW50IElOLWxpc3QgdmFsdWVzIHRo YXQgZGlkIG5vdCBtYXRjaCBhbnkgTUNWLgorCQkgKgorCQkgKiBFYWNoIHN1Y2ggdmFsdWUg aXMgYXNzdW1lZCB0byBoYXZlIHByb2JhYmlsaXR5ID0gbm9ubWN2X3NlbGVjLAorCQkgKiBk ZXJpdmVkIGZyb20gdGhlIHJlbWFpbmluZyAobm9uLU1DVikgcHJvYmFiaWxpdHkgbWFzcy4K KwkJICovCisJCWFjY3VtX3NjYWxhcmFycmF5X3Byb2Iobm9ubWN2X3NlbGVjLCBub25tY3Zf Y250LCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5LAorCQkJCQkJCQludWxsZnJh YywgJnNlbGVjLCAmczFkaXNqb2ludCk7CisKKwkJLyoKKwkJICogQWNjb3VudCBmb3Igbm9u LUNvbnN0IElOLWxpc3QgZWxlbWVudHMuCisJCSAqCisJCSAqIFRoZXNlIHZhbHVlcyBjYW5u b3QgYmUgbWF0Y2hlZCBhZ2FpbnN0IE1DVnMsIHNvIHdlIHJlbHkgb24gdGhlCisJCSAqIG9w ZXJhdG9yJ3MgZ2VuZXJpYyBzZWxlY3Rpdml0eSBlc3RpbWF0b3IgZm9yIGVhY2ggb2YgdGhl bS4KKwkJICovCisJCWFjY3VtX3NjYWxhcmFycmF5X3Byb2Iobm9uY29uc3Rfc2VsLCBub25j b25zdF9jbnQsIHVzZU9yLCBpc0VxdWFsaXR5LCBpc0luZXF1YWxpdHksCisJCQkJCQkJCW51 bGxmcmFjLCAmc2VsZWMsICZzMWRpc2pvaW50KTsKKworCQkvKgorCQkgKiBGb3IgPSBBTlkg b3IgPD4gQUxMLCBpZiB0aGUgSU4tbGlzdCBlbGVtZW50cyBhcmUgYXNzdW1lZCBkaXN0aW5j dCwKKwkJICogdGhlIGV2ZW50cyBhcmUgZGlzam9pbnQgYW5kIHRoZSB0b3RhbCBwcm9iYWJp bGl0eSBpcyB0aGUgc3VtIG9mCisJCSAqIGluZGl2aWR1YWwgcHJvYmFiaWxpdGllcy4gIFVz ZSB0aGF0IGVzdGltYXRlIGlmIGl0IGxpZXMgaW4gWzAsMV0uCisJCSAqLworCQlpZiAoKHVz ZU9yID8gaXNFcXVhbGl0eSA6IGlzSW5lcXVhbGl0eSkgJiYKKwkJCXMxZGlzam9pbnQgPj0g MC4wICYmIHMxZGlzam9pbnQgPD0gMS4wKQorCQkJc2VsZWMgPSBzMWRpc2pvaW50OworCisJ CUNMQU1QX1BST0JBQklMSVRZKHNlbGVjKTsKKworCQlNQ1ZIYXNoVGFibGVfZGVzdHJveSho YXNoVGFibGUpOworCX0KKworCWlmIChoYXZlX21jdnMpCisJCWZyZWVfYXR0c3RhdHNzbG90 KCZzc2xvdCk7CisKKwlyZXR1cm4gc2VsZWM7Cit9CisKIC8qCiAgKiBFc3RpbWF0ZSBudW1i ZXIgb2YgZWxlbWVudHMgaW4gdGhlIGFycmF5IHlpZWxkZWQgYnkgYW4gZXhwcmVzc2lvbi4K ICAqCkBAIC0yNjEyLDcgKzMwNDIsNyBAQCBlcWpvaW5zZWwoUEdfRlVOQ1RJT05fQVJHUykK IAkJICogSWYgdGhlIE1DViBsaXN0cyBhcmUgbG9uZyBlbm91Z2ggdG8ganVzdGlmeSBoYXNo aW5nLCB0cnkgdG8gbG9vayB1cAogCQkgKiBoYXNoIGZ1bmN0aW9ucyBmb3IgdGhlIGpvaW4g b3BlcmF0b3IuCiAJCSAqLwotCQlpZiAoKHNzbG90MS5udmFsdWVzICsgc3Nsb3QyLm52YWx1 ZXMpID49IEVRSk9JTlNFTF9NQ1ZfSEFTSF9USFJFU0hPTEQpCisJCWlmICgoc3Nsb3QxLm52 YWx1ZXMgKyBzc2xvdDIubnZhbHVlcykgPj0gTUNWX0hBU0hfVEhSRVNIT0xEKQogCQkJKHZv aWQpIGdldF9vcF9oYXNoX2Z1bmN0aW9ucyhvcGVyYXRvciwgJmhhc2hMZWZ0LCAmaGFzaFJp Z2h0KTsKIAl9CiAJZWxzZQotLSAKMi4zNC4xCgo= --------------ve0uhGe6VpGttmkBJPT93NhW Content-Type: text/x-patch; charset=UTF-8; name="v6-0002-Use-O-1-selectivity-formula-for-eqsel-neqsel-IN-A.patch" Content-Disposition: attachment; filename*0="v6-0002-Use-O-1-selectivity-formula-for-eqsel-neqsel-IN-A.pa"; filename*1="tch" Content-Transfer-Encoding: base64 RnJvbSA3ZDY2ODc1MmNlYjQ5YjkwMTU3MWE5NmQxNTZlMDIxOWRhNGU3YzFmIE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBFdmRva2ltb3YgSWxpYSA8aWx5YS5ldmRva2ltb3ZA dGFudG9ybGFicy5jb20+CkRhdGU6IFdlZCwgMjUgRmViIDIwMjYgMjM6MDA6MzIgKzAzMDAK U3ViamVjdDogW1BBVENIIHY2IDIvM10gVXNlIE8oMSkgc2VsZWN0aXZpdHkgZm9ybXVsYSBm b3IgZXFzZWwvbmVxc2VsIElOL0FMTAoKUmVwbGFjZSBwZXItZWxlbWVudCBpdGVyYXRpb24g aW4gU2NhbGFyQXJyYXlPcEV4cHIgc2VsZWN0aXZpdHkKZXN0aW1hdGlvbiB3aXRoIGEgY2xv c2VkLWZvcm0gcHJvYmFiaWxpdHkgZm9ybXVsYSB3aGVuIGFsbCBlbGVtZW50cwpzaGFyZSB0 aGUgc2FtZSBlcXNlbCgpL25lcXNlbCgpIHNlbWFudGljcy4KClByZXNlcnZlcyBleGlzdGlu ZyBpbmRlcGVuZGVuY2UvZGlzam9pbnQgbW9kZWxzIHdoaWxlIHJlZHVjaW5nCnBsYW5uaW5n IGNvc3QgZm9yIGxhcmdlIElOL0FMTCBsaXN0cyBmcm9tIE8oTikgdG8gTygxKS4KClNwZWNp YWwgaGFuZGxpbmcgYWRkZWQgZm9yIHVuaXF1ZSBjb2x1bW5zIHVzaW5nIDEvcmVsdHVwbGVz LgotLS0KIHNyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jIHwgMTU3ICsrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysKIDEgZmlsZSBjaGFuZ2VkLCAxNTcgaW5zZXJ0aW9u cygrKQoKZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jIGIv c3JjL2JhY2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMKaW5kZXggZWVmM2YwMzc1YTUuLmY2 MDkxYTU3NmQ4IDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC91dGlscy9hZHQvc2VsZnVuY3Mu YworKysgYi9zcmMvYmFja2VuZC91dGlscy9hZHQvc2VsZnVuY3MuYwpAQCAtMTg0LDYgKzE4 NCw5IEBAIGdldF9yZWxhdGlvbl9zdGF0c19ob29rX3R5cGUgZ2V0X3JlbGF0aW9uX3N0YXRz X2hvb2sgPSBOVUxMOwogZ2V0X2luZGV4X3N0YXRzX2hvb2tfdHlwZSBnZXRfaW5kZXhfc3Rh dHNfaG9vayA9IE5VTEw7CiAKIHN0YXRpYyBkb3VibGUgZXFzZWxfaW50ZXJuYWwoUEdfRlVO Q1RJT05fQVJHUywgYm9vbCBuZWdhdGUpOworc3RhdGljIFNlbGVjdGl2aXR5IGNhbGN1bGF0 ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShTZWxlY3Rpdml0eSBzMiwgaW50IG51bV9lbGVtcywK KwkJCQkJCQkgIGJvb2wgdXNlT3IsCisJCQkJCQkJICBib29sIGlzRXF1YWxpdHksIGJvb2wg aXNJbmVxdWFsaXR5KTsKIHN0YXRpYyBkb3VibGUgZXFqb2luc2VsX2lubmVyKEZtZ3JJbmZv ICplcXByb2MsIE9pZCBjb2xsYXRpb24sCiAJCQkJCQkJICBPaWQgaGFzaExlZnQsIE9pZCBo YXNoUmlnaHQsCiAJCQkJCQkJICBWYXJpYWJsZVN0YXREYXRhICp2YXJkYXRhMSwgVmFyaWFi bGVTdGF0RGF0YSAqdmFyZGF0YTIsCkBAIC0xODkzLDYgKzE4OTYsNjEgQEAgc3RyaXBfYXJy YXlfY29lcmNpb24oTm9kZSAqbm9kZSkKIAlyZXR1cm4gbm9kZTsKIH0KIAorLyoKKyAqIGNh bGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eQorICoKKyAqIENvbWJpbmUgc2VsZWN0aXZp dGllcyBvZiBOIGlkZW50aWNhbCBTY2FsYXJBcnJheU9wRXhwciBlbGVtZW50cy4KKyAqCisg KiBUaGlzIGZ1bmN0aW9uIGFzc3VtZXMgdGhhdCBhbGwgZWxlbWVudHMgb2YgdGhlIElOL0FO WSBvciBBTEwgbGlzdAorICogaGF2ZSB0aGUgc2FtZSBwZXItZWxlbWVudCBzZWxlY3Rpdml0 eSBzMiwgYW5kIGNvbXB1dGVzIHRoZSBvdmVyYWxsCisgKiBzZWxlY3Rpdml0eSB3aXRob3V0 IGl0ZXJhdGluZyBvdmVyIHRoZSBlbGVtZW50cy4KKyAqCisgKiBGb3IgT1Igc2VtYW50aWNz ICh4ID0gQU5ZICguLi4pKToKKyAqICAgbWFpbiBtb2RlbCAgICAgIDogMSAtICgxIC0gczIp Xk4KKyAqICAgZGlzam9pbnQgbW9kZWwgIDogTiAqIHMyCisgKgorICogRm9yIEFORCBzZW1h bnRpY3MgKHggPD4gQUxMICguLi4pKToKKyAqICAgbWFpbiBtb2RlbCAgICAgIDogczJeTgor ICogICBkaXNqb2ludCBtb2RlbCAgOiAxIC0gTiAqICgxIC0gczIpCisgKgorICogSWYgdGhl IGRpc2pvaW50IGVzdGltYXRlIGlzIHdpdGhpbiBbMCwxXSwgaXQgaXMgcHJlZmVycmVkLgor ICogT3RoZXJ3aXNlLCB3ZSBmYWxsIGJhY2sgdG8gdGhlIG1haW4gKGluZGVwZW5kZW5jZSkg bW9kZWwuCisgKi8KK3N0YXRpYyBTZWxlY3Rpdml0eQorY2FsY3VsYXRlX2NvbWJpbmVkX3Nl bGVjdGl2aXR5KFNlbGVjdGl2aXR5IHMyLCBpbnQgbnVtX2VsZW1zLCBib29sIHVzZU9yLCBi b29sIGlzRXF1YWxpdHksIGJvb2wgaXNJbmVxdWFsaXR5KQoreworCWJvb2wJCXVzZV9kaXNq b2ludCA9IGZhbHNlOworCVNlbGVjdGl2aXR5CXMxOworCVNlbGVjdGl2aXR5CXMxZGlzam9p bnQ7CisKKwlzMSA9IHMxZGlzam9pbnQgPSAodXNlT3IgPyAwLjAgOiAxLjApOworCisJaWYg KHVzZU9yKQorCXsKKwkJaWYgKGlzRXF1YWxpdHkpCisJCXsKKwkJCXMxZGlzam9pbnQgPSBz MiAqIG51bV9lbGVtczsKKwkJCWlmIChzMWRpc2pvaW50ID49IDAuMCAmJiBzMWRpc2pvaW50 IDw9IDEuMCkKKwkJCQl1c2VfZGlzam9pbnQgPSB0cnVlOworCQl9CisJCXMxID0gdXNlX2Rp c2pvaW50ID8gczFkaXNqb2ludCA6ICgxLjAgLSBwb3coMS4wIC0gczIsIG51bV9lbGVtcykp OworCX0KKwllbHNlCisJeworCQlpZiAoaXNJbmVxdWFsaXR5KQorCQl7CisJCQlzMWRpc2pv aW50ID0gMS4wICsgbnVtX2VsZW1zICogKHMyIC0gMS4wKTsKKwkJCWlmIChzMWRpc2pvaW50 ID49IDAuMCAmJiBzMWRpc2pvaW50IDw9IDEuMCkKKwkJCQl1c2VfZGlzam9pbnQgPSB0cnVl OworCQl9CisJCXMxID0gdXNlX2Rpc2pvaW50ID8gczFkaXNqb2ludCA6IHBvdyhzMiwgbnVt X2VsZW1zKTsKKwl9CisKKwlDTEFNUF9QUk9CQUJJTElUWShzMSk7CisKKwlyZXR1cm4gczE7 Cit9CisKIC8qCiAgKgkJc2NhbGFyYXJyYXlzZWwJCS0gU2VsZWN0aXZpdHkgb2YgU2NhbGFy QXJyYXlPcEV4cHIgTm9kZS4KICAqLwpAQCAtMjAzMCw2ICsyMDg4LDcyIEBAIHNjYWxhcmFy cmF5c2VsKFBsYW5uZXJJbmZvICpyb290LAogCQkJCQkJICBlbG1sZW4sIGVsbWJ5dmFsLCBl bG1hbGlnbiwKIAkJCQkJCSAgJmVsZW1fdmFsdWVzLCAmZWxlbV9udWxscywgJm51bV9lbGVt cyk7CiAKKwkJLyoKKwkJICogVHJ5IHRvIGF2b2lkIE8oTl4yKSBzZWxlY3Rpdml0eSBjYWxj dWxhdGlvbiBmb3IgU2NhbGFyQXJyYXlPcEV4cHIuCisJCSAqCisJCSAqIEZvciBlcXVhbGl0 eS9pbmVxdWFsaXR5IG9wZXJhdG9ycyBpbiByZXN0cmljdGlvbiBjbGF1c2VzLAorCQkgKiBh dHRlbXB0IHRvIGRlcml2ZSBhIHNpbmdsZSBwZXItZWxlbWVudCBzZWxlY3Rpdml0eSAoczIp IGFuZAorCQkgKiBjb21iaW5lIGl0IGluIE8oMSkgdGltZSB1c2luZyBhIGNsb3NlZC1mb3Jt IGZvcm11bGEgaW5zdGVhZAorCQkgKiBvZiBpdGVyYXRpbmcgb3ZlciBhbGwgZWxlbWVudHMu CisJCSAqLworCQlpZiAoKGlzRXF1YWxpdHkgfHwgaXNJbmVxdWFsaXR5KSAmJiAhaXNfam9p bl9jbGF1c2UpCisJCXsKKwkJCVZhcmlhYmxlU3RhdERhdGEgdmFyZGF0YTsKKwkJCVNlbGVj dGl2aXR5IHMyID0gLTEuMDsKKwkJCU5vZGUgICAgICAgKm90aGVyX29wID0gTlVMTDsKKwkJ CWJvb2wgICAgICAgIHZhcl9vbl9sZWZ0OworCisJCQkvKgorCQkJICogSWYgdGhlIGNsYXVz ZSBpcyBvZiB0aGUgZm9ybSAidmFyIE9QIHNvbWV0aGluZyIgb3IKKwkJCSAqICJzb21ldGhp bmcgT1AgdmFyIiwgZXh0cmFjdCBzdGF0aXN0aWNzIGZvciB0aGUgdmFyaWFibGUuCisJCQkg KiBPdGhlcndpc2UsIGZhbGwgYmFjayB0byBhIGRlZmF1bHQgcGVyLWVsZW1lbnQgZXN0aW1h dGUuCisJCQkgKi8KKwkJCWlmIChnZXRfcmVzdHJpY3Rpb25fdmFyaWFibGUocm9vdCwgY2xh dXNlLT5hcmdzLCB2YXJSZWxpZCwgJnZhcmRhdGEsICZvdGhlcl9vcCwgJnZhcl9vbl9sZWZ0 KSkKKwkJCXsKKwkJCQkvKgorCQkJCSAqIEZhc3QgcGF0aCBmb3IgdW5pcXVlIGNvbHVtbnMu CisJCQkJICoKKwkJCQkgKiBJZiB0aGUgdmFyaWFibGUgaXMga25vd24gdG8gYmUgdW5pcXVl IGFuZCB0aGUgcmVsYXRpb24KKwkJCQkgKiBoYXMgYXQgbGVhc3Qgb25lIHR1cGxlLCBlcXVh bGl0eSBzZWxlY3Rpdml0eSBpcyBleGFjdGx5CisJCQkJICogMSAvIHJlbHR1cGxlcy4KKwkJ CQkgKi8KKwkJCQlpZiAodmFyZGF0YS5pc3VuaXF1ZSAmJiB2YXJkYXRhLnJlbCAmJiB2YXJk YXRhLnJlbC0+dHVwbGVzID49IDEuMCkKKwkJCQl7CisJCQkJCXMyID0gMS4wIC8gdmFyZGF0 YS5yZWwtPnR1cGxlczsKKwkJCQkJaWYgKEhlYXBUdXBsZUlzVmFsaWQodmFyZGF0YS5zdGF0 c1R1cGxlKSkKKwkJCQkJeworCQkJCQkJRm9ybV9wZ19zdGF0aXN0aWMgc3RhdHMgPSAoRm9y bV9wZ19zdGF0aXN0aWMpIEdFVFNUUlVDVCh2YXJkYXRhLnN0YXRzVHVwbGUpOworCQkJCQkJ aWYgKGlzSW5lcXVhbGl0eSkKKwkJCQkJCQlzMiA9IDEuMCAtIHMyIC0gc3RhdHMtPnN0YW51 bGxmcmFjOworCQkJCQl9CisJCQkJfQorCQkJCWVsc2UgaWYgKGlzSW5lcXVhbGl0eSkKKwkJ CQl7CisJCQkJCU9pZCBuZWdhdG9yID0gZ2V0X25lZ2F0b3Iob3BlcmF0b3IpOworCQkJCQlp ZiAoIU9pZElzVmFsaWQobmVnYXRvcikpCisJCQkJCQlzMiA9IDEuMCAtIERFRkFVTFRfRVFf U0VMOworCQkJCX0KKworCQkJCVJlbGVhc2VWYXJpYWJsZVN0YXRzKHZhcmRhdGEpOworCisJ CQkJaWYgKHMyID49IDAuMCkKKwkJCQl7CisJCQkJCUNMQU1QX1BST0JBQklMSVRZKHMyKTsK KworCQkJCQlzMSA9IGNhbGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShzMiwgbnVtX2Vs ZW1zLCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5KTsKKworCQkJCQlyZXR1cm4g czE7CisJCQkJfQorCQkJfQorCQkJZWxzZQorCQkJeworCQkJCXMyID0gKGlzSW5lcXVhbGl0 eSkgPyAoMS4wIC0gREVGQVVMVF9FUV9TRUwpIDogREVGQVVMVF9FUV9TRUw7CisJCQkJczEg PSBjYWxjdWxhdGVfY29tYmluZWRfc2VsZWN0aXZpdHkoczIsIG51bV9lbGVtcywgdXNlT3Is IGlzRXF1YWxpdHksIGlzSW5lcXVhbGl0eSk7CisKKwkJCQlyZXR1cm4gczE7CisJCQl9CisJ CX0KKwogCQkvKgogCQkgKiBGb3IgZ2VuZXJpYyBvcGVyYXRvcnMsIHdlIGFzc3VtZSB0aGUg cHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyBpcwogCQkgKiBpbmRlcGVuZGVudCBmb3IgZWFjaCBh cnJheSBlbGVtZW50LiAgQnV0IGZvciAiPSBBTlkiIG9yICI8PiBBTEwiLApAQCAtMjEwNSw2 ICsyMjI5LDM5IEBAIHNjYWxhcmFycmF5c2VsKFBsYW5uZXJJbmZvICpyb290LAogCQlnZXRf dHlwbGVuYnl2YWwoYXJyYXlleHByLT5lbGVtZW50X3R5cGVpZCwKIAkJCQkJCSZlbG1sZW4s ICZlbG1ieXZhbCk7CiAKKwkJLyoKKwkJICogVHJ5IHRvIGF2b2lkIE8oTl4yKSBzZWxlY3Rp dml0eSBjYWxjdWxhdGlvbiBmb3IgU2NhbGFyQXJyYXlPcEV4cHIuCisJCSAqCisJCSAqIEZv ciBlcXVhbGl0eS9pbmVxdWFsaXR5IG9wZXJhdG9ycyBpbiByZXN0cmljdGlvbiBjbGF1c2Vz LAorCQkgKiBhdHRlbXB0IHRvIGRlcml2ZSBhIHNpbmdsZSBwZXItZWxlbWVudCBzZWxlY3Rp dml0eSAoczIpIGFuZAorCQkgKiBjb21iaW5lIGl0IGluIE8oMSkgdGltZSB1c2luZyBhIGNs b3NlZC1mb3JtIGZvcm11bGEgaW5zdGVhZAorCQkgKiBvZiBpdGVyYXRpbmcgb3ZlciBhbGwg ZWxlbWVudHMuCisJCSAqLworCQlpZiAoKGlzRXF1YWxpdHkgfHwgaXNJbmVxdWFsaXR5KSAm JiAhaXNfam9pbl9jbGF1c2UpCisJCXsKKwkJCVZhcmlhYmxlU3RhdERhdGEgdmFyZGF0YTsK KwkJCVNlbGVjdGl2aXR5IHMyID0gLTEuMDsKKwkJCU5vZGUJKm90aGVyX29wID0gTlVMTDsK KwkJCWJvb2wJdmFyX29uX2xlZnQ7CisJCQlpbnQJbnVtX2VsZW1zID0gbGlzdF9sZW5ndGgo YXJyYXlleHByLT5lbGVtZW50cyk7CisKKwkJCS8qCisJCQkgKiBJZiBleHByZXNzaW9uIGlz IG5vdCB2YXJpYWJsZSA9IHNvbWV0aGluZyBvciBzb21ldGhpbmcgPQorCQkJICogdmFyaWFi bGUsIHRoZW4gZmFsbCBiYWNrIHRvIGRlZmF1bHQgY29kZSBwYXRoIHRvIGNvbXB1dGUKKwkJ CSAqIGRlZmF1bHQgc2VsZWN0aXZpdHkuCisJCQkgKi8KKwkJCWlmICghZ2V0X3Jlc3RyaWN0 aW9uX3ZhcmlhYmxlKHJvb3QsIGNsYXVzZS0+YXJncywgdmFyUmVsaWQsCisJCQkJCQkJCQkJ ICZ2YXJkYXRhLCAmb3RoZXJfb3AsICZ2YXJfb25fbGVmdCkpCisJCQl7CisJCQkJczIgPSAo aXNJbmVxdWFsaXR5KSA/ICgxLjAgLSBERUZBVUxUX0VRX1NFTCkgOiBERUZBVUxUX0VRX1NF TDsKKwkJCQlzMSA9IGNhbGN1bGF0ZV9jb21iaW5lZF9zZWxlY3Rpdml0eShzMiwgbnVtX2Vs ZW1zLCB1c2VPciwgaXNFcXVhbGl0eSwgaXNJbmVxdWFsaXR5KTsKKworCQkJCXJldHVybiBz MTsKKwkJCX0KKwkJCWVsc2UKKwkJCQlSZWxlYXNlVmFyaWFibGVTdGF0cyh2YXJkYXRhKTsK KwkJfQorCiAJCS8qCiAJCSAqIFdlIHVzZSB0aGUgYXNzdW1wdGlvbiBvZiBkaXNqb2ludCBw cm9iYWJpbGl0aWVzIGhlcmUgdG9vLCBhbHRob3VnaAogCQkgKiB0aGUgb2RkcyBvZiBlcXVh bCBhcnJheSBlbGVtZW50cyBhcmUgcmF0aGVyIGhpZ2hlciBpZiB0aGUgZWxlbWVudHMKLS0g CjIuMzQuMQoK --------------ve0uhGe6VpGttmkBJPT93NhW Content-Type: text/x-patch; charset=UTF-8; name="v6-0001-Reduce-planning-time-for-large-NOT-IN-lists-conta.patch" Content-Disposition: attachment; filename*0="v6-0001-Reduce-planning-time-for-large-NOT-IN-lists-conta.pa"; filename*1="tch" Content-Transfer-Encoding: base64 RnJvbSBjNmNjMzA3ZTZkN2ExMzFiYTVmYzNjNTlmYzg2YmEwZGY2NzY4YTQzIE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBFdmRva2ltb3YgSWxpYSA8aWx5YS5ldmRva2ltb3ZA dGFudG9ybGFicy5jb20+CkRhdGU6IFdlZCwgMjUgRmViIDIwMjYgMjI6NTg6MzIgKzAzMDAK U3ViamVjdDogW1BBVENIIHY2IDEvM10gUmVkdWNlIHBsYW5uaW5nIHRpbWUgZm9yIGxhcmdl IE5PVCBJTiBsaXN0cyBjb250YWluaW5nCiAgIE5VTEwKCkZvciB4IDw+IEFMTCAoLi4uKSAv IHggTk9UIElOICguLi4pLCB0aGUgcHJlc2VuY2Ugb2YgYSBOVUxMIGVsZW1lbnQKbWFrZXMg dGhlIHNlbGVjdGl2aXR5IDAuMC4KClRoZSBwbGFubmVyIGN1cnJlbnRseSBzdGlsbCBpdGVy YXRlcyBvdmVyIGFsbCBlbGVtZW50cyBhbmQgY29tcHV0ZXMKcGVyLWVsZW1lbnQgc2VsZWN0 aXZpdHksIGV2ZW4gdGhvdWdoIHRoZSBmaW5hbCByZXN1bHQgaXMga25vd24uCgpBZGQgYW4g ZWFybHkgTlVMTCBjaGVjayBmb3IgY29uc3RhbnQgYXJyYXlzIGFuZCBpbW1lZGlhdGVseSBy ZXR1cm4KMC4wIHVuZGVyIEFMTCBzZW1hbnRpY3MuCgpUaGlzIHJlZHVjZXMgcGxhbm5pbmcg dGltZSBmb3IgbGFyZ2UgTk9UIElOIC8gPD4gQUxMIGxpc3RzIHdpdGhvdXQKY2hhbmdpbmcg c2VtYW50aWNzLgotLS0KIHNyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5jcy5jICAgICAg ICAgIHwgIDkgKysrKysKIHNyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvZXhwcmVzc2lvbnMu b3V0IHwgNDQgKysrKysrKysrKysrKysrKysrKysrKysKIHNyYy90ZXN0L3JlZ3Jlc3Mvc3Fs L2V4cHJlc3Npb25zLnNxbCAgICAgIHwgNDEgKysrKysrKysrKysrKysrKysrKysrCiAzIGZp bGVzIGNoYW5nZWQsIDk0IGluc2VydGlvbnMoKykKCmRpZmYgLS1naXQgYS9zcmMvYmFja2Vu ZC91dGlscy9hZHQvc2VsZnVuY3MuYyBiL3NyYy9iYWNrZW5kL3V0aWxzL2FkdC9zZWxmdW5j cy5jCmluZGV4IDI5ZmVjNjU1NTkzLi5lZWYzZjAzNzVhNSAxMDA2NDQKLS0tIGEvc3JjL2Jh Y2tlbmQvdXRpbHMvYWR0L3NlbGZ1bmNzLmMKKysrIGIvc3JjL2JhY2tlbmQvdXRpbHMvYWR0 L3NlbGZ1bmNzLmMKQEAgLTIwMTgsNiArMjAxOCwxMSBAQCBzY2FsYXJhcnJheXNlbChQbGFu bmVySW5mbyAqcm9vdCwKIAkJaWYgKGFycmF5aXNudWxsKQkJLyogcXVhbCBjYW4ndCBzdWNj ZWVkIGlmIG51bGwgYXJyYXkgKi8KIAkJCXJldHVybiAoU2VsZWN0aXZpdHkpIDAuMDsKIAkJ YXJyYXl2YWwgPSBEYXR1bUdldEFycmF5VHlwZVAoYXJyYXlkYXR1bSk7CisKKwkJLyogU2Vs ZWN0aXZpdHkgb2YgIldIRVJFIHggTk9UIElOIChOVUxMLCAuLi4gKSIgaXMgYWx3YXlzIDAg Ki8KKwkJaWYgKCF1c2VPciAmJiBhcnJheV9jb250YWluc19udWxscyhhcnJheXZhbCkpCisJ CQlyZXR1cm4gKFNlbGVjdGl2aXR5KSAwLjA7CisKIAkJZ2V0X3R5cGxlbmJ5dmFsYWxpZ24o QVJSX0VMRU1UWVBFKGFycmF5dmFsKSwKIAkJCQkJCQkgJmVsbWxlbiwgJmVsbWJ5dmFsLCAm ZWxtYWxpZ24pOwogCQlkZWNvbnN0cnVjdF9hcnJheShhcnJheXZhbCwKQEAgLTIxMTUsNiAr MjEyMCwxMCBAQCBzY2FsYXJhcnJheXNlbChQbGFubmVySW5mbyAqcm9vdCwKIAkJCUxpc3QJ ICAgKmFyZ3M7CiAJCQlTZWxlY3Rpdml0eSBzMjsKIAorCQkJLyogU2VsZWN0aXZpdHkgb2Yg IldIRVJFIHggTk9UIElOIChOVUxMLCAuLi4gKSIgaXMgYWx3YXlzIDAgKi8KKwkJCWlmICgh dXNlT3IgJiYgSXNBKGVsZW0sIENvbnN0KSAmJiAoKENvbnN0ICopIGVsZW0pLT5jb25zdGlz bnVsbCkKKwkJCQlyZXR1cm4gKFNlbGVjdGl2aXR5KSAwLjA7CisKIAkJCS8qCiAJCQkgKiBU aGVvcmV0aWNhbGx5LCBpZiBlbGVtIGlzbid0IG9mIG5vbWluYWxfZWxlbWVudF90eXBlIHdl IHNob3VsZAogCQkJICogaW5zZXJ0IGEgUmVsYWJlbFR5cGUsIGJ1dCBpdCBzZWVtcyB1bmxp a2VseSB0aGF0IGFueSBvcGVyYXRvcgpkaWZmIC0tZ2l0IGEvc3JjL3Rlc3QvcmVncmVzcy9l eHBlY3RlZC9leHByZXNzaW9ucy5vdXQgYi9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL2V4 cHJlc3Npb25zLm91dAppbmRleCA5YTNjOTdiMTVhMy4uMzRmMTRhNTc3NWEgMTAwNjQ0Ci0t LSBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvZXhwcmVzc2lvbnMub3V0CisrKyBiL3Ny Yy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvZXhwcmVzc2lvbnMub3V0CkBAIC00MjYsMyArNDI2 LDQ3IEBAIHNlbGVjdCAqIGZyb20gaW50dGVzdCB3aGVyZSBhIG5vdCBpbiAoMDo6bXlpbnQs Mjo6bXlpbnQsMzo6bXlpbnQsNDo6bXlpbnQsNTo6bXlpCiAoMCByb3dzKQogCiByb2xsYmFj azsKKy0tIFRlc3QgPD4gQUxMIHdoZW4gYXJyYXkgaW5pdGlhbGx5IGNvbnRhaW5lZCBOVUxM IGJ1dCBubyBsb25nZXIgZG9lcworYmVnaW47CitjcmVhdGUgZnVuY3Rpb24gY2hlY2tfZXN0 aW1hdGVkX3Jvd3ModGV4dCkgcmV0dXJucyB0YWJsZSAoZXN0aW1hdGVkIGludCkKK2xhbmd1 YWdlIHBscGdzcWwgYXMKKyQkCitkZWNsYXJlCisgICAgbG4gdGV4dDsKKyAgICB0bXAgdGV4 dFtdOworICAgIGZpcnN0X3JvdyBib29sIDo9IHRydWU7CitiZWdpbgorICAgIGZvciBsbiBp bgorICAgICAgICBleGVjdXRlIGZvcm1hdCgnZXhwbGFpbiAlcycsICQxKQorICAgIGxvb3AK KyAgICAgICAgaWYgZmlyc3Rfcm93IHRoZW4KKyAgICAgICAgICAgIGZpcnN0X3JvdyA6PSBm YWxzZTsKKyAgICAgICAgICAgIHRtcCA6PSByZWdleHBfbWF0Y2gobG4sICdyb3dzPShcZCop Jyk7CisgICAgICAgICAgICByZXR1cm4gcXVlcnkgc2VsZWN0IHRtcFsxXTo6aW50OworICAg ICAgICBlbmQgaWY7CisgICAgZW5kIGxvb3A7CitlbmQ7CiskJDsKK2NyZWF0ZSBmdW5jdGlv biByZXBsYWNlX2VsZW0oYXJyIGludFtdLCBpZHggaW50LCB2YWwgaW50KQorcmV0dXJucyBp bnRbXSBBUyAkJAorYmVnaW4KKyAgICAgIGFycltpZHhdIDo9IHZhbDsKKyAgICAgIHJldHVy biBhcnI7CitlbmQ7CiskJCBsYW5ndWFnZSBwbHBnc3FsIGltbXV0YWJsZTsKK2NyZWF0ZSB0 YWJsZSBub3Rpbl90ZXN0IGFzIHNlbGVjdCBnZW5lcmF0ZV9zZXJpZXMoMSwgMTAwMCkgYXMg eDsKK2FuYWx5emUgbm90aW5fdGVzdDsKK3NlbGVjdCAqIGZyb20gY2hlY2tfZXN0aW1hdGVk X3Jvd3MoJ3NlbGVjdCAqIGZyb20gbm90aW5fdGVzdCB3aGVyZSB4IDw+IGFsbChhcnJheVsx LDk5LDNdKScpOworIGVzdGltYXRlZCAKKy0tLS0tLS0tLS0tCisgICAgICAgOTk3CisoMSBy b3cpCisKKy0tIHNhbWUgYXJyYXksIGNvbnN0cnVjdGVkIGZyb20gYW4gYXJyYXkgd2l0aCBh IE5VTEwKK3NlbGVjdCAqIGZyb20gY2hlY2tfZXN0aW1hdGVkX3Jvd3MoJ3NlbGVjdCAqIGZy b20gbm90aW5fdGVzdCB3aGVyZSB4IDw+IGFsbChyZXBsYWNlX2VsZW0oYXJyYXlbMSxudWxs LDNdLCAyLCA5OSkpJyk7CisgZXN0aW1hdGVkIAorLS0tLS0tLS0tLS0KKyAgICAgICA5OTcK KygxIHJvdykKKworcm9sbGJhY2s7CmRpZmYgLS1naXQgYS9zcmMvdGVzdC9yZWdyZXNzL3Nx bC9leHByZXNzaW9ucy5zcWwgYi9zcmMvdGVzdC9yZWdyZXNzL3NxbC9leHByZXNzaW9ucy5z cWwKaW5kZXggZTAyYzIxZjMzNjguLmNhOTQ4NTliYmY4IDEwMDY0NAotLS0gYS9zcmMvdGVz dC9yZWdyZXNzL3NxbC9leHByZXNzaW9ucy5zcWwKKysrIGIvc3JjL3Rlc3QvcmVncmVzcy9z cWwvZXhwcmVzc2lvbnMuc3FsCkBAIC0yMDksMyArMjA5LDQ0IEBAIHNlbGVjdCAqIGZyb20g aW50dGVzdCB3aGVyZSBhIG5vdCBpbiAoMTo6bXlpbnQsMjo6bXlpbnQsMzo6bXlpbnQsNDo6 bXlpbnQsNTo6bXlpCiBzZWxlY3QgKiBmcm9tIGludHRlc3Qgd2hlcmUgYSBub3QgaW4gKDA6 Om15aW50LDI6Om15aW50LDM6Om15aW50LDQ6Om15aW50LDU6Om15aW50LCBudWxsKTsKIAog cm9sbGJhY2s7CisKKy0tIFRlc3QgPD4gQUxMIHdoZW4gYXJyYXkgaW5pdGlhbGx5IGNvbnRh aW5lZCBOVUxMIGJ1dCBubyBsb25nZXIgZG9lcworCitiZWdpbjsKKworY3JlYXRlIGZ1bmN0 aW9uIGNoZWNrX2VzdGltYXRlZF9yb3dzKHRleHQpIHJldHVybnMgdGFibGUgKGVzdGltYXRl ZCBpbnQpCitsYW5ndWFnZSBwbHBnc3FsIGFzCiskJAorZGVjbGFyZQorICAgIGxuIHRleHQ7 CisgICAgdG1wIHRleHRbXTsKKyAgICBmaXJzdF9yb3cgYm9vbCA6PSB0cnVlOworYmVnaW4K KyAgICBmb3IgbG4gaW4KKyAgICAgICAgZXhlY3V0ZSBmb3JtYXQoJ2V4cGxhaW4gJXMnLCAk MSkKKyAgICBsb29wCisgICAgICAgIGlmIGZpcnN0X3JvdyB0aGVuCisgICAgICAgICAgICBm aXJzdF9yb3cgOj0gZmFsc2U7CisgICAgICAgICAgICB0bXAgOj0gcmVnZXhwX21hdGNoKGxu LCAncm93cz0oXGQqKScpOworICAgICAgICAgICAgcmV0dXJuIHF1ZXJ5IHNlbGVjdCB0bXBb MV06OmludDsKKyAgICAgICAgZW5kIGlmOworICAgIGVuZCBsb29wOworZW5kOworJCQ7CisK K2NyZWF0ZSBmdW5jdGlvbiByZXBsYWNlX2VsZW0oYXJyIGludFtdLCBpZHggaW50LCB2YWwg aW50KQorcmV0dXJucyBpbnRbXSBBUyAkJAorYmVnaW4KKyAgICAgIGFycltpZHhdIDo9IHZh bDsKKyAgICAgIHJldHVybiBhcnI7CitlbmQ7CiskJCBsYW5ndWFnZSBwbHBnc3FsIGltbXV0 YWJsZTsKKworY3JlYXRlIHRhYmxlIG5vdGluX3Rlc3QgYXMgc2VsZWN0IGdlbmVyYXRlX3Nl cmllcygxLCAxMDAwKSBhcyB4OworYW5hbHl6ZSBub3Rpbl90ZXN0OworCitzZWxlY3QgKiBm cm9tIGNoZWNrX2VzdGltYXRlZF9yb3dzKCdzZWxlY3QgKiBmcm9tIG5vdGluX3Rlc3Qgd2hl cmUgeCA8PiBhbGwoYXJyYXlbMSw5OSwzXSknKTsKKy0tIHNhbWUgYXJyYXksIGNvbnN0cnVj dGVkIGZyb20gYW4gYXJyYXkgd2l0aCBhIE5VTEwKK3NlbGVjdCAqIGZyb20gY2hlY2tfZXN0 aW1hdGVkX3Jvd3MoJ3NlbGVjdCAqIGZyb20gbm90aW5fdGVzdCB3aGVyZSB4IDw+IGFsbChy ZXBsYWNlX2VsZW0oYXJyYXlbMSxudWxsLDNdLCAyLCA5OSkpJyk7CisKK3JvbGxiYWNrOwpc IE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKLS0gCjIuMzQuMQoK --------------ve0uhGe6VpGttmkBJPT93NhW--