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 1wBp9W-001PSH-23 for pgsql-hackers@arkaria.postgresql.org; Sun, 12 Apr 2026 07:22:43 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wBp9U-001a7v-2y for pgsql-hackers@arkaria.postgresql.org; Sun, 12 Apr 2026 07:22:41 +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.96) (envelope-from ) id 1wBp9U-001a7n-1p for pgsql-hackers@lists.postgresql.org; Sun, 12 Apr 2026 07:22:41 +0000 Received: from mail-yx1-xb12b.google.com ([2607:f8b0:4864:20::b12b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wBp9T-00000000dM9-0VhF for pgsql-hackers@lists.postgresql.org; Sun, 12 Apr 2026 07:22:40 +0000 Received: by mail-yx1-xb12b.google.com with SMTP id 956f58d0204a3-64ebdab2ecfso451205d50.2 for ; Sun, 12 Apr 2026 00:22:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775978557; cv=none; d=google.com; s=arc-20240605; b=SnUCrwfStLDaW4K5vKp/d5LQ2fTcl87QpIziZHIOBZ18fQSkPImV0NtqZ8Odut17Uq F0oj7mc3dUqSqf07Ql1oBm9zN3Cwafm76eOGufucsYNgiOQW2WLtkNijv82Q6uXwka6V asB4qWE98qwPRmL+LAQe1XImdbyEgQK00oG8qOML2cFuxoLJ+IcdTps7dWN/dbEtBFsD iISQQjVUSu+x72HbUtIoueDVu5xcm4zAHm3u5wrUhyeMnMxToyvx5mdma5OB0Mz0fH/F ylPjmObSexjb+c336V5MrA4PQfLuOfw+lGl7vUm1FTiaWGwo6o2lOjcI0uIgMd+0bOx9 JSjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=809Hj/ig3ts8RzFFeybeISWak5YpzEcn0Xm5q1cUjlU=; fh=nwNxTtLLPTU0ewfLM7SSbrjMajMl+wwnFkCY/fi90vE=; b=GgjAGuSi8PuGf+lbFYU/RjRX+e5bWRogAN4bLMZo2qlcWhJc62Wr7P8vtbxkPajFsS 2/AA4Fp5Jc9N15zpmt42+sMEelHhE8N9hAa/1aztodJZGBOkkCRA2Pej1i+OMNwJ1Lzo FWX3qKkFOOhDD/Ynsj968JlOfzzl78v0zqIcHaCkD3xTO2/GEU25zaiQHs0ALupAQMms qTT824AyRPblCCZVK+P/XzHU/ByjiBjmrP5GcAm2WnR0TnrxwthUDjWqlFewGR70WvEB gGeG7TvIuvMfwoqUVzYmTn1vqh4uWgqln9xEbqM42S8KkKXFDWrIX9zwHKCEUakckUvU C2Vw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775978557; x=1776583357; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=809Hj/ig3ts8RzFFeybeISWak5YpzEcn0Xm5q1cUjlU=; b=SkH8Rbn/in7cFormezFqsApLnMyXPq6VyPV6NQYWgaRUB8kjH8lECbnF8DiOWfVgYX B8I2r+Bkte0C5y1RvcnzrryLx+iczERNM14N+kJLy+OuQjzx9zvjQraPMBam+GZfy7Rg IJPwJP29j2MloApj+53A2Fq2/krjPG5C58ls8LLy8EOWaLltKO3Hz4oCIG8Gj87wYsGs f+JHQz1W7SsQmU6w5LtznYHubLydyDQ+Mg2l7vGibGzcN/aOu7b+Nbu10fIJQGTluvsc tJ5/2+cUuGBc4dGjko9DrDKiYWNKDtxXm6dxGGourUWcYU8tkYgBmRK2dCNWIRaMXXes AZqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775978557; x=1776583357; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=809Hj/ig3ts8RzFFeybeISWak5YpzEcn0Xm5q1cUjlU=; b=d7n4QOS9k9OCpTO2BGfdjEwGq3jULNUgbprj+VovI6ddU73Ba76rdp7Gja+scWjZii V6tT9tFYHwyDsqJ8QCbzhbn2BUP7lxOJpkjLu1IHr4awYbLFDS/ME0xcM5KDyxGZ91jG kXdLHqkQX4LU1sa0n6scB9d2X0fMvluTAC2uxn6xDYPOUz7GieSkFHiSpZMSDjKwygbS AQI2Ru8Q6L4H0bgxkaayyj+dX4dWV38h2ql+2x1jj4WHHHAgkfnOiGO6jYbm2UIaBB59 YEJP8SwfgkxAEPfHQkfEdBm5GzrlkQqwAnleGdI3XU4H/6aFCtCiXcZordjEORpUuPJs AvHw== X-Gm-Message-State: AOJu0YwkIiGq1JUdOshnWbDbXTeT+Zo/Qe0M+ibNY66aLwflqm8VUa77 n7pN28uqZ8JsvFBqgMV0hFYgahn/jzZwFQW7AxC6PwYNVCd7JvUCEz5OpWIDHod5XPgKlfhOkYa ODlNDXgpAxR/5yExXZCNA/G4czGd8DHGO0sTx4HAflQ== X-Gm-Gg: AeBDieuqkAB+hxSZrN/sgyqtpcIUaBToTDTZuIXoWzshOfTqarjyR/eYFlvaA4lsKWO dwVbeiEgEoHUxkhVbn/30iYlgBCh+cZcDQhC2CG8t1oEkyVITu77KiU3Ll5687ZGlmSGRX26qYq czYQjPLemfiGWdiD+Bq+RdLnSpTCTIY6xRr3VZkEmy9+6g1yD8ibIC4tkypnN/xxMdMUmrrjFgQ AxnndVEgLKt9pQ+Zekld/m73g4p0GMZNFOV+vzjVg9iAWL+MHuykN1MDz28OA2CbmEO5sPeXU74 AjEf9YnGzQ== X-Received: by 2002:a05:690e:d85:b0:651:8b9f:3dc5 with SMTP id 956f58d0204a3-65198b97af9mr6262341d50.6.1775978556781; Sun, 12 Apr 2026 00:22:36 -0700 (PDT) MIME-Version: 1.0 From: CharSyam Date: Sun, 12 Apr 2026 16:22:24 +0900 X-Gm-Features: AQROBzCHlMcaTdfvGTXqzQRnaahLcuM2xTDBYog_jlyln0JCx_3nasvl1qAfvfM Message-ID: Subject: [PATCH] Reduce pg_class scans in GRANT/REVOKE ON ALL TABLES IN SCHEMA To: pgsql-hackers@lists.postgresql.org Content-Type: multipart/mixed; boundary="00000000000001af5a064f3e3b32" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000001af5a064f3e3b32 Content-Type: multipart/alternative; boundary="00000000000001af5a064f3e3b30" --00000000000001af5a064f3e3b30 Content-Type: text/plain; charset="UTF-8" Hi hackers, While reading aclchk.c I noticed that objectsInSchemaToOids(), used by GRANT/REVOKE ... ON ALL TABLES IN SCHEMA, calls getRelationsInNamespace() five times for the OBJECT_TABLE case -- once per relkind (RELATION, VIEW, MATVIEW, FOREIGN_TABLE, PARTITIONED_TABLE): case OBJECT_TABLE: objs = getRelationsInNamespace(namespaceId, RELKIND_RELATION); objects = list_concat(objects, objs); objs = getRelationsInNamespace(namespaceId, RELKIND_VIEW); ... objs = getRelationsInNamespace(namespaceId, RELKIND_PARTITIONED_TABLE); objects = list_concat(objects, objs); break; pg_class does have an index on (relname, relnamespace), but there is no index matching (relnamespace, relkind), so each of those per-relkind calls falls back to a full heap scan via table_beginscan_catalog(). The work is just repeated five times. The attached patch introduces a small helper getRelationsInNamespaceMulti() that performs a single heap scan filtered by relnamespace and distributes matching tuples into per-relkind buckets supplied by the caller. Relkind filtering is done in C after each tuple is read, which is trivially cheap. The OBJECT_TABLE case uses the helper; OBJECT_SEQUENCE and OBJECT_PROPGRAPH are left on the original getRelationsInNamespace() helper because they only need a single relkind and benefit from the second ScanKey. Correctness / order preservation -------------------------------- * Result order is identical. The underlying pg_class heap (and thus its physical scan order) is the same regardless of how we filter, so each bucket ends up holding the same OIDs in the same relative order as a separate per-relkind heap scan would have produced. Concatenating the buckets in the original relkind order reproduces the previous list tuple-for-tuple. I verified this empirically. On a schema with interleaved relkinds (tables, views, matviews, partitioned tables) I ran two equivalent SQL formulations while forcing seq scans on pg_class: OLD-path model: UNION ALL of five "SELECT oid FROM pg_class WHERE relnamespace = X AND relkind = Y ORDER BY ctid" queries, one per relkind, in the same group order the code uses. NEW-path model: a single "SELECT oid FROM pg_class WHERE relnamespace = X ORDER BY ctid" bucketed by relkind and concatenated in the same group order. The two formulations produced identical OID sequences, element by element. A positional FULL JOIN between them returned zero rows. * MVCC semantics are, if anything, a bit stricter. The old code took five separate catalog scans, so in principle concurrent DDL could commit between scan N and scan N+1 and be visible to one but not another. With a single scan everything is collected under one catalog snapshot. * Locking is unchanged in kind: AccessShareLock on pg_class is still taken, just once instead of five times. Benchmark --------- This is a targeted micro-optimization, not a dramatic speedup. With 10,000 tables in a single schema (pg_class ~10,452 rows), running GRANT/REVOKE SELECT ON ALL TABLES IN SCHEMA in a loop (6 iterations, first dropped as warmup), I measured a consistent ~15% reduction in end-to-end time: baseline patched delta GRANT (avg) 88.2 ms 75.9 ms -14% REVOKE (avg) 134.9 ms 115.7 ms -14% Per-iteration numbers (ms): baseline GRANT : 92, 87, 87, 85, 89 patched GRANT : 77, 72, 72, 76, 79, 79 baseline REVOKE: 145, 144, 132, 128, 130, 128 patched REVOKE: 114, 117, 112, 120, 112, 119 The absolute savings are small because most of the time in these commands is spent updating per-relation ACL tuples, not scanning pg_class. For schemas with only a handful of relations the effect is not measurable. The change is aimed at multi-tenant / partition-heavy installations that regularly issue "... ON ALL TABLES IN SCHEMA ..." statements over large catalogs. Testing ------- Both `make check` and `make check-world` pass cleanly with the patch applied on top of current master (all suites green, no new failures). TAP tests were not exercised (tree configured without --enable-tap-tests); I can rerun with TAP enabled if that is useful. The patch is attached (against master). Feedback and review welcome -- in particular I'd like to know if anyone sees a correctness concern I missed, or prefers a different shape for the helper (e.g. returning a single flat list rather than per-relkind buckets). Thanks, charsyam --00000000000001af5a064f3e3b30 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi hackers,

=C2=A0 While reading aclchk.c I noticed= that objectsInSchemaToOids(), used
=C2=A0 by GRANT/REVOKE ... ON ALL TA= BLES IN SCHEMA, calls
=C2=A0 getRelationsInNamespace() five times for th= e OBJECT_TABLE case --
=C2=A0 once per relkind (RELATION, VIEW, MATVIEW,= FOREIGN_TABLE,
=C2=A0 PARTITIONED_TABLE):

=C2=A0 =C2=A0 =C2=A0 c= ase OBJECT_TABLE:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 objs =3D getRelatio= nsInNamespace(namespaceId, RELKIND_RELATION);
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 objects =3D list_concat(objects, objs);
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 objs =3D getRelationsInNamespace(namespaceId, RELKIND_VIEW);<= br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ...
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 objs =3D getRelationsInNamespace(namespaceId, RELKIND_PARTITIONED_TA= BLE);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 objects =3D list_concat(objects= , objs);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;

=C2=A0 pg_clas= s does have an index on (relname, relnamespace), but there
=C2=A0 is no = index matching (relnamespace, relkind), so each of those
=C2=A0 per-relk= ind calls falls back to a full heap scan via
=C2=A0 table_beginscan_cata= log().=C2=A0 The work is just repeated five times.

=C2=A0 The attach= ed patch introduces a small helper
=C2=A0 getRelationsInNamespaceMulti()= that performs a single heap scan
=C2=A0 filtered by relnamespace and di= stributes matching tuples into
=C2=A0 per-relkind buckets supplied by th= e caller.=C2=A0 Relkind filtering is
=C2=A0 done in C after each tuple i= s read, which is trivially cheap.=C2=A0 The
=C2=A0 OBJECT_TABLE case use= s the helper; OBJECT_SEQUENCE and
=C2=A0 OBJECT_PROPGRAPH are left on th= e original getRelationsInNamespace()
=C2=A0 helper because they only nee= d a single relkind and benefit from the
=C2=A0 second ScanKey.

= =C2=A0 Correctness / order preservation
=C2=A0 -------------------------= -------
=C2=A0 =C2=A0* Result order is identical.=C2=A0 The underlying p= g_class heap (and
=C2=A0 =C2=A0 =C2=A0thus its physical scan order) is t= he same regardless of how we
=C2=A0 =C2=A0 =C2=A0filter, so each bucket = ends up holding the same OIDs in the same
=C2=A0 =C2=A0 =C2=A0relative o= rder as a separate per-relkind heap scan would have
=C2=A0 =C2=A0 =C2=A0= produced.=C2=A0 Concatenating the buckets in the original relkind
=C2=A0= =C2=A0 =C2=A0order reproduces the previous list tuple-for-tuple.

= =C2=A0 =C2=A0 =C2=A0I verified this empirically.=C2=A0 On a schema with int= erleaved
=C2=A0 =C2=A0 =C2=A0relkinds (tables, views, matviews, partitio= ned tables) I ran two
=C2=A0 =C2=A0 =C2=A0equivalent SQL formulations wh= ile forcing seq scans on pg_class:

=C2=A0 =C2=A0 =C2=A0 =C2=A0OLD-pa= th model: UNION ALL of five
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"SELE= CT oid FROM pg_class
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 WHERE rel= namespace =3D X AND relkind =3D Y
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 ORDER BY ctid"
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0queries, one p= er relkind, in the same group order the code
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0uses.

=C2=A0 =C2=A0 =C2=A0 =C2=A0NEW-path model: a single
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"SELECT oid FROM pg_class
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 WHERE relnamespace =3D X
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ORDER BY ctid"
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0bucketed by relkind and concatenated in the same group
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0order.

=C2=A0 =C2=A0 =C2=A0The two fo= rmulations produced identical OID sequences, element
=C2=A0 =C2=A0 =C2= =A0by element.=C2=A0 A positional FULL JOIN between them returned zero
= =C2=A0 =C2=A0 =C2=A0rows.

=C2=A0 =C2=A0* MVCC semantics are, if anyt= hing, a bit stricter.=C2=A0 The old code
=C2=A0 =C2=A0 =C2=A0took five s= eparate catalog scans, so in principle concurrent DDL
=C2=A0 =C2=A0 =C2= =A0could commit between scan N and scan N+1 and be visible to one
=C2=A0= =C2=A0 =C2=A0but not another.=C2=A0 With a single scan everything is colle= cted
=C2=A0 =C2=A0 =C2=A0under one catalog snapshot.

=C2=A0 =C2= =A0* Locking is unchanged in kind: AccessShareLock on pg_class is
=C2=A0= =C2=A0 =C2=A0still taken, just once instead of five times.

=C2=A0 B= enchmark
=C2=A0 ---------
=C2=A0 This is a targeted micro-optimizatio= n, not a dramatic speedup.
=C2=A0 With 10,000 tables in a single schema = (pg_class ~10,452 rows),
=C2=A0 running GRANT/REVOKE SELECT ON ALL TABLE= S IN SCHEMA in a loop
=C2=A0 (6 iterations, first dropped as warmup), I = measured a consistent
=C2=A0 ~15% reduction in end-to-end time:

= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0baseline =C2=A0 =C2=A0patched =C2=A0 =C2=A0 delta
=C2=A0 =C2= =A0 =C2=A0 GRANT =C2=A0(avg) =C2=A0 =C2=A0 88.2 ms =C2=A0 =C2=A0 75.9 ms = =C2=A0 =C2=A0-14%
=C2=A0 =C2=A0 =C2=A0 REVOKE (avg) =C2=A0 =C2=A0134.9 m= s =C2=A0 =C2=A0115.7 ms =C2=A0 =C2=A0-14%

=C2=A0 Per-iteration numbe= rs (ms):

=C2=A0 =C2=A0 =C2=A0 baseline GRANT : 92, 87, 87, 85, 89=C2=A0 =C2=A0 =C2=A0 patched =C2=A0GRANT : 77, 72, 72, 76, 79, 79
=C2= =A0 =C2=A0 =C2=A0 baseline REVOKE: 145, 144, 132, 128, 130, 128
=C2=A0 = =C2=A0 =C2=A0 patched =C2=A0REVOKE: 114, 117, 112, 120, 112, 119

=C2= =A0 The absolute savings are small because most of the time in these
=C2= =A0 commands is spent updating per-relation ACL tuples, not scanning
=C2= =A0 pg_class.=C2=A0 For schemas with only a handful of relations the effect=
=C2=A0 is not measurable.=C2=A0 The change is aimed at multi-tenant /=C2=A0 partition-heavy installations that regularly issue
=C2=A0 "= ;... ON ALL TABLES IN SCHEMA ..." statements over large catalogs.
<= br>=C2=A0 Testing
=C2=A0 -------
=C2=A0 Both `make check` and `make c= heck-world` pass cleanly with the
=C2=A0 patch applied on top of current= master (all suites green, no new
=C2=A0 failures).=C2=A0 TAP tests were= not exercised (tree configured without
=C2=A0 --enable-tap-tests); I ca= n rerun with TAP enabled if that is useful.

=C2=A0 The patch is atta= ched (against master).=C2=A0 Feedback and review
=C2=A0 welcome -- in pa= rticular I'd like to know if anyone sees a
=C2=A0 correctness concer= n I missed, or prefers a different shape for the
=C2=A0 helper (e.g. ret= urning a single flat list rather than per-relkind
=C2=A0 buckets).
=C2=A0 Thanks,
=C2=A0 charsyam
--00000000000001af5a064f3e3b30-- --00000000000001af5a064f3e3b32 Content-Type: application/octet-stream; name="0001-Reduce-pg_class-scans-in-GRANT-REVOKE-ON-ALL-TABLES-.patch" Content-Disposition: attachment; filename="0001-Reduce-pg_class-scans-in-GRANT-REVOKE-ON-ALL-TABLES-.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnvfrozh0 RnJvbSAzMmU4NmRlMGUzNmE5Yjk1NDQ0MjZhYjkxYzZhZjU3ZDAyOWQwNzhjIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBjaGFyc3lhbSA8Y2hhcnN5YW1AbmF2ZXIuY29tPgpEYXRlOiBT dW4sIDEyIEFwciAyMDI2IDE2OjIwOjM1ICswOTAwClN1YmplY3Q6IFtQQVRDSF0gUmVkdWNlIHBn X2NsYXNzIHNjYW5zIGluIEdSQU5UL1JFVk9LRSBPTiBBTEwgVEFCTEVTIElOIFNDSEVNQQoKV2hl biBwcm9jZXNzaW5nIEdSQU5UL1JFVk9LRSAuLi4gT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEsCm9i amVjdHNJblNjaGVtYVRvT2lkcygpIGNhbGxlZCBnZXRSZWxhdGlvbnNJbk5hbWVzcGFjZSgpIGZp dmUgdGltZXMsCm9uY2UgcGVyIHJlbGtpbmQgKFJFTEFUSU9OLCBWSUVXLCBNQVRWSUVXLCBGT1JF SUdOX1RBQkxFLApQQVJUSVRJT05FRF9UQUJMRSkuICBwZ19jbGFzcyBkb2VzIGhhdmUgYW4gaW5k ZXggb24KKHJlbG5hbWUsIHJlbG5hbWVzcGFjZSksIGJ1dCB0aGVyZSBpcyBubyBpbmRleCBtYXRj aGluZwoocmVsbmFtZXNwYWNlLCByZWxraW5kKSwgc28gZWFjaCBvZiB0aG9zZSBwZXItcmVsa2lu ZCBjYWxscyBmYWxscwpiYWNrIHRvIGEgZnVsbCBoZWFwIHNjYW4gdmlhIHRhYmxlX2JlZ2luc2Nh bl9jYXRhbG9nKCkgLS0gaS5lLiB0aGUKY2F0YWxvZyBpcyBzY2FubmVkIGZpdmUgdGltZXMgaW4g dG90YWwuCgpJbnRyb2R1Y2UgZ2V0UmVsYXRpb25zSW5OYW1lc3BhY2VNdWx0aSgpLCB3aGljaCBw ZXJmb3JtcyBhIHNpbmdsZQpoZWFwIHNjYW4gZmlsdGVyZWQgYnkgcmVsbmFtZXNwYWNlIGFuZCBk aXN0cmlidXRlcyBtYXRjaGluZyB0dXBsZXMKaW50byBwZXItcmVsa2luZCBidWNrZXRzIHN1cHBs aWVkIGJ5IHRoZSBjYWxsZXIuICBSZWxraW5kIGZpbHRlcmluZwppcyBkb25lIGluIEMgYWZ0ZXIg ZWFjaCB0dXBsZSBpcyByZWFkLCB3aGljaCBpcyB0cml2aWFsbHkgY2hlYXAuClRoZSBPQkpFQ1Rf VEFCTEUgY2FzZSB1c2VzIHRoZSBoZWxwZXI7IE9CSkVDVF9TRVFVRU5DRSBhbmQKT0JKRUNUX1BS T1BHUkFQSCBrZWVwIGNhbGxpbmcgZ2V0UmVsYXRpb25zSW5OYW1lc3BhY2UoKSB1bmNoYW5nZWQK YmVjYXVzZSB0aGV5IG9ubHkgbmVlZCBhIHNpbmdsZSByZWxraW5kIGFuZCBiZW5lZml0IGZyb20g dGhlIHNlY29uZApTY2FuS2V5LgoKQmVoYXZpb3IgaXMgcHJlc2VydmVkOgoKKiBSZXN1bHQgb3Jk ZXIgaXMgaWRlbnRpY2FsLiAgVGhlIHVuZGVybHlpbmcgcGdfY2xhc3MgaGVhcCAoYW5kCiAgdGhl cmVmb3JlIGl0cyBwaHlzaWNhbCBzY2FuIG9yZGVyKSBpcyB0aGUgc2FtZSByZWdhcmRsZXNzIG9m IGhvdwogIHdlIGZpbHRlciwgc28gZWFjaCBidWNrZXQgZW5kcyB1cCBob2xkaW5nIGV4YWN0bHkg dGhlIE9JRHMgdGhhdAogIHRoZSBjb3JyZXNwb25kaW5nIHBlci1yZWxraW5kIGhlYXAgc2NhbiB3 b3VsZCBoYXZlIHByb2R1Y2VkLCBpbgogIHRoZSBzYW1lIG9yZGVyLiAgQ29uY2F0ZW5hdGluZyB0 aGUgYnVja2V0cyBpbiB0aGUgb3JpZ2luYWwKICByZWxraW5kIG9yZGVyIHJlcHJvZHVjZXMgdGhl IHByZXZpb3VzIGxpc3QgdHVwbGUtZm9yLXR1cGxlLgogIFRoaXMgd2FzIHZlcmlmaWVkIGVtcGly aWNhbGx5IGJ5IGNvbXBhcmluZywgb24gYSBzY2hlbWEgd2l0aAogIG1peGVkIHJlbGtpbmRzLCB0 aGUgT0lEIHNlcXVlbmNlIHByb2R1Y2VkIGJ5IHRoZSBvbGQgVU5JT04tQUxMCiAgcGF0dGVybiBh Z2FpbnN0IHRoZSBuZXcgc2luZ2xlLXNjYW4gKyBidWNrZXRlZCBwYXR0ZXJuOyB0aGUKICBzZXF1 ZW5jZXMgYXJlIGlkZW50aWNhbCBlbGVtZW50IGJ5IGVsZW1lbnQuCgoqIE1WQ0Mgc2VtYW50aWNz IGFyZSwgaWYgYW55dGhpbmcsIGEgYml0IHN0cmljdGVyOiBhbGwgcmVsa2luZHMKICBhcmUgbm93 IGNvbGxlY3RlZCB1bmRlciBhIHNpbmdsZSBjYXRhbG9nIHNuYXBzaG90IHJhdGhlciB0aGFuCiAg Zml2ZS4KCiogTG9ja2luZyBpcyB1bmNoYW5nZWQgaW4ga2luZCAtLSBBY2Nlc3NTaGFyZUxvY2sg b24gcGdfY2xhc3MgaXMKICBzdGlsbCB0YWtlbiwganVzdCBvbmNlIGluc3RlYWQgb2YgZml2ZSB0 aW1lcy4KCkEgc2ltcGxlIGJlbmNobWFyayAoMTAsMDAwIHRhYmxlcyBpbiBvbmUgc2NoZW1hLCBw Z19jbGFzcyB+MTAsNDUyCnJvd3MpIHNob3dzIGEgY29uc2lzdGVudCB+MTUlIHJlZHVjdGlvbiBp biBlbmQtdG8tZW5kIHRpbWUgb2YKR1JBTlQvUkVWT0tFIFNFTEVDVCBPTiBBTEwgVEFCTEVTIElO IFNDSEVNQToKCiAgR1JBTlQgOiA4OC4yIG1zIC0+IDc1LjkgbXMKICBSRVZPS0U6IDEzNC45IG1z IC0+IDExNS43IG1zCgpUaGUgYWJzb2x1dGUgc2F2aW5ncyBhcmUgc21hbGwgYmVjYXVzZSB0aGUg YnVsayBvZiB0aGUgdGltZSBpbgp0aGVzZSBjb21tYW5kcyBpcyBzcGVudCB1cGRhdGluZyBwZXIt cmVsYXRpb24gQUNMIHR1cGxlcywgbm90CnNjYW5uaW5nIHBnX2NsYXNzLiAgRm9yIHNjaGVtYXMg d2l0aCBvbmx5IGEgaGFuZGZ1bCBvZiByZWxhdGlvbnMKdGhlIGVmZmVjdCBpcyBub3QgbWVhc3Vy YWJsZS4gIFRoZSBjaGFuZ2UgaXMgdGhlcmVmb3JlIGEgdGFyZ2V0ZWQKaW1wcm92ZW1lbnQgZm9y IGRlcGxveW1lbnRzIHdpdGggdmVyeSBsYXJnZSBjYXRhbG9ncwoobXVsdGktdGVuYW50IC8gcGFy dGl0aW9uLWhlYXZ5IHN5c3RlbXMpIHRoYXQgZnJlcXVlbnRseSBydW4gQUxMClRBQkxFUyBJTiBT Q0hFTUEgZ3JhbnRzLgotLS0KIHNyYy9iYWNrZW5kL2NhdGFsb2cvYWNsY2hrLmMgfCA5MCArKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0KIDEgZmlsZSBjaGFuZ2VkLCA4MCBpbnNl cnRpb25zKCspLCAxMCBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC9jYXRh bG9nL2FjbGNoay5jIGIvc3JjL2JhY2tlbmQvY2F0YWxvZy9hY2xjaGsuYwppbmRleCA2NzQyNGZl M2IwYy4uYTY4ZjBhOTg5ZDQgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL2NhdGFsb2cvYWNsY2hr LmMKKysrIGIvc3JjL2JhY2tlbmQvY2F0YWxvZy9hY2xjaGsuYwpAQCAtMTI1LDYgKzEyNSwxMSBA QCBzdGF0aWMgTGlzdCAqb2JqZWN0TmFtZXNUb09pZHMoT2JqZWN0VHlwZSBvYmp0eXBlLCBMaXN0 ICpvYmpuYW1lcywKIAkJCQkJCQkgICBib29sIGlzX2dyYW50KTsKIHN0YXRpYyBMaXN0ICpvYmpl Y3RzSW5TY2hlbWFUb09pZHMoT2JqZWN0VHlwZSBvYmp0eXBlLCBMaXN0ICpuc3BuYW1lcyk7CiBz dGF0aWMgTGlzdCAqZ2V0UmVsYXRpb25zSW5OYW1lc3BhY2UoT2lkIG5hbWVzcGFjZUlkLCBjaGFy IHJlbGtpbmQpOworLyogU2luZ2xlLXNjYW4gaGVscGVyIG92ZXIgcGdfY2xhc3MgZm9yIG11bHRp cGxlIHJlbGtpbmRzIGluIG9uZSBuYW1lc3BhY2UgKi8KK3N0YXRpYyB2b2lkIGdldFJlbGF0aW9u c0luTmFtZXNwYWNlTXVsdGkoT2lkIG5hbWVzcGFjZUlkLAorCQkJCQkJCQkJCSBjb25zdCBjaGFy ICpyZWxraW5kcywKKwkJCQkJCQkJCQkgaW50IG5raW5kcywKKwkJCQkJCQkJCQkgTGlzdCAqKmJ1 Y2tldHMpOwogc3RhdGljIHZvaWQgZXhwYW5kX2NvbF9wcml2aWxlZ2VzKExpc3QgKmNvbG5hbWVz LCBPaWQgdGFibGVfb2lkLAogCQkJCQkJCQkgIEFjbE1vZGUgdGhpc19wcml2aWxlZ2VzLAogCQkJ CQkJCQkgIEFjbE1vZGUgKmNvbF9wcml2aWxlZ2VzLApAQCAtNzk3LDE2ICs4MDIsMjUgQEAgb2Jq ZWN0c0luU2NoZW1hVG9PaWRzKE9iamVjdFR5cGUgb2JqdHlwZSwgTGlzdCAqbnNwbmFtZXMpCiAJ CXN3aXRjaCAob2JqdHlwZSkKIAkJewogCQkJY2FzZSBPQkpFQ1RfVEFCTEU6Ci0JCQkJb2JqcyA9 IGdldFJlbGF0aW9uc0luTmFtZXNwYWNlKG5hbWVzcGFjZUlkLCBSRUxLSU5EX1JFTEFUSU9OKTsK LQkJCQlvYmplY3RzID0gbGlzdF9jb25jYXQob2JqZWN0cywgb2Jqcyk7Ci0JCQkJb2JqcyA9IGdl dFJlbGF0aW9uc0luTmFtZXNwYWNlKG5hbWVzcGFjZUlkLCBSRUxLSU5EX1ZJRVcpOwotCQkJCW9i amVjdHMgPSBsaXN0X2NvbmNhdChvYmplY3RzLCBvYmpzKTsKLQkJCQlvYmpzID0gZ2V0UmVsYXRp b25zSW5OYW1lc3BhY2UobmFtZXNwYWNlSWQsIFJFTEtJTkRfTUFUVklFVyk7Ci0JCQkJb2JqZWN0 cyA9IGxpc3RfY29uY2F0KG9iamVjdHMsIG9ianMpOwotCQkJCW9ianMgPSBnZXRSZWxhdGlvbnNJ bk5hbWVzcGFjZShuYW1lc3BhY2VJZCwgUkVMS0lORF9GT1JFSUdOX1RBQkxFKTsKLQkJCQlvYmpl Y3RzID0gbGlzdF9jb25jYXQob2JqZWN0cywgb2Jqcyk7Ci0JCQkJb2JqcyA9IGdldFJlbGF0aW9u c0luTmFtZXNwYWNlKG5hbWVzcGFjZUlkLCBSRUxLSU5EX1BBUlRJVElPTkVEX1RBQkxFKTsKLQkJ CQlvYmplY3RzID0gbGlzdF9jb25jYXQob2JqZWN0cywgb2Jqcyk7CisJCQkJeworCQkJCQljb25z dCBjaGFyIGtpbmRzW10gPSB7CisJCQkJCQlSRUxLSU5EX1JFTEFUSU9OLAorCQkJCQkJUkVMS0lO RF9WSUVXLAorCQkJCQkJUkVMS0lORF9NQVRWSUVXLAorCQkJCQkJUkVMS0lORF9GT1JFSUdOX1RB QkxFLAorCQkJCQkJUkVMS0lORF9QQVJUSVRJT05FRF9UQUJMRQorCQkJCQl9OworCQkJCQlMaXN0 ICpidWNrZXRzW2xlbmd0aG9mKGtpbmRzKV07CisJCQkJCWludCBpOworCisJCQkJCWZvciAoaSA9 IDA7IGkgPCAoaW50KSBsZW5ndGhvZihraW5kcyk7IGkrKykKKwkJCQkJCWJ1Y2tldHNbaV0gPSBO SUw7CisKKwkJCQkJZ2V0UmVsYXRpb25zSW5OYW1lc3BhY2VNdWx0aShuYW1lc3BhY2VJZCwga2lu ZHMsIGxlbmd0aG9mKGtpbmRzKSwgYnVja2V0cyk7CisKKwkJCQkJZm9yIChpID0gMDsgaSA8IChp bnQpIGxlbmd0aG9mKGtpbmRzKTsgaSsrKQorCQkJCQkJb2JqZWN0cyA9IGxpc3RfY29uY2F0KG9i amVjdHMsIGJ1Y2tldHNbaV0pOworCQkJCX0KIAkJCQlicmVhazsKIAkJCWNhc2UgT0JKRUNUX1NF UVVFTkNFOgogCQkJCW9ianMgPSBnZXRSZWxhdGlvbnNJbk5hbWVzcGFjZShuYW1lc3BhY2VJZCwg UkVMS0lORF9TRVFVRU5DRSk7CkBAIC05MDcsNiArOTIxLDYyIEBAIGdldFJlbGF0aW9uc0luTmFt ZXNwYWNlKE9pZCBuYW1lc3BhY2VJZCwgY2hhciByZWxraW5kKQogCXJldHVybiByZWxhdGlvbnM7 CiB9CiAKKy8qCisgKiBnZXRSZWxhdGlvbnNJbk5hbWVzcGFjZU11bHRpCisgKgorICogUGVyZm9y bSBhIHNpbmdsZSBoZWFwIHNjYW4gb3ZlciBwZ19jbGFzcyBmb3IgdGhlIGdpdmVuIG5hbWVzcGFj ZSwgYW5kCisgKiBkaXN0cmlidXRlIG1hdGNoaW5nIHR1cGxlcyBpbnRvIHBlci1yZWxraW5kIGJ1 Y2tldHMgcHJvdmlkZWQgYnkgdGhlCisgKiBjYWxsZXIuICBUaGVyZSBpcyBubyBwZ19jbGFzcyBp bmRleCBtYXRjaGluZyAocmVsbmFtZXNwYWNlLCByZWxraW5kKSwKKyAqIHNvIHRoZSBwcmV2aW91 cyBwZXItcmVsa2luZCB2YXJpYW50IGFsc28gcmVzb3J0ZWQgdG8gYSBmdWxsIGhlYXAgc2NhbjsK KyAqIHRoaXMgaGVscGVyIHNpbXBseSBjb2xsYXBzZXMgTiBzdWNoIHNjYW5zIGludG8gb25lLgor ICoKKyAqIE9yZGVyIHByZXNlcnZhdGlvbjogd2l0aGluIGVhY2ggYnVja2V0LCBlbnRyaWVzIGFw cGVhciBpbiB0aGUgb3JkZXIKKyAqIHRoZXkgd2VyZSBlbmNvdW50ZXJlZCBkdXJpbmcgdGhlIGhl YXAgc2Nhbi4gIEJlY2F1c2UgdGhlIHVuZGVybHlpbmcKKyAqIGhlYXAgKGFuZCB0aHVzIGl0cyBw aHlzaWNhbCBzY2FuIG9yZGVyKSBpcyB0aGUgc2FtZSByZWdhcmRsZXNzIG9mCisgKiBob3cgd2Ug ZmlsdGVyLCBlYWNoIGJ1Y2tldCBlbmRzIHVwIGhvbGRpbmcgdGhlIHNhbWUgT0lEcyBpbiB0aGUg c2FtZQorICogcmVsYXRpdmUgb3JkZXIgYXMgYSBzZXBhcmF0ZSBwZXItcmVsa2luZCBoZWFwIHNj YW4gd291bGQgaGF2ZQorICogcHJvZHVjZWQuICBDb25jYXRlbmF0aW5nIHRoZSBidWNrZXRzIGlu IHRoZSBjYWxsZXIncyByZXF1ZXN0ZWQKKyAqIHJlbGtpbmQgb3JkZXIgdGhlcmVmb3JlIHJlcHJv ZHVjZXMgdGhlIGxpc3QgdGhhdCB0aGUgcHJldmlvdXMgY29kZQorICogYnVpbHQgZnJvbSBOIHNl cGFyYXRlIGdldFJlbGF0aW9uc0luTmFtZXNwYWNlKCkgY2FsbHMsIHR1cGxlIGZvcgorICogdHVw bGUuCisgKi8KK3N0YXRpYyB2b2lkCitnZXRSZWxhdGlvbnNJbk5hbWVzcGFjZU11bHRpKE9pZCBu YW1lc3BhY2VJZCwgY29uc3QgY2hhciAqcmVsa2luZHMsIGludCBua2luZHMsIExpc3QgKipidWNr ZXRzKQoreworCVNjYW5LZXlEYXRhIGtleTsKKwlSZWxhdGlvbglyZWw7CisJVGFibGVTY2FuRGVz YyBzY2FuOworCUhlYXBUdXBsZQl0dXBsZTsKKwlpbnQJCQlpOworCisJLyogT3BlbiBwZ19jbGFz cyBvbmNlIGFuZCBzY2FuIGJ5IG5hbWVzcGFjZTsgZmlsdGVyIHJlbGtpbmQgaW4tY29kZSAqLwor CVNjYW5LZXlJbml0KCZrZXksCisJCQkJQW51bV9wZ19jbGFzc19yZWxuYW1lc3BhY2UsCisJCQkJ QlRFcXVhbFN0cmF0ZWd5TnVtYmVyLCBGX09JREVRLAorCQkJCU9iamVjdElkR2V0RGF0dW0obmFt ZXNwYWNlSWQpKTsKKworCXJlbCA9IHRhYmxlX29wZW4oUmVsYXRpb25SZWxhdGlvbklkLCBBY2Nl c3NTaGFyZUxvY2spOworCXNjYW4gPSB0YWJsZV9iZWdpbnNjYW5fY2F0YWxvZyhyZWwsIDEsICZr ZXkpOworCisJd2hpbGUgKCh0dXBsZSA9IGhlYXBfZ2V0bmV4dChzY2FuLCBGb3J3YXJkU2NhbkRp cmVjdGlvbikpICE9IE5VTEwpCisJeworCQlGb3JtX3BnX2NsYXNzIGNmb3JtID0gKEZvcm1fcGdf Y2xhc3MpIEdFVFNUUlVDVCh0dXBsZSk7CisJCWNoYXIJCXJrID0gY2Zvcm0tPnJlbGtpbmQ7CisK KwkJZm9yIChpID0gMDsgaSA8IG5raW5kczsgaSsrKQorCQl7CisJCQlpZiAocmsgPT0gcmVsa2lu ZHNbaV0pCisJCQl7CisJCQkJYnVja2V0c1tpXSA9IGxhcHBlbmRfb2lkKGJ1Y2tldHNbaV0sIGNm b3JtLT5vaWQpOworCQkJCWJyZWFrOworCQkJfQorCQl9CisJfQorCisJdGFibGVfZW5kc2Nhbihz Y2FuKTsKKwl0YWJsZV9jbG9zZShyZWwsIEFjY2Vzc1NoYXJlTG9jayk7Cit9CisKIAogLyoKICAq IEFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBzdGF0ZW1lbnQKLS0gCjIuNTAuMSAoQXBwbGUgR2l0 LTE1NSkKCg== --00000000000001af5a064f3e3b32--