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 1sUJXG-0025H1-K0 for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jul 2024 05:18:34 +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 1sUJXE-00A6lA-KL for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jul 2024 05:18:33 +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 1sUJXE-00A6l1-9J for pgsql-hackers@lists.postgresql.org; Thu, 18 Jul 2024 05:18:32 +0000 Received: from mail-il1-x12a.google.com ([2607:f8b0:4864:20::12a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sUJXC-00098S-FW for pgsql-hackers@lists.postgresql.org; Thu, 18 Jul 2024 05:18:32 +0000 Received: by mail-il1-x12a.google.com with SMTP id e9e14a558f8ab-3818c2d364cso1233895ab.1 for ; Wed, 17 Jul 2024 22:18:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1721279909; x=1721884709; darn=lists.postgresql.org; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=UqU8sS2UDmpGdtzBI/EATgCE4NJtTtxeL9LXsF/utD4=; b=bWEEZOeAp7o703za1uDJ28u4koeQRxzuXvfMUTpgl3y2q2NUm2hoOSfRXDBM0NBNeC C1pSZ+IxNgWEJ17ZE/Kj23J5Zx4MYm/T+qF6IBehFMTF+oCzPZyjLHnHRL1upE78omRd FSax8sNwsISFT84ImsF+785RcXOhiijoZiF+JbvlCgYXK0dsVVLzLOEAIhQWw613T1ec dicNnnq8tYLJA3Y0WwtZPqJS1vsH/SfjRygwv17q3aGox8kesRHpMsb3aSdBd1STNIOC OazjROhiLI18pVrUhu8fs0V4JiRMMOecma1iOxARHar/yI/J0Wa7PYYXHZo1PFOg6ICw g7MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721279909; x=1721884709; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=UqU8sS2UDmpGdtzBI/EATgCE4NJtTtxeL9LXsF/utD4=; b=dhmtz5vBQOq/3Uus6CtNepfKqsQ3opIoO6B33Ziz+j8EHhcDhxKdDmL26CpH5SOmEm mFPRrNn0EkLcqxKkyvqjt3gHX52jwwd8M1kZu8Z6oNx6NK50NWAKLZTzUqBilgrm3DZQ GcDSQsRnBb+NdRSAgnYhWc/wrzGk+IgszFMYY8T3db8mwxDyinfKcvw2jP3twhWHYu5s IcrnYgsffeSQcd8JfM2LI4pu9nI2dF3198PVF4+K8abapLr+dUGRx7TQnPDxLy+YpkQd 8heFG3rUzUqDZ9p8bhKqN59Lq/AL4T3xwl/OwPmpEb8+K8OdWX1LJGf74RRw7FtLm1qe +sAg== X-Gm-Message-State: AOJu0YzfWOgz+EjJk0nxS0baIULsNFudWuOth9LV3L2fuzhYThlUdeFQ xqIFUKX7fd4CPA9DXByLwL1LlH+hUU5QsHwMMJtamBpRKwLTDPS6 X-Google-Smtp-Source: AGHT+IFpqjZwaoeEl+um0jFS23K/eKKe3mx4GQAZu/k4aZ4nVXnuhdMAJnLQAPQQMEJxLd56FVw9OA== X-Received: by 2002:a92:cd86:0:b0:396:5af7:64e3 with SMTP id e9e14a558f8ab-3965af767d6mr21191525ab.15.1721279908889; Wed, 17 Jul 2024 22:18:28 -0700 (PDT) Received: from [192.168.1.40] (cm-27-145-170-29.revip12.asianet.co.th. [27.145.170.29]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-78e33dbe77esm7190660a12.31.2024.07.17.22.18.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 17 Jul 2024 22:18:28 -0700 (PDT) Content-Type: multipart/mixed; boundary="------------K00fQCkeJqxcZ1weUHMDxrka" Message-ID: <208b2729-1d8e-48d2-8a4d-ce592be0bde4@gmail.com> Date: Thu, 18 Jul 2024 12:18:24 +0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Expand applicability of aggregate's sortop optimization To: Matthias van de Meent Cc: PostgreSQL Hackers , David Rowley , ilmari@ilmari.org References: <24c11397-d9a1-4aac-a999-a79352a6a35b@gmail.com> Content-Language: en-US From: Andrei Lepikhov 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. --------------K00fQCkeJqxcZ1weUHMDxrka Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 17/7/2024 16:33, Matthias van de Meent wrote: > On Wed, 17 Jul 2024 at 05:29, Andrei Lepikhov wrote: >> As I see, the code: >> aggsortop = fetch_agg_sort_op(aggref->aggfnoid); >> if (!OidIsValid(aggsortop)) >> return false; /* not a MIN/MAX aggregate */ >> >> used twice and can be evaluated earlier to avoid duplicated code. > > The code is structured like this to make sure we only start accessing > catalogs once we know that all other reasons to bail out from this > optimization indicate we can apply the opimization. You'll notice that > I've tried to put the cheapest checks that only use caller-supplied > information first, and catalog accesses only after that. After additional research I think I get the key misunderstanding why you did so: As I see, the checks: if (list_length(aggref->aggorder) > 1) return false; if (orderClause->tleSortGroupRef != curTarget->ressortgroupref) return false; not needed at all. You already have check: if (list_length(aggref->args) != 1) and this tells us, that if we have ordering like MIN(x ORDER BY ), this ordering contains only aggregate argument x. Because if it contained some expression, the transformAggregateCall() would add this expression to agg->args by calling the transformSortClause() routine. The tleSortGroupRef is just exactly ressortgroupref - no need to recheck it one more time. Of course, it is suitable only for MIN/MAX aggregates, but we discuss only them right now. Am I wrong? If you want, you can place it as assertions (see the diff in attachment). -- regards, Andrei Lepikhov --------------K00fQCkeJqxcZ1weUHMDxrka Content-Type: text/plain; charset=UTF-8; name="rewritten-patch-v2.diff" Content-Disposition: attachment; filename="rewritten-patch-v2.diff" Content-Transfer-Encoding: base64 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL29wdGltaXplci9wbGFuL3BsYW5hZ2cuYyBiL3Ny Yy9iYWNrZW5kL29wdGltaXplci9wbGFuL3BsYW5hZ2cuYwppbmRleCBhZmI1NDQ1Yjc3Li5l MGNiZTVjOTIzIDEwMDY0NAotLS0gYS9zcmMvYmFja2VuZC9vcHRpbWl6ZXIvcGxhbi9wbGFu YWdnLmMKKysrIGIvc3JjL2JhY2tlbmQvb3B0aW1pemVyL3BsYW4vcGxhbmFnZy5jCkBAIC0y NTMsNiArMjUzLDIwIEBAIGNhbl9taW5tYXhfYWdncyhQbGFubmVySW5mbyAqcm9vdCwgTGlz dCAqKmNvbnRleHQpCiAJCWlmIChsaXN0X2xlbmd0aChhZ2dyZWYtPmFyZ3MpICE9IDEpCiAJ CQlyZXR1cm4gZmFsc2U7CQkvKiBpdCBjb3VsZG4ndCBiZSBNSU4vTUFYICovCiAKKwkJLyoK KwkJICogV2UgbWlnaHQgaW1wbGVtZW50IHRoZSBvcHRpbWl6YXRpb24gd2hlbiBhIEZJTFRF UiBjbGF1c2UgaXMgcHJlc2VudAorCQkgKiBieSBhZGRpbmcgdGhlIGZpbHRlciB0byB0aGUg cXVhbHMgb2YgdGhlIGdlbmVyYXRlZCBzdWJxdWVyeS4gIEZvcgorCQkgKiBub3csIGp1c3Qg cHVudC4KKwkJICovCisJCWlmIChhZ2dyZWYtPmFnZ2ZpbHRlciAhPSBOVUxMKQorCQkJcmV0 dXJuIGZhbHNlOworCisJCWN1clRhcmdldCA9IChUYXJnZXRFbnRyeSAqKSBsaW5pdGlhbChh Z2dyZWYtPmFyZ3MpOworCisJCWFnZ3NvcnRvcCA9IGZldGNoX2FnZ19zb3J0X29wKGFnZ3Jl Zi0+YWdnZm5vaWQpOworCQlpZiAoIU9pZElzVmFsaWQoYWdnc29ydG9wKSkKKwkJCXJldHVy biBmYWxzZTsJCS8qIG5vdCBhIE1JTi9NQVggYWdncmVnYXRlICovCisKIAkJLyoKIAkJICog T1JERVIgQlkgaXMgdXN1YWxseSBpcnJlbGV2YW50IGZvciBNSU4vTUFYLCBidXQgaXQgY2Fu IGNoYW5nZSB0aGUKIAkJICogb3V0Y29tZSBpZiB0aGUgYWdnc29ydG9wJ3Mgb3BlcmF0b3Ig Y2xhc3MgcmVjb2duaXplcyBub24taWRlbnRpY2FsCkBAIC0yNjcsMjIgKzI4MSwzNSBAQCBj YW5fbWlubWF4X2FnZ3MoUGxhbm5lckluZm8gKnJvb3QsIExpc3QgKipjb250ZXh0KQogCQkg KiBxdWlja2x5LgogCQkgKi8KIAkJaWYgKGFnZ3JlZi0+YWdnb3JkZXIgIT0gTklMKQotCQkJ cmV0dXJuIGZhbHNlOwotCQkvKiBub3RlOiB3ZSBkbyBub3QgY2FyZSBpZiBESVNUSU5DVCBp cyBtZW50aW9uZWQgLi4uICovCisJCXsKKwkJCVNvcnRHcm91cENsYXVzZSAqb3JkZXJDbGF1 c2U7CiAKLQkJLyoKLQkJICogV2UgbWlnaHQgaW1wbGVtZW50IHRoZSBvcHRpbWl6YXRpb24g d2hlbiBhIEZJTFRFUiBjbGF1c2UgaXMgcHJlc2VudAotCQkgKiBieSBhZGRpbmcgdGhlIGZp bHRlciB0byB0aGUgcXVhbHMgb2YgdGhlIGdlbmVyYXRlZCBzdWJxdWVyeS4gIEZvcgotCQkg KiBub3csIGp1c3QgcHVudC4KLQkJICovCi0JCWlmIChhZ2dyZWYtPmFnZ2ZpbHRlciAhPSBO VUxMKQotCQkJcmV0dXJuIGZhbHNlOworCQkJLyoKKwkJCSAqIElmIHRoZSBvcmRlciBjbGF1 c2UgaXMgdGhlIHNhbWUgY29sdW1uIGFzIHRoZSBvbmUgd2UncmUKKwkJCSAqIGFnZ3JlZ2F0 aW5nLCB3ZSBjYW4gc3RpbGwgdXNlIHRoZSBpbmRleDogSXQgaXMgdW5kZWZpbmVkIHdoaWNo CisJCQkgKiB2YWx1ZSBpcyBNSU4oKSBvciBNQVgoKSwgYXMgd2VsbCBhcyB3aGljaCB2YWx1 ZSBpcyBmaXJzdCBvcgorCQkJICogbGFzdCB3aGVuIHNvcnRlZC4gU28sIHdlIGNhbiBzdGls bCB1c2UgdGhlIGluZGV4IElGRiB0aGUKKwkJCSAqIGFnZ3JlZ2F0ZWQgZXhwcmVzc2lvbiBl cXVhbHMgdGhlIGV4cHJlc3Npb24gdXNlZCBpbiB0aGUKKwkJCSAqIG9yZGVyaW5nIG9wZXJh dGlvbi4KKwkJCSAqLwogCi0JCWFnZ3NvcnRvcCA9IGZldGNoX2FnZ19zb3J0X29wKGFnZ3Jl Zi0+YWdnZm5vaWQpOwotCQlpZiAoIU9pZElzVmFsaWQoYWdnc29ydG9wKSkKLQkJCXJldHVy biBmYWxzZTsJCS8qIG5vdCBhIE1JTi9NQVggYWdncmVnYXRlICovCisJCQkvKgorCQkJICog V2Ugb25seSBhY2NlcHQgYSBzaW5nbGUgYXJndW1lbnQgdG8gbWluL21heCBhZ2dyZWdhdGVz LAorCQkJICogb3JkZXJpbmdzIHRoYXQgaGF2ZSBtb3JlIGNsYXVzZXMgd29uJ3QgcHJvdmlk ZSBjb3JyZWN0IHJlc3VsdHMuCisJCQkgKi8KKwkJCUFzc2VydChsaXN0X2xlbmd0aChhZ2dy ZWYtPmFnZ29yZGVyKSA9PSAxKTsKKworCQkJb3JkZXJDbGF1c2UgPSBjYXN0Tm9kZShTb3J0 R3JvdXBDbGF1c2UsIGxpbml0aWFsKGFnZ3JlZi0+YWdnb3JkZXIpKTsKKworCQkJQXNzZXJ0 KG9yZGVyQ2xhdXNlLT50bGVTb3J0R3JvdXBSZWYgPT0gY3VyVGFyZ2V0LT5yZXNzb3J0Z3Jv dXByZWYpOworCisJCQlpZiAob3JkZXJDbGF1c2UtPnNvcnRvcCAhPSBhZ2dzb3J0b3AgJiYK KwkJCQlvcmRlckNsYXVzZS0+c29ydG9wICE9IGdldF9jb21tdXRhdG9yKGFnZ3NvcnRvcCkp CisJCQkJcmV0dXJuIGZhbHNlOworCQl9CisKKwkJLyogbm90ZTogd2UgZG8gbm90IGNhcmUg aWYgRElTVElOQ1QgaXMgbWVudGlvbmVkIC4uLiAqLwogCi0JCWN1clRhcmdldCA9IChUYXJn ZXRFbnRyeSAqKSBsaW5pdGlhbChhZ2dyZWYtPmFyZ3MpOwogCiAJCWlmIChjb250YWluX211 dGFibGVfZnVuY3Rpb25zKChOb2RlICopIGN1clRhcmdldC0+ZXhwcikpCiAJCQlyZXR1cm4g ZmFsc2U7CQkvKiBub3QgcG90ZW50aWFsbHkgaW5kZXhhYmxlICovCmRpZmYgLS1naXQgYS9z cmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL2FnZ3JlZ2F0ZXMub3V0IGIvc3JjL3Rlc3QvcmVn cmVzcy9leHBlY3RlZC9hZ2dyZWdhdGVzLm91dAppbmRleCBhNTU5NmFiMjEwLi41ZDM3NTEw ZDY0IDEwMDY0NAotLS0gYS9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL2FnZ3JlZ2F0ZXMu b3V0CisrKyBiL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvYWdncmVnYXRlcy5vdXQKQEAg LTEwMDMsNiArMTAwMyw3MSBAQCBzZWxlY3QgbWF4KHVuaXF1ZTEpIGZyb20gdGVuazEgd2hl cmUgdW5pcXVlMSA+IDQyOwogIDk5OTkKICgxIHJvdykKIAorLS0gV2hlbiBzb3J0aW5nIG9u IHRoZSBjb2x1bW4gdGhhdCdzIGJlaW5nIGFnZ3JlZ2F0ZWQsIGluZGV4ZXMgY2FuIGFsc28g YmUKKy0tIHVzZWQsIGJ1dCBvbmx5IHdoZW4gdGhlIGFnZ3JlZ2F0ZSdzIG9wZXJhdG9yIGhh cyB0aGUgc2FtZSBvcmRlcmluZyBiZWhhdmlvcgorLS0gYXMgdGhlIE9SREVSIEJZLWNsYXVz ZSwgaS5lLiBpZiBpdCBpcyBpbiB0aGUgc2FtZSBidHJlZSBvcGNsYXNzIGFzIHRoZSBvbmUK Ky0tIGNob3NlbiBmb3IgdGhlIE9SREVSIEJZIGNsYXVzZS4KK2V4cGxhaW4gKGNvc3RzIG9m ZikKKyAgc2VsZWN0IG1pbih1bmlxdWUxIE9SREVSIEJZIHVuaXF1ZTEgQVNDIE5VTExTIExB U1QpIGZyb20gdGVuazE7CisgICAgICAgICAgICAgICAgICAgICAgICAgUVVFUlkgUExBTiAg ICAgICAgICAgICAgICAgICAgICAgICAKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIFJlc3VsdAorICAgSW5pdFBsYW4g MQorICAgICAtPiAgTGltaXQKKyAgICAgICAgICAgLT4gIEluZGV4IE9ubHkgU2NhbiB1c2lu ZyB0ZW5rMV91bmlxdWUxIG9uIHRlbmsxCisgICAgICAgICAgICAgICAgIEluZGV4IENvbmQ6 ICh1bmlxdWUxIElTIE5PVCBOVUxMKQorKDUgcm93cykKKworc2VsZWN0IG1pbih1bmlxdWUx IE9SREVSIEJZIHVuaXF1ZTEgQVNDIE5VTExTIExBU1QpIGZyb20gdGVuazE7CisgbWluIAor LS0tLS0KKyAgIDAKKygxIHJvdykKKworZXhwbGFpbiAoY29zdHMgb2ZmKQorICBzZWxlY3Qg bWF4KHVuaXF1ZTEgT1JERVIgQlkgdW5pcXVlMSBVU0lORyA8KSBmcm9tIHRlbmsxOworICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBRVUVSWSBQTEFOICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyBSZXN1bHQKKyAgIEluaXRQbGFuIDEK KyAgICAgLT4gIExpbWl0CisgICAgICAgICAgIC0+ICBJbmRleCBPbmx5IFNjYW4gQmFja3dh cmQgdXNpbmcgdGVuazFfdW5pcXVlMSBvbiB0ZW5rMQorICAgICAgICAgICAgICAgICBJbmRl eCBDb25kOiAodW5pcXVlMSBJUyBOT1QgTlVMTCkKKyg1IHJvd3MpCisKK3NlbGVjdCBtYXgo dW5pcXVlMSBPUkRFUiBCWSB1bmlxdWUxIFVTSU5HIDwpIGZyb20gdGVuazE7CisgbWF4ICAK Ky0tLS0tLQorIDk5OTkKKygxIHJvdykKKworZXhwbGFpbiAoY29zdHMgb2ZmKQorICBzZWxl Y3QgbWF4KHVuaXF1ZTEgT1JERVIgQlkgdGVudGhvdXMpIGZyb20gdGVuazE7CisgICAgICAg ICAgUVVFUlkgUExBTiAgICAgICAgICAgCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCisgQWdncmVnYXRlCisgICAtPiAgU29ydAorICAgICAgICAgU29ydCBLZXk6IHRlbnRo b3VzCisgICAgICAgICAtPiAgU2VxIFNjYW4gb24gdGVuazEKKyg0IHJvd3MpCisKK3NlbGVj dCBtYXgodW5pcXVlMSBPUkRFUiBCWSB0ZW50aG91cykgZnJvbSB0ZW5rMTsKKyBtYXggIAor LS0tLS0tCisgOTk5OQorKDEgcm93KQorCistLSAgQnV0IGV2ZW4gdGhlbiwgdGhlIGluZGV4 IGNhbid0IGJlIHVzZWQgaWYgd2Ugb3JkZXIgYnkgbXVsdGlwbGUgY29sdW1ucy4KK2V4cGxh aW4gKGNvc3RzIG9mZikKKyAgc2VsZWN0IG1heCh1bmlxdWUxIE9SREVSIEJZIHVuaXF1ZTEs IHRlbnRob3VzKSBmcm9tIHRlbmsxOworICAgICAgICAgICAgIFFVRVJZIFBMQU4gICAgICAg ICAgICAgIAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorIEFnZ3Jl Z2F0ZQorICAgLT4gIFNvcnQKKyAgICAgICAgIFNvcnQgS2V5OiB1bmlxdWUxLCB0ZW50aG91 cworICAgICAgICAgLT4gIFNlcSBTY2FuIG9uIHRlbmsxCisoNCByb3dzKQorCiAtLSB0aGUg cGxhbm5lciBtYXkgY2hvb3NlIGEgZ2VuZXJpYyBhZ2dyZWdhdGUgaGVyZSBpZiBwYXJhbGxl bCBxdWVyeSBpcwogLS0gZW5hYmxlZCwgc2luY2UgdGhhdCBwbGFuIHdpbGwgYmUgcGFyYWxs ZWwgc2FmZSBhbmQgdGhlICJvcHRpbWl6ZWQiCiAtLSBwbGFuLCB3aGljaCBoYXMgYWxtb3N0 IGlkZW50aWNhbCBjb3N0LCB3aWxsIG5vdCBiZS4gIHdlIHdhbnQgdG8gdGVzdApkaWZmIC0t Z2l0IGEvc3JjL3Rlc3QvcmVncmVzcy9zcWwvYWdncmVnYXRlcy5zcWwgYi9zcmMvdGVzdC9y ZWdyZXNzL3NxbC9hZ2dyZWdhdGVzLnNxbAppbmRleCBjYTZkMWJjZmI3Li41Y2RmMzM2ZmMw IDEwMDY0NAotLS0gYS9zcmMvdGVzdC9yZWdyZXNzL3NxbC9hZ2dyZWdhdGVzLnNxbAorKysg Yi9zcmMvdGVzdC9yZWdyZXNzL3NxbC9hZ2dyZWdhdGVzLnNxbApAQCAtMzY4LDYgKzM2OCwy NCBAQCBleHBsYWluIChjb3N0cyBvZmYpCiAgIHNlbGVjdCBtYXgodW5pcXVlMSkgZnJvbSB0 ZW5rMSB3aGVyZSB1bmlxdWUxID4gNDI7CiBzZWxlY3QgbWF4KHVuaXF1ZTEpIGZyb20gdGVu azEgd2hlcmUgdW5pcXVlMSA+IDQyOwogCistLSBXaGVuIHNvcnRpbmcgb24gdGhlIGNvbHVt biB0aGF0J3MgYmVpbmcgYWdncmVnYXRlZCwgaW5kZXhlcyBjYW4gYWxzbyBiZQorLS0gdXNl ZCwgYnV0IG9ubHkgd2hlbiB0aGUgYWdncmVnYXRlJ3Mgb3BlcmF0b3IgaGFzIHRoZSBzYW1l IG9yZGVyaW5nIGJlaGF2aW9yCistLSBhcyB0aGUgT1JERVIgQlktY2xhdXNlLCBpLmUuIGlm IGl0IGlzIGluIHRoZSBzYW1lIGJ0cmVlIG9wY2xhc3MgYXMgdGhlIG9uZQorLS0gY2hvc2Vu IGZvciB0aGUgT1JERVIgQlkgY2xhdXNlLgorZXhwbGFpbiAoY29zdHMgb2ZmKQorICBzZWxl Y3QgbWluKHVuaXF1ZTEgT1JERVIgQlkgdW5pcXVlMSBBU0MgTlVMTFMgTEFTVCkgZnJvbSB0 ZW5rMTsKK3NlbGVjdCBtaW4odW5pcXVlMSBPUkRFUiBCWSB1bmlxdWUxIEFTQyBOVUxMUyBM QVNUKSBmcm9tIHRlbmsxOworZXhwbGFpbiAoY29zdHMgb2ZmKQorICBzZWxlY3QgbWF4KHVu aXF1ZTEgT1JERVIgQlkgdW5pcXVlMSBVU0lORyA8KSBmcm9tIHRlbmsxOworc2VsZWN0IG1h eCh1bmlxdWUxIE9SREVSIEJZIHVuaXF1ZTEgVVNJTkcgPCkgZnJvbSB0ZW5rMTsKK2V4cGxh aW4gKGNvc3RzIG9mZikKKyAgc2VsZWN0IG1heCh1bmlxdWUxIE9SREVSIEJZIHRlbnRob3Vz KSBmcm9tIHRlbmsxOworc2VsZWN0IG1heCh1bmlxdWUxIE9SREVSIEJZIHRlbnRob3VzKSBm cm9tIHRlbmsxOworCistLSAgQnV0IGV2ZW4gdGhlbiwgdGhlIGluZGV4IGNhbid0IGJlIHVz ZWQgaWYgd2Ugb3JkZXIgYnkgbXVsdGlwbGUgY29sdW1ucy4KK2V4cGxhaW4gKGNvc3RzIG9m ZikKKyAgc2VsZWN0IG1heCh1bmlxdWUxIE9SREVSIEJZIHVuaXF1ZTEsIHRlbnRob3VzKSBm cm9tIHRlbmsxOworCiAtLSB0aGUgcGxhbm5lciBtYXkgY2hvb3NlIGEgZ2VuZXJpYyBhZ2dy ZWdhdGUgaGVyZSBpZiBwYXJhbGxlbCBxdWVyeSBpcwogLS0gZW5hYmxlZCwgc2luY2UgdGhh dCBwbGFuIHdpbGwgYmUgcGFyYWxsZWwgc2FmZSBhbmQgdGhlICJvcHRpbWl6ZWQiCiAtLSBw bGFuLCB3aGljaCBoYXMgYWxtb3N0IGlkZW50aWNhbCBjb3N0LCB3aWxsIG5vdCBiZS4gIHdl IHdhbnQgdG8gdGVzdAo= --------------K00fQCkeJqxcZ1weUHMDxrka--