)]}'
{"id":"openstack%2Fplacement~962776","triplet_id":"openstack%2Fplacement~master~I13ab83a165c229ae57876df4570e8af25221a45e","project":"openstack/placement","branch":"master","topic":"bug/2126751","attention_set":{},"removed_from_attention_set":{"11604":{"account":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"last_update":"2025-10-15 14:36:41.000000000","reason":"Change was submitted"},"4393":{"account":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"last_update":"2025-10-15 13:25:15.000000000","reason":"\u003cGERRIT_ACCOUNT_4393\u003e replied on the change","reason_account":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"}},"9708":{"account":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"last_update":"2025-10-15 14:36:41.000000000","reason":"Change was submitted"}},"hashtags":[],"change_id":"I13ab83a165c229ae57876df4570e8af25221a45e","subject":"Prune a_c search space by invalid prefixes","status":"MERGED","created":"2025-10-02 09:43:24.000000000","updated":"2025-10-15 14:37:36.000000000","submitted":"2025-10-15 14:36:41.000000000","submitter":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"total_comment_count":149,"unresolved_comment_count":2,"has_review_started":true,"submission_id":"962776-bug/2126751","meta_rev_id":"fd0e911282748cd94a356409b7bd192630629ffe","_number":962776,"virtual_id_number":962776,"owner":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"actions":{},"labels":{"Verified":{"approved":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"all":[{"value":0,"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},{"value":0,"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},{"tag":"autogenerated:zuul:gate","value":2,"date":"2025-10-15 14:36:40.000000000","permitted_voting_range":{"min":2,"max":2},"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","default_value":0,"optional":true},"Code-Review":{"approved":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"all":[{"value":0,"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},{"value":2,"date":"2025-10-15 13:25:15.000000000","permitted_voting_range":{"min":2,"max":2},"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","default_value":0,"optional":true},"Workflow":{"approved":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"all":[{"value":0,"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},{"value":1,"date":"2025-10-15 13:25:15.000000000","permitted_voting_range":{"min":1,"max":1},"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true},"Review-Priority":{"all":[{"value":0,"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},{"value":0,"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},{"value":0,"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},{"value":0,"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"}],"values":{" 0":"Default Priority","+1":"Contributor Review Promise","+2":"Core Review Promise"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2025-10-02 11:18:07.000000000","updated_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"reviewer":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"state":"REVIEWER"},{"updated":"2025-10-03 15:29:50.000000000","updated_by":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"reviewer":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"state":"CC"},{"updated":"2025-10-06 14:49:03.000000000","updated_by":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"reviewer":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"state":"CC"},{"updated":"2025-10-08 14:25:10.000000000","updated_by":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"reviewer":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"state":"REVIEWER"},{"updated":"2025-10-09 21:16:43.000000000","updated_by":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"reviewer":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"state":"REVIEWER"}],"messages":[{"id":"e05a722d16bcbe0c791d35b46ccfd24cc740c80a","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-02 09:43:24.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"1d66856d98314e13d5d6edea24fe56daea2b5622","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-02 11:18:07.000000000","message":"Patch Set 1: Verified-1\n\n(28 comments)\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/bd9be2e9adba410ca833728dd0fc0609\n\n- grenade https://zuul.opendev.org/t/openstack/build/cc6a672ca68d4574800d7d5fddb23a24 : SUCCESS in 56m 46s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/e487875a6b0a4daf8cb55dca5b0022d1 : SUCCESS in 50m 36s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/789ca8c510244a7f84b81df86300a622 : SUCCESS in 1h 32m 45s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/c9d6b333a4314b3db4e30b38e5f9afcf : SUCCESS in 1h 00m 38s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/8b08c8ef39424b7da98658c64a5a7fc5 : TIMED_OUT in 51m 06s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/244b8d02d82d419fb441cdf812448de0 : FAILURE in 5m 00s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/58d5f3b8ca3843bfbe6b6ec067fa20df : FAILURE in 4m 58s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/85ab49b6a7dc4941be85c48432396c45 : FAILURE in 6m 25s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/4dea66507cac478a91288729f3ae2860 : FAILURE in 8m 01s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/426d006b6ffe48f887d107cdca6b329d : SUCCESS in 9m 42s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/0746acb64c6f4d70bc447f47c499fa9f : SUCCESS in 14m 52s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/a9ba4ebffc964e67a7d5fceb2c87a71e : SUCCESS in 20m 21s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/41bde0c0e687458890aa5f296d5bd5c9 : SUCCESS in 25m 49s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/4fc47c07b27c4750a9d3842e795785ef : SUCCESS in 19m 22s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/de65539e2f5245b88583f168cf10af17 : FAILURE in 3m 30s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/c0c09b3dd3634aaba1bd9bbbb2f283d2 : SUCCESS in 50m 13s","accounts_in_message":[],"_revision_number":1},{"id":"76e061b98c02a095b28bc75b74f37832724d52b3","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 09:39:57.000000000","message":"Uploaded patch set 2: New patch set was added with same tree, parent tree, and commit message as Patch Set 1.\n\nOutdated Votes:\n* Verified-1\n","accounts_in_message":[],"_revision_number":2},{"id":"f02a50f3870122883d4a85e7b078f86209b3e076","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 10:05:37.000000000","message":"Uploaded patch set 3.","accounts_in_message":[],"_revision_number":3},{"id":"b9939f4eae21750d8f06683ef0a10c8febda334e","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 10:07:46.000000000","message":"Patch Set 3: Workflow-1\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"80bdbd064d4d64e617ad9f7ebddc29d341e50468","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 10:13:13.000000000","message":"Uploaded patch set 4.\n\nOutdated Votes:\n* Workflow-1\n","accounts_in_message":[],"_revision_number":4},{"id":"f30e49a3c6f26aecabdb52f91301170a3e089c43","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-03 11:20:43.000000000","message":"Patch Set 4: Verified-1\n\n(26 comments)\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/2d8daa74bfc14240b2b19956113dd009\n\n- grenade https://zuul.opendev.org/t/openstack/build/885c15bb93ba4c4d88970c633632cbf1 : SUCCESS in 42m 37s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/a3accbd25a5344e0a814ba78430a9054 : SUCCESS in 1h 01m 21s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/7980b58e86074a22b4b3bfd89d69b99b : SUCCESS in 52m 25s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/5eff742be4604694ad2866b30cd023ed : SUCCESS in 37m 24s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/5bda5e3ee39d4948b7cdb2eeba2062f9 : FAILURE in 5m 46s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/aff94c4115cd45068a81b6800cad259e : FAILURE in 3m 38s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/f2c4c26222e34d9684f225158ed5d27c : FAILURE in 4m 23s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/8bc7fbcf4219480099c12f6e7b3023f1 : FAILURE in 5m 17s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/3c04679974cc452188e7a6a0b0a8ceb7 : FAILURE in 7m 58s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/817789145f664f4ab3b72b4940fedd6a : SUCCESS in 9m 56s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/5d3f81c67cf84d79bb40ed1b1a3e05bf : SUCCESS in 3m 46s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/853c5da171f74fb9858f6c2f73283766 : SUCCESS in 9m 00s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/d99847f81f734b11b5c42fd5c3c40bc7 : SUCCESS in 21m 21s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/098c1d06b0fb4fa798c126d357a31b4d : SUCCESS in 13m 57s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/0dcf351400334db88b0774cdb74a09e9 : FAILURE in 2m 38s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/712eeaf09ba046969a6ef565bc460a78 : SUCCESS in 48m 30s","accounts_in_message":[],"_revision_number":4},{"id":"6d41223b29e9a89c314a259f9222a6f0314202de","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 14:59:13.000000000","message":"Uploaded patch set 5.\n\nOutdated Votes:\n* Verified-1\n","accounts_in_message":[],"_revision_number":5},{"id":"bfceb1f543de08314de32fd62a69a567586038e0","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 15:05:35.000000000","message":"Patch Set 5: Workflow-1\n\n(5 comments)","accounts_in_message":[],"_revision_number":5},{"id":"9cc1909462af7becc031026d39d6e456283d3dfd","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-03 15:05:52.000000000","message":"Patch Set 5:\n\n(1 comment)","accounts_in_message":[],"_revision_number":5},{"id":"42ead22d557af1f55c28bef7e13d7ebd79e8ee27","author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"date":"2025-10-03 15:29:50.000000000","message":"Patch Set 5:\n\n(3 comments)","accounts_in_message":[],"_revision_number":5},{"id":"062d1e8e0763386f10dae52c97903eccebe9cee7","author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"date":"2025-10-03 16:12:44.000000000","message":"Patch Set 5:\n\n(1 comment)","accounts_in_message":[],"_revision_number":5},{"id":"d4b25cbacd5e7759174eb9fc348e28cb5d4e4cd0","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-03 16:41:59.000000000","message":"Patch Set 5: Verified-1\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/8e8f5db121ef4c9ca94563cb524da1ee\n\n- grenade https://zuul.opendev.org/t/openstack/build/f374f3a34f89494c83e7f82e1f050a07 : SUCCESS in 56m 43s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/fc103ca7f3bf477ba24a332896b733ae : SUCCESS in 1h 01m 02s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/a0dafa154fc44249a53274968bda86c3 : SUCCESS in 1h 37m 13s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/d0a342af4c2e4b2fa9a9807fd2db1963 : SUCCESS in 41m 27s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/5d7032b3b0974f0eb116b43e3406598f : SUCCESS in 6m 02s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/eb69f3563945433e8563fac6dabf75b3 : FAILURE in 5m 27s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/a7210fd24f0f4116ba5b69fff574a9d2 : SUCCESS in 5m 10s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/41c8f010cade406eb94ecf13be9d4c88 : SUCCESS in 5m 38s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/4890383afc224ffc8ef949da7d57894d : SUCCESS in 9m 07s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/66baf450f0464a36bc733fbcba8f728c : SUCCESS in 9m 13s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/b6798ef81d8f436681a13e1679740269 : SUCCESS in 9m 16s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/e37b1c56fd6d483ab56c20a97b390a5d : SUCCESS in 10m 18s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/b36c882e70154f0d87ab542428eaa418 : SUCCESS in 21m 32s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/f0401f24560f4ee28f3ca3673260d56c : SUCCESS in 25m 56s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/8c31ddf422fb430690bc8d665f00e312 : FAILURE in 3m 18s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/eb965dc71f3b4a2483ef44bbb868d61b : SUCCESS in 29m 50s","accounts_in_message":[],"_revision_number":5},{"id":"f50eb7635a7656cba9737fe2b527344b62652b0e","author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"date":"2025-10-06 12:34:39.000000000","message":"Patch Set 5:\n\n(2 comments)","accounts_in_message":[],"_revision_number":5},{"id":"0b95619915d379a36502517285c360bec1ec618d","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 14:41:06.000000000","message":"Uploaded patch set 6.\n\nOutdated Votes:\n* Verified-1\n* Workflow-1\n","accounts_in_message":[],"_revision_number":6},{"id":"34d1d8b4cf217f9b5a206a14413be7f65cc0fcf1","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-06 14:49:03.000000000","message":"Patch Set 6:\n\n(1 comment)","accounts_in_message":[],"_revision_number":6},{"id":"5b860683ea6ee098389a3dd8b4b0ecd06d6e29ec","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-06 15:19:26.000000000","message":"Patch Set 6:\n\n(5 comments)","accounts_in_message":[],"_revision_number":6},{"id":"be7a3a984d62406b0b13ae55099b12b8b50a78ff","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 15:32:57.000000000","message":"Patch Set 6:\n\n(4 comments)","accounts_in_message":[],"_revision_number":6},{"id":"ceb279668b178a378a2ca1ab086ab2176d9ee17d","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 15:36:39.000000000","message":"Patch Set 6:\n\n(1 comment)","accounts_in_message":[],"_revision_number":6},{"id":"f216dc88dd364eb401bc188d4a74d99195a07b71","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-06 15:42:55.000000000","message":"Patch Set 6:\n\n(1 comment)","accounts_in_message":[],"_revision_number":6},{"id":"129f811311a4f1d2059527cf203ac0008f6651e3","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 15:55:47.000000000","message":"Patch Set 6:\n\n(1 comment)","accounts_in_message":[],"_revision_number":6},{"id":"4f9adbceac4702b0b5a4d8c27af92e53a15088e5","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-06 15:57:11.000000000","message":"Patch Set 6: Verified-1\n\n(3 comments)\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/56e0e95027584313beefea5feefd42eb\n\n- grenade https://zuul.opendev.org/t/openstack/build/28cc512299a04e4a83006b104af812bf : SUCCESS in 1h 07m 44s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/42155e3a41a44dd18af803f58476248b : SUCCESS in 44m 44s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/cd8be0884a4c4241a318af6ba35aec56 : SUCCESS in 1h 15m 05s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/31520e64fc3242c2a10aa29bd8c607ca : SUCCESS in 47m 03s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/1dd85936720045a7ac878647cdcdf150 : SUCCESS in 20m 26s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/94816e3e92a84f8bb36c3778000f0931 : FAILURE in 5m 30s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/bb0d28fb923a4b79b925abecfb7a7edc : SUCCESS in 5m 03s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/3061a0b99fcf4efd9f3c31e532796cb4 : SUCCESS in 5m 32s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/89b94837327b4af98c9fb49c7e63be41 : SUCCESS in 4m 22s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/b00db5c0df1341c0a9e038d442abc06e : SUCCESS in 8m 44s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/9ec0299c57ea42fdb2500268205594ae : SUCCESS in 6m 48s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/ff96552e82934e238185f3829d07a13e : SUCCESS in 5m 32s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/d50ce0a37ff14b11b8e8815afd6208a2 : SUCCESS in 28m 58s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/8f8918f426a045f6b4b64b196ab5144a : SUCCESS in 17m 30s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/a0430642ca7f4a9ca1e44278df6ce8a2 : FAILURE in 1m 43s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/5f7cc74da0354bf394e257ae67b6ba47 : SUCCESS in 57m 11s","accounts_in_message":[],"_revision_number":6},{"id":"fd9763dc983a1f08733a4c2819b8c590c63fd927","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 16:11:14.000000000","message":"Uploaded patch set 7.\n\nOutdated Votes:\n* Verified-1\n","accounts_in_message":[],"_revision_number":7},{"id":"9907f9b6bc13900007f232c109f547f96287d6e2","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-06 16:13:07.000000000","message":"Patch Set 7:\n\n(2 comments)","accounts_in_message":[],"_revision_number":7},{"id":"e79305569a0f6f813cc40b10fc71d101d225bc26","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-06 16:27:14.000000000","message":"Patch Set 7:\n\n(4 comments)","accounts_in_message":[],"_revision_number":7},{"id":"f94f8f0d09ecae7b6a858788b20c80c5174924b9","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-06 17:38:55.000000000","message":"Patch Set 7: Verified-1\n\n(2 comments)\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/eebeebe8a37a46bea52ebd7f49afc45f\n\n- grenade https://zuul.opendev.org/t/openstack/build/d66771603bd648bb9c3f62b7d3eb14a6 : SUCCESS in 1h 00m 13s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/6dea7697dc7e4184a64cf77393fc32f9 : SUCCESS in 35m 31s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/c32ec82a47c04f01bb88aefe998a96e6 : SUCCESS in 1h 27m 08s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/e6b19a0ac31b496abed9de1db02aed33 : SUCCESS in 1h 01m 18s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/3098cc3fc6464fdbb1df68ef6f7e5a7c : SUCCESS in 15m 14s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/7b98b1ca7d434fee9253ffa6eb6ad72c : FAILURE in 2m 55s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/de269067a843403b86a49da747cdb0b1 : SUCCESS in 4m 55s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/e32ae1dd283743b8af9ed404e0b64c39 : SUCCESS in 3m 41s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/0a7de2cd0f73472ba452135384f5c7cc : SUCCESS in 9m 00s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/6484ff96413244beb57af8b80563d978 : SUCCESS in 9m 37s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/dd77067f5b2744b5beaa9b58d4e0e4bc : SUCCESS in 5m 22s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/e62be447b09c45eeaf59148de969bbec : SUCCESS in 10m 57s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/141f870282ed4ef2a0bba9bbff955619 : SUCCESS in 26m 06s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/6b2396a5d4954c67a88dcf75dee7142e : SUCCESS in 24m 49s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/9e4de807e3304af9a7bd227b2a7ab3b5 : FAILURE in 1m 45s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/e1ff4e713a7d438c89169e8cf489f3d2 : SUCCESS in 41m 02s","accounts_in_message":[],"_revision_number":7},{"id":"1b1160666e6a15c5fa41a1aed76f797cc1e940ae","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 08:50:37.000000000","message":"Uploaded patch set 8.\n\nOutdated Votes:\n* Verified-1\n","accounts_in_message":[],"_revision_number":8},{"id":"a9acd61d22685e3bdc73a572634ad9381b5bb885","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 08:50:45.000000000","message":"Patch Set 7:\n\n(3 comments)","accounts_in_message":[],"_revision_number":7},{"id":"8492040ea2bfdd0ecc763e6e350dcb150f40e60f","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 08:51:42.000000000","message":"Patch Set 8:\n\n(2 comments)","accounts_in_message":[],"_revision_number":8},{"id":"db97744d6c93c5a77656cfc8fbd64e5cddd9f049","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 09:58:02.000000000","message":"Uploaded patch set 9.","accounts_in_message":[],"_revision_number":9},{"id":"4c4a114655e2a53c41223942b0ff3463de02e674","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 09:59:08.000000000","message":"Patch Set 9:\n\n(1 comment)","accounts_in_message":[],"_revision_number":9},{"id":"b20085a8e993a12f4b7875228744ec2630cb53f8","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 10:08:32.000000000","message":"Uploaded patch set 10.","accounts_in_message":[],"_revision_number":10},{"id":"9637cc26b928bdde8d20752a75acc7a5d4b8790c","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 11:32:22.000000000","message":"Patch Set 10:\n\n(1 comment)","accounts_in_message":[],"_revision_number":10},{"id":"44754fac895ba656176ad0cbee191bda5978b044","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-07 12:01:43.000000000","message":"Patch Set 10: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/e60ff6e88a9f49b1960f1ebd71ed8ba6\n\n- grenade https://zuul.opendev.org/t/openstack/build/198c575ef69c4061830b988177f27979 : SUCCESS in 59m 11s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/d6d86af672574f709e1e4872060fb126 : SUCCESS in 1h 02m 20s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/4181c5563242413bba287ca16d22cbbb : SUCCESS in 1h 39m 27s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/3db8b7b0e1a14b12b9682aa004fdc163 : SUCCESS in 1h 10m 23s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/937088d29c6045119887ab8d1c032ed6 : SUCCESS in 25m 10s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/1dca8094f69d47098c9d2fca4ab0754a : SUCCESS in 4m 47s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/c2f52642ce0e479592b1505fc8cb6a77 : SUCCESS in 4m 26s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/02a39f6e1c484f069923f9b1d7769585 : SUCCESS in 5m 09s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/957e656808274b0097ae498d4718ec29 : SUCCESS in 4m 42s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/882bdc7728c1465c9974b7aec62b7494 : SUCCESS in 4m 44s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/12048af291da4e8c917241cdb36643c2 : SUCCESS in 7m 13s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/1360449a27764136a3ffda21dcf85d71 : SUCCESS in 11m 18s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/fac59efb14f644bbaa688a1fe887ef2c : SUCCESS in 24m 56s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/6c05cb3483f242e3a244955edb4cff73 : SUCCESS in 12m 33s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/710c9ec4eeea47ea810a9fa82c1f696a : FAILURE in 2m 56s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/9188e20574bb4412ba2aee6c0bc66b8e : SUCCESS in 1h 00m 41s","accounts_in_message":[],"_revision_number":10},{"id":"3c9705859246810c8d152850b209dc9d43b916a2","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:03:18.000000000","message":"Patch Set 10:\n\n(1 comment)","accounts_in_message":[],"_revision_number":10},{"id":"9fb8ce9131f25bdd312800a15c9a453ed87910df","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:13:59.000000000","message":"Uploaded patch set 11.\n\nOutdated Votes:\n* Verified+1\n","accounts_in_message":[],"_revision_number":11},{"id":"d621aead883c7d15ae2038b79a3db01babdc40e8","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:14:17.000000000","message":"Patch Set 10:\n\n(1 comment)","accounts_in_message":[],"_revision_number":10},{"id":"7b522defb06680577fb0da245534113548e44932","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:16:04.000000000","message":"Patch Set 11:\n\n(3 comments)","accounts_in_message":[],"_revision_number":11},{"id":"ff870915d38b39f98d801a8697b9abc3fe670be1","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:23:34.000000000","message":"Patch Set 11:\n\n(1 comment)","accounts_in_message":[],"_revision_number":11},{"id":"5585b62a199aba0ea983e7277f80b0b3f2dc17b1","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-07 12:23:56.000000000","message":"Patch Set 11:\n\n(1 comment)","accounts_in_message":[],"_revision_number":11},{"id":"0f1951e1aa7ab7827ceccf9623f95867e08f9abc","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-07 14:01:20.000000000","message":"Patch Set 11:\n\n(14 comments)","accounts_in_message":[],"_revision_number":11},{"id":"1619b02507dad1f2ac67b631f3fb14ebd77770be","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-07 14:05:12.000000000","message":"Patch Set 11:\n\n(6 comments)","accounts_in_message":[],"_revision_number":11},{"id":"44ebcc60795bcdfb4f9ae19a930d2668bccf5211","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-07 15:22:48.000000000","message":"Patch Set 11: Verified-1\n\nBuild failed (check pipeline).  For information on how to proceed, see\nhttps://docs.opendev.org/opendev/infra-manual/latest/developers.html#automated-testing\nand https://docs.openstack.org/project-team-guide/testing.html#how-to-handle-test-failures\n\nhttps://zuul.opendev.org/t/openstack/buildset/b6f90d9d4747421da01b7c0eef4fda6b\n\n- grenade https://zuul.opendev.org/t/openstack/build/fc5fe6c7f9d94916abb673436bb16305 : SUCCESS in 54m 52s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/abd8f7a307d44c98b15f1fb94392f4ba : TIMED_OUT in 3h 02m 14s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/81649cbda4d4437fa09b30c579bb0976 : SUCCESS in 1h 17m 05s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/75c566f85aaf4d20b55860d4804c3047 : SUCCESS in 59m 51s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/6fdcb2df5b4440aa9f2ef4ac9895beac : SUCCESS in 20m 41s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/8a27c52b2c854d8dab4a7ff7115f69a1 : SUCCESS in 4m 36s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/91d84dbb411f46fdb3e39bb11432326c : SUCCESS in 4m 12s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/e31b92f2a1274432a6289652bb3acf81 : SUCCESS in 5m 13s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/40efe370d753431d924686ace07ab703 : SUCCESS in 7m 10s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/3cb99110ed5d4922944166c20695d86d : SUCCESS in 4m 40s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/ea067ba2f50c48aea658e598eb32ccbb : SUCCESS in 9m 07s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/4a5b8717413c412eb6d01c4ddc40f7aa : SUCCESS in 12m 49s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/375f00c8f57c4bb093dca0481cd9a101 : SUCCESS in 19m 48s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/72786489e90d438f94081157d2c0b857 : SUCCESS in 28m 54s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/1c978520ab934fd1ac31c3927e5ddc92 : FAILURE in 2m 32s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/ad32e64077514fe29a82fa05e322867d : SUCCESS in 54m 45s","accounts_in_message":[],"_revision_number":11},{"id":"ccf6694c8f0cbfa05ed10286cf0082ec8c2c91d3","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 12:29:17.000000000","message":"Uploaded patch set 12.\n\nOutdated Votes:\n* Verified-1\n","accounts_in_message":[],"_revision_number":12},{"id":"4c885651bbcca919d70089e29d2ab1935159d0ea","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 12:29:50.000000000","message":"Patch Set 12:\n\n(19 comments)","accounts_in_message":[],"_revision_number":12},{"id":"4f9041eefab5237ac00ac139a5a74512c9175b01","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 12:52:24.000000000","message":"Uploaded patch set 13.","accounts_in_message":[],"_revision_number":13},{"id":"9bad9ea513b0f07e07af0b7d0c782f5bcf4b2070","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 12:52:32.000000000","message":"Patch Set 12:\n\n(1 comment)","accounts_in_message":[],"_revision_number":12},{"id":"750f7904d303e20b00b74f9a97b6501d45f9b1c9","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 13:25:50.000000000","message":"Patch Set 13: Workflow-1\n\n(1 comment)","accounts_in_message":[],"_revision_number":13},{"id":"9204eb559a8ea7acbceb30908e2e25050b71777c","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 13:26:48.000000000","message":"Uploaded patch set 14.\n\nOutdated Votes:\n* Workflow-1\n","accounts_in_message":[],"_revision_number":14},{"id":"e0f528b1d6fac177354c188614509a6146f352d7","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 13:27:07.000000000","message":"Patch Set 14:\n\n(1 comment)","accounts_in_message":[],"_revision_number":14},{"id":"c6c26cef04ebe008aebbec07d3e65e1742c8fb0f","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-08 13:41:48.000000000","message":"Patch Set 14:\n\n(6 comments)","accounts_in_message":[],"_revision_number":14},{"id":"18e1e8113a9409f689019b871d3ba9e0f4aa6524","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 14:10:05.000000000","message":"Uploaded patch set 15.","accounts_in_message":[],"_revision_number":15},{"id":"d496f952929dffe8e89752aa84bec8205b8f6bda","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-08 14:10:14.000000000","message":"Patch Set 14:\n\n(5 comments)","accounts_in_message":[],"_revision_number":14},{"id":"3123d2a354ab66dc078392341c0ff37952461be6","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-08 14:25:10.000000000","message":"Patch Set 15: Code-Review+2","accounts_in_message":[],"_revision_number":15},{"id":"509c56a2e706eb73ee529530cd920f19b43475af","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-08 15:13:11.000000000","message":"Patch Set 15: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/7d0c2a2ab4424cb78636f53206d80a2d\n\n- grenade https://zuul.opendev.org/t/openstack/build/b06ba7a180314747876bdf1e215fd5fd : SUCCESS in 1h 01m 05s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/684346884eb2410386380396a018d79b : SUCCESS in 30m 16s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/8400aee7659d40059b8d8dbfc55366e5 : SUCCESS in 53m 30s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/ed4ef2ca9cae497182060be32bf0fb33 : SUCCESS in 31m 55s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/70b723842f0c44ac8cda94e0b3543763 : SUCCESS in 7m 08s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/afeea3bb383c4172bd413c2d8fe30a77 : SUCCESS in 2m 58s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/137944c7cff248caa2765fe82a573817 : SUCCESS in 2m 59s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/e09206928677486789b68bbe06c342f9 : SUCCESS in 5m 17s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/423ca642ac07455c9aca01f1e7dd289b : SUCCESS in 7m 21s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/5fd22ff20b414684a37f60e099449353 : SUCCESS in 7m 55s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/4f952db779e3483c9024a6b25f003c91 : SUCCESS in 9m 36s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/40f770bbb4b94922aa6c382dad3b98cc : SUCCESS in 6m 19s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/db383b5423884a218b91ad997bbc8793 : SUCCESS in 20m 34s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/a336e6bb31b74e0aa4488465ccd773a9 : SUCCESS in 32m 57s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/437b4d45d31c47af985d508213cd9bf3 : FAILURE in 2m 33s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/59384c27ede54106bae71a0b9c4ad91d : SUCCESS in 29m 20s","accounts_in_message":[],"_revision_number":15},{"id":"6300ad845ff5a2d3afbd3b601443ae13b3c3340c","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-09 14:32:22.000000000","message":"Uploaded patch set 16.\n\nOutdated Votes:\n* Code-Review+2 (copy condition: \"changekind:TRIVIAL_REBASE OR is:MIN\")\n* Verified+1\n","accounts_in_message":[],"_revision_number":16},{"id":"c735544cf3855e4c931108dce034a8e8fa37b414","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-09 15:51:33.000000000","message":"Patch Set 16: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/04473d933f974822a7c7f79e4e8c72ca\n\n- grenade https://zuul.opendev.org/t/openstack/build/54cf199562054a238e85b9618c2ff6b8 : SUCCESS in 1h 13m 03s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/aececc4a00db489b8fcc6ff768a443e1 : SUCCESS in 1h 04m 26s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/1a76199b612349de8fc4627353e13fd5 : SUCCESS in 57m 19s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/4192d3baf6f94bcf83c82c79b636fcd6 : SUCCESS in 56m 38s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/a844dd3647004bbb8bdfbefd40e54e88 : SUCCESS in 13m 08s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/d6783b779c554c18a354a2e84265f79e : SUCCESS in 4m 54s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/b5f784e13b6a4a6aa9d85547edd4f6f7 : SUCCESS in 3m 41s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/245c1530a41246aab74c519f069a34e3 : SUCCESS in 5m 22s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/cb569c4e50a54924835797204e14ea27 : SUCCESS in 7m 20s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/c840a0068fc94b84b6000158cd98bc8c : SUCCESS in 8m 55s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/4e8f4210f9d6452bbe85c10c34503df4 : SUCCESS in 5m 06s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/7e44a8e94d0845ec9a24a6725b7f8932 : SUCCESS in 6m 09s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/2b25bc2897904005a9dbeb1cc67d37b0 : SUCCESS in 5m 10s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/bc550bcfbb7d427b860b9ec86c7f6371 : SUCCESS in 26m 45s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/1a94d78488da4e5f9e8792530602d235 : SUCCESS in 10m 48s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/8edfa2eede0844eb951c3ecf494f27e6 : FAILURE in 4m 23s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/49ba505b50d44c5180ae850ccd5208d0 : SUCCESS in 1h 04m 31s","accounts_in_message":[],"_revision_number":16},{"id":"e11e23607fe657a5ceaf51078b1f535a4cbe817b","author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"date":"2025-10-09 21:16:43.000000000","message":"Patch Set 16: Code-Review+1\n\n(7 comments)","accounts_in_message":[],"_revision_number":16},{"id":"94bc9f6658f27ed43073f89234c6c8503fcadfdf","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-10 10:03:29.000000000","message":"Uploaded patch set 17.\n\nOutdated Votes:\n* Code-Review+1 (copy condition: \"changekind:TRIVIAL_REBASE OR is:MIN\")\n* Verified+1\n","accounts_in_message":[],"_revision_number":17},{"id":"ffe1d6af38b025f6946e37ce45de3d2686fb702a","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-10 10:03:52.000000000","message":"Patch Set 16:\n\n(3 comments)","accounts_in_message":[],"_revision_number":16},{"id":"b88b8752323afe80d49cadaabf06e7626e969751","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-10 11:42:41.000000000","message":"Patch Set 17: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/d83f4d2c8c6b421ca81f990143467c62\n\n- grenade https://zuul.opendev.org/t/openstack/build/958db357db14462098ef8fdf4992039c : SUCCESS in 59m 52s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/8a9a6078498c4bef9475d60edc72d128 : SUCCESS in 52m 17s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/f0be82af8eef4dca81ca21e77ab959b6 : SUCCESS in 1h 37m 21s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/674d733e876343d29159db6cad0ba3a0 : SUCCESS in 1h 04m 37s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/8cce55554eda4229b54c4a950fa6a1da : SUCCESS in 16m 19s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/a9c1665272e147778549a998d7317b04 : SUCCESS in 2m 59s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/81ca61d59cd048509a3c37f29d3594f9 : SUCCESS in 4m 55s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/6d8225148bd444a7b6108eef9efac711 : SUCCESS in 4m 46s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/c90bbf28abd54e788b3805a41d3de23b : SUCCESS in 7m 39s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/6e8afe491fea4666b86b17c8097dfdea : SUCCESS in 9m 35s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/0a07743f332442b393a71e4e4584d9de : SUCCESS in 4m 39s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/bbfe800956ec469e87f065c2d1b579d8 : SUCCESS in 3m 42s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/1a2b5616c2254827924f809b9dbc9a74 : SUCCESS in 5m 07s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/85ee8c9734954a3581253712dd02906e : SUCCESS in 29m 11s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/37b77c0ccb294e72abc738a7e41a2284 : SUCCESS in 16m 45s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/f4c3e9654b56461dba41a4ff2aa6bed5 : FAILURE in 1m 42s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/08ff94ee0a7346d8adeeace12a4a768a : SUCCESS in 30m 38s","accounts_in_message":[],"_revision_number":17},{"id":"e1955a066b0a3af8fb0e0399d1cbb1c0d1a4d06b","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-13 07:08:58.000000000","message":"Patch Set 17:\n\n(1 comment)","accounts_in_message":[],"_revision_number":17},{"id":"e9805793bb8c9eb9122e927e4ea684bc15e069ec","author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"date":"2025-10-13 16:17:01.000000000","message":"Patch Set 17: Code-Review+2\n\n(2 comments)","accounts_in_message":[],"_revision_number":17},{"id":"8731dab87d088203ff46df27d992f99af79b2a51","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-13 18:47:47.000000000","message":"Patch Set 17:\n\n(9 comments)","accounts_in_message":[],"_revision_number":17},{"id":"56d58b6f8fa680f1467c0b4c2a833755f147330e","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-13 19:13:42.000000000","message":"Patch Set 17:\n\n(1 comment)","accounts_in_message":[],"_revision_number":17},{"id":"804804f1ea64a9900263234e7805d4a3742786c9","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-14 08:33:55.000000000","message":"Patch Set 17:\n\n(7 comments)","accounts_in_message":[],"_revision_number":17},{"id":"65c8d12e37ccc48744920a449b1a0872ad2226a9","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-14 13:40:00.000000000","message":"Uploaded patch set 18.\n\nOutdated Votes:\n* Code-Review+2 (copy condition: \"changekind:TRIVIAL_REBASE OR is:MIN\")\n* Verified+1\n","accounts_in_message":[],"_revision_number":18},{"id":"ae22977ad19d9a7cbb3d49fd22bd66398572f706","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-14 13:40:13.000000000","message":"Patch Set 18:\n\n(7 comments)","accounts_in_message":[],"_revision_number":18},{"id":"b6ff3122921432a23417c22561e91ffc87ed10fa","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-14 14:44:53.000000000","message":"Patch Set 18: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/29fc3ffdea95433eb1a61d9c6adf3575\n\n- grenade https://zuul.opendev.org/t/openstack/build/529f87cf6fa943acab0ea0ab457d31a5 : SUCCESS in 29m 09s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/7a3d328679a845ce98553fdd2ae56350 : SUCCESS in 46m 46s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/9ccc2e7335564337a899f628d7088e71 : SUCCESS in 52m 46s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/571d5e6cf77246e3ab18ac6fe83d90f2 : SUCCESS in 31m 35s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/9bf8f3cbd8c54255b2f45f73bccbbf0b : SUCCESS in 16m 24s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/1f5417d0b19e4081b657a8414955df7b : SUCCESS in 5m 13s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/3534d59d1188481bb9933f151579c634 : SUCCESS in 4m 50s\n- openstack-tox-py312 https://zuul.opendev.org/t/openstack/build/3be3624266dd4086b7e960274c7dc5c4 : SUCCESS in 5m 17s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/7feaca1d7b154054be651a8900b09bbd : SUCCESS in 7m 26s (non-voting)\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/da45a72d41a84db68af2e1fd6c867c20 : SUCCESS in 7m 40s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/b2499c6e15484e499a8475015ddde671 : SUCCESS in 7m 18s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/d248c3e2039544af8bcaa7b78cc754e9 : SUCCESS in 5m 21s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/759e00e5b68348fc8b8a2d363c444128 : SUCCESS in 5m 06s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/9aea50d2a920463ab4b264c84cca8e19 : SUCCESS in 27m 19s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/b251428ec98e46de9953c7024c69b83d : SUCCESS in 29m 29s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/8243bb0b858a4f288002416a110af4bf : FAILURE in 3m 14s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/aa3836c6617947f88338eb9ef072351d : SUCCESS in 59m 05s","accounts_in_message":[],"_revision_number":18},{"id":"863a027a1d0a1dbc226681a5b75e343153df60a6","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-14 17:18:33.000000000","message":"Patch Set 18:\n\n(2 comments)","accounts_in_message":[],"_revision_number":18},{"id":"8f897ce652813444bcc42d266da2087c323713bd","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-14 17:31:10.000000000","message":"Patch Set 18:\n\n(4 comments)","accounts_in_message":[],"_revision_number":18},{"id":"28df5379b30cddc8c25d5926a6c2ad17638777d5","tag":"autogenerated:gerrit:newPatchSet","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-15 07:57:21.000000000","message":"Uploaded patch set 19: Commit message was updated.\n\nOutdated Votes:\n* Verified+1\n","accounts_in_message":[],"_revision_number":19},{"id":"4f040a180e06e401f329460783aaeffd6d5c1ddd","author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"date":"2025-10-15 07:57:34.000000000","message":"Patch Set 18:\n\n(5 comments)","accounts_in_message":[],"_revision_number":18},{"id":"7cfdd1c7cb8c43cfb3f97d9cd129695a80503ca6","tag":"autogenerated:zuul:check","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-15 09:07:14.000000000","message":"Patch Set 19: Verified+1\n\nBuild succeeded (check pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/f27d6bcbac794c9ab65af70ff3106ee6\n\n- grenade https://zuul.opendev.org/t/openstack/build/813c69e7034c4fa8b0b1fa934c1765ae : SUCCESS in 47m 13s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/9f843f4b2bb64d919ca66ed23d4c2706 : SUCCESS in 1h 05m 05s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/d0a8a3945f7d4424b04c0a9ccae0c735 : SUCCESS in 1h 02m 48s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/6b25616033b54f58a888149d27ffbd2d : SUCCESS in 1h 04m 50s\n- openstack-tox-cover https://zuul.opendev.org/t/openstack/build/1b132c5eb77b4fc9a53c67983e88be72 : SUCCESS in 14m 22s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/16fb2a0f065a4e92b2d25cde28044588 : SUCCESS in 2m 53s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/3797adc3663f4384a87fed4fb30f4778 : SUCCESS in 7m 40s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/92ac049fe8784bc2aca8e63f173623b9 : SUCCESS in 7m 42s\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/0dba054e7acb40b58c6b49f117387605 : SUCCESS in 8m 54s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/95543883672949b49453b829bce4778a : SUCCESS in 5m 01s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/2ff72876c3654944aae0697888a7108c : SUCCESS in 6m 21s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/2c1568d302c5465faa0c64d446570651 : SUCCESS in 10m 29s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/96f5c52cc285473595a6dace5a3a06a4 : SUCCESS in 26m 46s\n- placement-nested-perfload https://zuul.opendev.org/t/openstack/build/139ea9a39b1746858750c541d92753d5 : SUCCESS in 28m 25s (non-voting)\n- placement-perfload https://zuul.opendev.org/t/openstack/build/53169a8df8264019b7fb662bf6a05f95 : FAILURE in 1m 39s (non-voting)\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/117d7497ad294d91b40a217a4df0b8e8 : SUCCESS in 56m 43s","accounts_in_message":[],"_revision_number":19},{"id":"21729e0f75b2ee0e62093969a14e4f6eec998c2d","author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"date":"2025-10-15 13:25:15.000000000","message":"Patch Set 19: Code-Review+2 Workflow+1\n\n(2 comments)","accounts_in_message":[],"_revision_number":19},{"id":"54ca30572de4eb93d9916ff1097fe2e3ee8c5ce4","tag":"autogenerated:zuul:gate","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-15 13:25:43.000000000","message":"Patch Set 19: -Verified\n\nStarting gate jobs.","accounts_in_message":[],"_revision_number":19},{"id":"278e32273706d6febd7fb0338df7d1f8935bd5fb","tag":"autogenerated:zuul:gate","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-15 14:36:40.000000000","message":"Patch Set 19: Verified+2\n\nBuild succeeded (gate pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/31b3aed515ab4aa7a5a4bf330026ef94\n\n- grenade https://zuul.opendev.org/t/openstack/build/b9cf470212114b6c87883b0cf97db0d4 : SUCCESS in 1h 03m 54s\n- tempest-integrated-placement https://zuul.opendev.org/t/openstack/build/53c9c3e3743b40eea9f33343fb3eee66 : SUCCESS in 52m 27s\n- grenade-skip-level-always https://zuul.opendev.org/t/openstack/build/10c8a46c3d01469faa380407005cd566 : SUCCESS in 1h 06m 26s\n- openstacksdk-functional-devstack https://zuul.opendev.org/t/openstack/build/417d0c7e62514222b89784d9a79c96b3 : SUCCESS in 46m 27s\n- openstack-tox-pep8 https://zuul.opendev.org/t/openstack/build/7948d6cfecda48038de020aec5901d16 : SUCCESS in 4m 49s\n- openstack-tox-py310 https://zuul.opendev.org/t/openstack/build/3ea850cdb18f47f89fd6cb75bd2b6145 : SUCCESS in 4m 57s\n- openstack-tox-py313 https://zuul.opendev.org/t/openstack/build/3ef55430292544f088deef427cbab588 : SUCCESS in 10m 12s\n- openstack-tox-docs https://zuul.opendev.org/t/openstack/build/e9236d17b94246f59fbb85b668f40933 : SUCCESS in 6m 24s\n- build-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/91388ad723ba4e97a7623b2f037e8b41 : SUCCESS in 5m 03s\n- openstack-tox-functional-py310 https://zuul.opendev.org/t/openstack/build/86f7d4ea214643fdbabf7f65f6313e07 : SUCCESS in 3m 44s\n- openstack-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/c1719e9974484d5f8aec850b6941c705 : SUCCESS in 5m 09s\n- placement-nova-tox-functional-py312 https://zuul.opendev.org/t/openstack/build/125226e104244c339bfb6b3d13125268 : SUCCESS in 26m 49s\n- tempest-ipv6-only https://zuul.opendev.org/t/openstack/build/d2fe745d9f794f7bb86c27c80671c279 : SUCCESS in 55m 12s","accounts_in_message":[],"_revision_number":19},{"id":"f04ed8a95b4eedec21a946e6ff7d5ecc8e6c5568","tag":"autogenerated:gerrit:merged","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-15 14:36:41.000000000","message":"Change has been successfully merged","accounts_in_message":[],"_revision_number":19},{"id":"fd0e911282748cd94a356409b7bd192630629ffe","tag":"autogenerated:zuul:promote","author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"date":"2025-10-15 14:37:36.000000000","message":"Patch Set 19:\n\nBuild succeeded (promote pipeline).\nhttps://zuul.opendev.org/t/openstack/buildset/61e10090d317488c94c75d76160753bc\n\n- promote-openstack-tox-docs https://zuul.opendev.org/t/openstack/build/1fb0eabd97194ce3827750c9a68760cd : SUCCESS in 46s\n- promote-openstack-releasenotes https://zuul.opendev.org/t/openstack/build/ed3e5022e0c7428c9e1a2441e865ffae : SUCCESS in 38s","accounts_in_message":[],"_revision_number":19}],"current_revision_number":19,"current_revision":"5b73b980d0f022de2855480f57c9d5f04a7a4712","revisions":{"8786eebdc52490945e0af04f5046b005bf729b00":{"kind":"REWORK","_number":1,"created":"2025-10-02 09:43:24.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/1"}}},"commit":{"parents":[{"commit":"447c9f9854ab8b267b5be30a0492c4a880599f39","subject":"Remove excessive logging from GET a_c","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/447c9f9854ab8b267b5be30a0492c4a880599f39"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:43:15.000000000","tz":120},"subject":"Prune search space with invalid prefixes","message":"Prune search space with invalid prefixes\n\nXXX Describe the change\n\nCloses-Bug: XXX file bug\n\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/8786eebdc52490945e0af04f5046b005bf729b00"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/8786eebdc52490945e0af04f5046b005bf729b00"}]},"branch":"refs/heads/master"},"245e28e902420bb5183687f04a2e72282eceafde":{"kind":"NO_CHANGE","_number":2,"created":"2025-10-03 09:39:57.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/2","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/2","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/2 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/2 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/2 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/2"}}},"commit":{"parents":[{"commit":"d97bfeacf100597846bf8f70efb095cfb7e23037","subject":"Reproduce GET a_c slowness","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d97bfeacf100597846bf8f70efb095cfb7e23037"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-03 09:39:43.000000000","tz":120},"subject":"Prune search space with invalid prefixes","message":"Prune search space with invalid prefixes\n\nXXX Describe the change\n\nCloses-Bug: XXX file bug\n\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/245e28e902420bb5183687f04a2e72282eceafde"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/245e28e902420bb5183687f04a2e72282eceafde"}]},"branch":"refs/heads/master"},"22ea28e62df21b76ca094d3139a9fb30b6087530":{"kind":"REWORK","_number":3,"created":"2025-10-03 10:05:37.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/3","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/3","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/3 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/3 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/3 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/3"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-03 10:04:49.000000000","tz":120},"subject":"Prune search space by invalid prefixes","message":"Prune search space by invalid prefixes\n\nXXX Describe the change\n\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/22ea28e62df21b76ca094d3139a9fb30b6087530"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/22ea28e62df21b76ca094d3139a9fb30b6087530"}]},"branch":"refs/heads/master"},"d666b11cf5d13cd49c2e10a4aefa733003ffaecd":{"kind":"REWORK","_number":4,"created":"2025-10-03 10:13:13.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/4","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/4","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/4 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/4 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/4 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/4"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-03 10:11:49.000000000","tz":120},"subject":"Prune search space by invalid prefixes","message":"Prune search space by invalid prefixes\n\nXXX Describe the change\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d666b11cf5d13cd49c2e10a4aefa733003ffaecd"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d666b11cf5d13cd49c2e10a4aefa733003ffaecd"}]},"branch":"refs/heads/master"},"601b6075257c2d98ee24d5068012e54ce1bc0281":{"kind":"REWORK","_number":5,"created":"2025-10-03 14:59:13.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/5","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/5","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/5 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/5 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/5 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/5"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-03 14:23:52.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/601b6075257c2d98ee24d5068012e54ce1bc0281"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/601b6075257c2d98ee24d5068012e54ce1bc0281"}]},"branch":"refs/heads/master"},"e9b0a915ae0b196b9273e5d71544f97ab4d008b0":{"kind":"REWORK","_number":6,"created":"2025-10-06 14:41:06.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/6","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/6","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/6 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/6 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/6 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/6"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-06 14:40:09.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/e9b0a915ae0b196b9273e5d71544f97ab4d008b0"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/e9b0a915ae0b196b9273e5d71544f97ab4d008b0"}]},"branch":"refs/heads/master"},"7ab10e2968b217db884c99d85d3a12389069d602":{"kind":"REWORK","_number":7,"created":"2025-10-06 16:11:14.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/7","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/7","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/7 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/7 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/7 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/7"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-06 16:11:06.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7ab10e2968b217db884c99d85d3a12389069d602"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7ab10e2968b217db884c99d85d3a12389069d602"}]},"branch":"refs/heads/master"},"1d804cb58015ef7d4f40b49d955d42708fa2d1a9":{"kind":"REWORK","_number":8,"created":"2025-10-07 08:50:37.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/8","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/8","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/8 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/8 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/8 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/8"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-07 08:49:14.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/1d804cb58015ef7d4f40b49d955d42708fa2d1a9"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/1d804cb58015ef7d4f40b49d955d42708fa2d1a9"}]},"branch":"refs/heads/master"},"86e3bd58b18c8204db8b96682550187abb5f1400":{"kind":"REWORK","_number":9,"created":"2025-10-07 09:58:02.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/9","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/9","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/9 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/9 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/9 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/9"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-07 09:57:47.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/86e3bd58b18c8204db8b96682550187abb5f1400"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/86e3bd58b18c8204db8b96682550187abb5f1400"}]},"branch":"refs/heads/master"},"9e8a305100301820c2937f5a74b296df40d54946":{"kind":"REWORK","_number":10,"created":"2025-10-07 10:08:32.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/10","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/10","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/10 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/10 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/10 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/10"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-07 10:08:18.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the his _consolidate_allocation_requests call has side effect on the\nindividual Group - RP mappings therefore the copy logic need to be\nadjusted a bit to copy more.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/9e8a305100301820c2937f5a74b296df40d54946"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/9e8a305100301820c2937f5a74b296df40d54946"}]},"branch":"refs/heads/master"},"e3cebf6f2263513149bfc3e68e6d638ea7e7e54f":{"kind":"REWORK","_number":11,"created":"2025-10-07 12:13:59.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/11","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/11","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/11 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/11 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/11 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/11"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-07 12:09:08.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the _consolidate_allocation_requests call has side effect on\nthe individual Group - RP ARR as it folds two or more groups\u0027 allocation\nfrom the same RP and RC into the first ARR. When the optimization is\nenabled the order of filtering is changed. Without the optimization the\norder is _satisfies_group_policy then _consolidate_allocation_requests,\nso the latter never sees overlapping group allocations when the\ngroup_policy is isolate as the former filters them out. So the folding\nlogic don\u0027t need to copy ARRs in case of group_policy isolate. However\nonce the optimization is enabled _consolidate_allocation_requests is\ncalled before _satisfies_group_policy so\n_consolidate_allocation_requests can see overlapping group allocations\nwith isolate as well and then it will fold them, so we need to copy the\nARR in this case to avoid the side effect.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/e3cebf6f2263513149bfc3e68e6d638ea7e7e54f"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/e3cebf6f2263513149bfc3e68e6d638ea7e7e54f"}]},"branch":"refs/heads/master"},"898241dd8f66fa318604a371da110a95ca7c1b6a":{"kind":"REWORK","_number":12,"created":"2025-10-08 12:29:17.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/12","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/12","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/12 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/12 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/12 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/12"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-08 12:28:05.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the _consolidate_allocation_requests call has side effect on\nthe individual Group - RP ARR as it folds two or more groups\u0027 allocation\nfrom the same RP and RC into the first ARR. When the optimization is\nenabled the order of filtering is changed. Without the optimization the\norder is _satisfies_group_policy then _consolidate_allocation_requests,\nso the latter never sees overlapping group allocations when the\ngroup_policy is isolate as the former filters them out. So the folding\nlogic don\u0027t need to copy ARRs in case of group_policy isolate. However\nonce the optimization is enabled _consolidate_allocation_requests is\ncalled before _satisfies_group_policy so\n_consolidate_allocation_requests can see overlapping group allocations\nwith isolate as well and then it will fold them, so we need to copy the\nARR in this case to avoid the side effect.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/898241dd8f66fa318604a371da110a95ca7c1b6a"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/898241dd8f66fa318604a371da110a95ca7c1b6a"}]},"branch":"refs/heads/master"},"d3da9c722565981628a86758218a9e46108125bc":{"kind":"REWORK","_number":13,"created":"2025-10-08 12:52:24.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/13","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/13","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/13 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/13 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/13 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/13"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-08 12:52:12.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the _consolidate_allocation_requests call has side effect on\nthe individual Group - RP ARR as it folds two or more groups\u0027 allocation\nfrom the same RP and RC into the first ARR. When the optimization is\nenabled the order of filtering is changed. Without the optimization the\norder is _satisfies_group_policy then _consolidate_allocation_requests,\nso the latter never sees overlapping group allocations when the\ngroup_policy is isolate as the former filters them out. So the folding\nlogic don\u0027t need to copy ARRs in case of group_policy isolate. However\nonce the optimization is enabled _consolidate_allocation_requests is\ncalled before _satisfies_group_policy so\n_consolidate_allocation_requests can see overlapping group allocations\nwith isolate as well and then it will fold them, so we need to copy the\nARR in this case to avoid the side effect.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d3da9c722565981628a86758218a9e46108125bc"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d3da9c722565981628a86758218a9e46108125bc"}]},"branch":"refs/heads/master"},"7c0e1d693f077e73e7bcf49d0e420003812c2ddb":{"kind":"REWORK","_number":14,"created":"2025-10-08 13:26:48.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/14","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/14","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/14 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/14 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/14 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/14"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-08 13:26:36.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the _consolidate_allocation_requests call has side effect on\nthe individual Group - RP ARR as it folds two or more groups\u0027 allocation\nfrom the same RP and RC into the first ARR. When the optimization is\nenabled the order of filtering is changed. Without the optimization the\norder is _satisfies_group_policy then _consolidate_allocation_requests,\nso the latter never sees overlapping group allocations when the\ngroup_policy is isolate as the former filters them out. So the folding\nlogic don\u0027t need to copy ARRs in case of group_policy isolate. However\nonce the optimization is enabled _consolidate_allocation_requests is\ncalled before _satisfies_group_policy so\n_consolidate_allocation_requests can see overlapping group allocations\nwith isolate as well and then it will fold them, so we need to copy the\nARR in this case to avoid the side effect.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7c0e1d693f077e73e7bcf49d0e420003812c2ddb"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7c0e1d693f077e73e7bcf49d0e420003812c2ddb"}]},"branch":"refs/heads/master"},"7baca3270788b733d62228eb005fca3fff238d20":{"kind":"REWORK","_number":15,"created":"2025-10-08 14:10:05.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/15","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/15","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/15 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/15 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/15 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/15"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-08 14:09:55.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA product generator algorithm that can skip structured parts of the\nproduct space efficiently. This is implemented by an index odometer.\nIn the above example we have 8 slots, one for each group, in the\nodometer and each slot\u0027s value is an index pointing to an RP 0-7.\n\n  G0 G1 G2 G3 G4 G5 G6 G7\n  0  0  .  .  .        0\n  .  .                 .\n  .  .                 .\n  .  .                 .\n  7  7  .  .  .        7\n\nA product is a specific state of the odometer. E.g.\nC0 is 0,0,0,0,0,0,0,0 on the odometer meaning\n\n  C0: G0R0,G1R0,G2R0,G3R0,G4R0,G5R0,G6R0,G7R0\n\nAfter we found a valid candidate and we just want to go to the next product\nthen we need to bump the rightmost slot on the odometer (handle the\noverflow to the earlier slots) and the new set of indexes give a new\nproduct.\n\nBut if we found an invalid candidate e.g. C0, and we know that it is\ninvalid as the G1 slot made it invalid (G0 and G1 tries to use the same\nresource) then instead of bumping the G7 slot to get a new product\nwe can bump the G1 slot directly (handle carry to G0), reset the higher\nslots to 0 and we effectively dropped all the products starting with\nG0R0,G1R0 invalid prefix.\n\nDeciding which group made a candidate invalid is easy. We can create\npartial candidates sequentially and test them:\nTest G0,G1, if it is valid test G0,G1,G2, etc. If G1..G8 valid then we\nfound a valid candidate.\n\nThere are further optimizations in the implementation. Creating a\nconsolidated candidate from the index set is expensive so we ensure\nwe only do it once for each candidate independently of which algorithm\nis used. This makes the interface of the product generator a bit awkward\nas in the normal itertools.product algo the consolidation happens after\nthe generation, but in the new odometer product algo it happens during\nthe testing of the candidate within the product generation.\n\nAlso the _consolidate_allocation_requests call has side effect on\nthe individual Group - RP ARR as it folds two or more groups\u0027 allocation\nfrom the same RP and RC into the first ARR. When the optimization is\nenabled the order of filtering is changed. Without the optimization the\norder is _satisfies_group_policy then _consolidate_allocation_requests,\nso the latter never sees overlapping group allocations when the\ngroup_policy is isolate as the former filters them out. So the folding\nlogic don\u0027t need to copy ARRs in case of group_policy isolate. However\nonce the optimization is enabled _consolidate_allocation_requests is\ncalled before _satisfies_group_policy so\n_consolidate_allocation_requests can see overlapping group allocations\nwith isolate as well and then it will fold them, so we need to copy the\nARR in this case to avoid the side effect.\n\nGemini 2.5 pro was used to put together the generic odometer based\nCartesian product algorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7baca3270788b733d62228eb005fca3fff238d20"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/7baca3270788b733d62228eb005fca3fff238d20"}]},"branch":"refs/heads/master"},"d73e760ec1c4fa762632b9c3ca1c2edb724ff6b7":{"kind":"REWORK","_number":16,"created":"2025-10-09 14:32:22.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/16","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/16","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/16 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/16 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/16 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/16"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-09 14:32:05.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA recursive product generator algorithm that calls a function on each\npartial candidate and if that function signals that the partial\ncandidate is invalid then the algorithm does skips any candidate that\nhas the same partial candidate prefix.\n\nThe recursion does a tree traversal to find all partial prefixes.\nWith the above G0-G8, RP0, RP8 example the start of the traversal\nlooks like:\n1. partial product G0-RP0, this does not exceed capacity so recurse\n2. partial product G0-RP0, G1-RP0, this exceeds capacity so do not\n   recurse but try another RP on this level.\n3. partial product G0-RP0, G1-RP1, this does not exceeds capacity so\n   recurse.\n4. partial product G0-RP0, G1-RP1, G2-RP0, this exceeds capacity so\n   do not recurse but try another RP on this level\n...\n\nWithout the optimization Placement uses the logic\n\n        areq \u003d _consolidate_allocation_requests(areq_list, rw_ctx)\n        if rw_ctx.exceeds_capacity(areq)\n            continue\n\non all product after it was generated. The\n_consolidate_allocation_requests folds the individual\nAllocationRequestResource object in the product into a single\nallocation. This has a side effect on some of the ARRs so the logic does\ncopy the affected ARRs. This is expensive especially if we want to call\nit on every partial product as well. However if we only want to check\nthe capacity we don\u0027t need to fold the ARRs we just need to sum the\namount each ARR hold and the check that against the capacity. So\n_exceeds_capacity() was added to do this optimized, side effect and copy\nfree, capacity check when the optimization is enabled.\n\nWhen a valid product is generated _consolidate_allocation_requests still\nneeds to be called to get the folded AllocationRequest in any case as\nthe caller of _merge_candidates expects such structure. But the final\nrw_ctx.exceeds_capacity can we skipped if the optimization is enabled.\n\nGemini 2.5 pro was used to put together the generic Cartesian product\nalgorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d73e760ec1c4fa762632b9c3ca1c2edb724ff6b7"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/d73e760ec1c4fa762632b9c3ca1c2edb724ff6b7"}]},"branch":"refs/heads/master"},"2e66df14aad5f72de2a436195de385d21fdb2163":{"kind":"REWORK","_number":17,"created":"2025-10-10 10:03:29.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/17","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/17","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/17 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/17 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/17 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/17"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-10 10:03:09.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA recursive product generator algorithm that calls a function on each\npartial candidate and if that function signals that the partial\ncandidate is invalid then the algorithm does skips any candidate that\nhas the same partial candidate prefix.\n\nThe recursion does a tree traversal to find all partial prefixes.\nWith the above G0-G8, RP0, RP8 example the start of the traversal\nlooks like:\n1. partial product G0-RP0, this does not exceed capacity so recurse\n2. partial product G0-RP0, G1-RP0, this exceeds capacity so do not\n   recurse but try another RP on this level.\n3. partial product G0-RP0, G1-RP1, this does not exceeds capacity so\n   recurse.\n4. partial product G0-RP0, G1-RP1, G2-RP0, this exceeds capacity so\n   do not recurse but try another RP on this level\n...\n\nWithout the optimization Placement uses the logic\n\n        areq \u003d _consolidate_allocation_requests(areq_list, rw_ctx)\n        if rw_ctx.exceeds_capacity(areq)\n            continue\n\non all product after it was generated. The\n_consolidate_allocation_requests folds the individual\nAllocationRequestResource object in the product into a single\nallocation. This has a side effect on some of the ARRs so the logic does\ncopy the affected ARRs. This is expensive especially if we want to call\nit on every partial product as well. However if we only want to check\nthe capacity we don\u0027t need to fold the ARRs we just need to sum the\namount each ARR hold and the check that against the capacity. So\n_exceeds_capacity() was added to do this optimized, side effect and copy\nfree, capacity check when the optimization is enabled.\n\nWhen a valid product is generated _consolidate_allocation_requests still\nneeds to be called to get the folded AllocationRequest in any case as\nthe caller of _merge_candidates expects such structure. But the final\nrw_ctx.exceeds_capacity can we skipped if the optimization is enabled.\n\nGemini 2.5 pro was used to put together the generic Cartesian product\nalgorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/2e66df14aad5f72de2a436195de385d21fdb2163"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/2e66df14aad5f72de2a436195de385d21fdb2163"}]},"branch":"refs/heads/master"},"98e56a39bd581b20dc80a60c1ef9d51980257893":{"kind":"REWORK","_number":18,"created":"2025-10-14 13:40:00.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/18","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/18","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/18 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/18 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/18 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/18"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-14 13:39:47.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enable via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA recursive product generator algorithm that calls a function on each\npartial candidate and if that function signals that the partial\ncandidate is invalid then the algorithm does skips any candidate that\nhas the same partial candidate prefix.\n\nThe recursion does a tree traversal to find all partial prefixes.\nWith the above G0-G8, RP0, RP8 example the start of the traversal\nlooks like:\n1. partial product G0-RP0, this does not exceed capacity so recurse\n2. partial product G0-RP0, G1-RP0, this exceeds capacity so do not\n   recurse but try another RP on this level.\n3. partial product G0-RP0, G1-RP1, this does not exceeds capacity so\n   recurse.\n4. partial product G0-RP0, G1-RP1, G2-RP0, this exceeds capacity so\n   do not recurse but try another RP on this level\n...\n\nWithout the optimization Placement uses the logic\n\n        areq \u003d _consolidate_allocation_requests(areq_list, rw_ctx)\n        if rw_ctx.exceeds_capacity(areq)\n            continue\n\non all product after it was generated. The\n_consolidate_allocation_requests folds the individual\nAllocationRequestResource object in the product into a single\nallocation. This has a side effect on some of the ARRs so the logic does\ncopy the affected ARRs. This is expensive especially if we want to call\nit on every partial product as well. However if we only want to check\nthe capacity we don\u0027t need to fold the ARRs we just need to sum the\namount each ARR hold and the check that against the capacity. So\n_exceeds_capacity() was added to do this optimized, side effect and copy\nfree, capacity check when the optimization is enabled.\n\nWhen a valid product is generated _consolidate_allocation_requests still\nneeds to be called to get the folded AllocationRequest in any case as\nthe caller of _merge_candidates expects such structure. But the final\nrw_ctx.exceeds_capacity can we skipped if the optimization is enabled.\n\nThe depth of the recursion is equal to the number of iterables passed to\nthe product call. It can be seen by the fact that each level of\nrecursion appends a new item to the partial product and when the length\nof the partial product equals to the number of iterables then we have a\nfull product and the algo yields. The default python recursion limit is\n1000 so we are not really limited by that as that means we could handle\n~ 990 iterables, meaning an allocation candidate query with 990 request\ngroups. The limiting factor of this algorithm is not recursion dept but\nexecution time.\n\nGemini 2.5 pro was used to put together the generic Cartesian product\nalgorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/98e56a39bd581b20dc80a60c1ef9d51980257893"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/98e56a39bd581b20dc80a60c1ef9d51980257893"}]},"branch":"refs/heads/master"},"5b73b980d0f022de2855480f57c9d5f04a7a4712":{"kind":"NO_CODE_CHANGE","_number":19,"created":"2025-10-15 07:57:21.000000000","uploader":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"ref":"refs/changes/76/962776/19","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/placement","ref":"refs/changes/76/962776/19","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/19 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/19 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/placement refs/changes/76/962776/19 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/placement refs/changes/76/962776/19"}}},"commit":{"parents":[{"commit":"0b783c7e1695f50b812cbae725f7c7913efd41a1","subject":"Reproduce GET a_c slowness bug/2126751","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/0b783c7e1695f50b812cbae725f7c7913efd41a1"}]}],"author":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-02 09:40:31.000000000","tz":120},"committer":{"name":"Balazs Gibizer","email":"gibi@redhat.com","date":"2025-10-15 07:56:03.000000000","tz":120},"subject":"Prune a_c search space by invalid prefixes","message":"Prune a_c search space by invalid prefixes\n\nAssume we have 8 RPs with 1 resource, and we request 8 groups\nwith 1 resource each.\nThe full candidate matrix for a single provider tree (compute node)\nby satisfying each group independently (G is request group, R is RP):\n\n  G0: [R0, R1,..., R7] # G0 can be fulfilled from R0, R1, ..., R7\n  G1: [R0, R1,..., R7]\n  ...\n  G7: [R0, R1,..., R7]\n\nPlacement needs to satisfy every group in the request so it\ncreates all the possible combinations (a Cartesian product) of the\nindividual group fulfilments and checks if they are valid, i.e if\nthere are no two or more groups trying to use the same single piece\nof resource.\nThe product looks like\n(C is candidate, G0-R0 means G0 group satisfied from R0 RP):\n\n  C0: [G0-R0, G1-R0, ..., G7-R0] # invalid, R0 has 1 res but C0 needs 8\n  C1: [G0-R0, G2-R0, ..., G7-R1] # invalid, R0 has 1 res but C1 needs 7\n  ...\n  Cx: [G0-R0, G1-R1, ..., G7-R7] # valid, each Rx has 1 res and\n                                 # Cx ask form 1 res each\n\nFrom this picture it is clear that:\n\n* There are a lot more invalid candidates than valid ones. Actually\n  in this specific scenario the total number of candidates are\n  8^8 ~ 16M. The valid candidates are 8! ~ 40K. Finding the valid ones\n  by blindly searching all possible ones are scaling very badly as\n  exponential grows faster than factorial. I.e. valid candidates will be\n  farther apart from each other in the search space.\n\n* There is a structure within and across the candidates. E.g. If we\n  know that C0 is invalid already because of G0-R0 and G1-R0 tries\n  to consume the same singe resource from R0 then:\n\n  * We don\u0027t need to check how G2 is mapped in C0 as that mapping cannot\n    change the fact the whole candidate is invalid.\n\n  * We know that every candidate that starts with G0-R0, G1-R0 are\n    invalid for the same reason and we don\u0027t need to generate and\n    test them\n\nThe latter means that C1...Cy (y \u003c x - 1) can be pruned out from the\nsearch space after C0 is tested. This is a lot of candidates. In the\nabove natural ordering of the product generation algorithm it is\nactually more than 40K candidates that we can skip after just testing\nC0 alone. When we reach Cx, the first valid candidate, the algo already\npruned out more than 300k candidates.\n\nAfter this patch the above pruning logic is not turned on automatically\nbut can be enabled via the config option:\n\n  [workarounds]\n  optimize_for_wide_provider_trees \u003d true\n\nThe implementation consists of the following pieces:\n\nA recursive product generator algorithm that calls a function on each\npartial candidate and if that function signals that the partial\ncandidate is invalid then the algorithm does skips any candidate that\nhas the same partial candidate prefix.\n\nThe recursion does a tree traversal to find all partial prefixes.\nWith the above G0-G8, RP0, RP8 example the start of the traversal\nlooks like:\n1. partial product G0-RP0, this does not exceed capacity so recurse\n2. partial product G0-RP0, G1-RP0, this exceeds capacity so do not\n   recurse but try another RP on this level.\n3. partial product G0-RP0, G1-RP1, this does not exceeds capacity so\n   recurse.\n4. partial product G0-RP0, G1-RP1, G2-RP0, this exceeds capacity so\n   do not recurse but try another RP on this level\n...\n\nWithout the optimization Placement uses the logic\n\n        areq \u003d _consolidate_allocation_requests(areq_list, rw_ctx)\n        if rw_ctx.exceeds_capacity(areq)\n            continue\n\non all products after it was generated. The\n_consolidate_allocation_requests folds the individual\nAllocationRequestResource object in the product into a single\nallocation. This has a side effect on some of the ARRs so the logic does\ncopy the affected ARRs. This is expensive especially if we want to call\nit on every partial product as well. However if we only want to check\nthe capacity we don\u0027t need to fold the ARRs we just need to sum the\namount each ARR hold and the check that against the capacity. So\n_exceeds_capacity() was added to do this optimized, side effect and copy\nfree, capacity check when the optimization is enabled.\n\nWhen a valid product is generated _consolidate_allocation_requests still\nneeds to be called to get the folded AllocationRequest in any case as\nthe caller of _merge_candidates expects such structure. But the final\nrw_ctx.exceeds_capacity can we skipped if the optimization is enabled.\n\nThe depth of the recursion is equal to the number of iterables passed to\nthe product call. It can be seen by the fact that each level of\nrecursion appends a new item to the partial product and when the length\nof the partial product equals to the number of iterables then we have a\nfull product and the algo yields. The default python recursion limit is\n1000 so we are not really limited by that as that means we could handle\n~ 990 iterables, meaning an allocation candidate query with 990 request\ngroups. The limiting factor of this algorithm is not recursion depth but\nexecution time.\n\nGemini 2.5 pro was used to put together the generic Cartesian product\nalgorithm.\n\nCo-Authored-by: Sean Mooney \u003cwork@seanmooney.info\u003e\nAssisted-By: gemini-2.5-pro\nCloses-Bug: #2126751\nChange-Id: I13ab83a165c229ae57876df4570e8af25221a45e\nSigned-off-by: Balazs Gibizer \u003cgibi@redhat.com\u003e\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/5b73b980d0f022de2855480f57c9d5f04a7a4712"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/placement/commit/5b73b980d0f022de2855480f57c9d5f04a7a4712"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[{"rule_name":"gerrit~DefaultSubmitRule","status":"CLOSED","labels":[{"label":"Verified","status":"MAY","applied_by":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]}},{"label":"Code-Review","status":"MAY","applied_by":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"}},{"label":"Workflow","status":"MAY","applied_by":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"}},{"label":"Review-Priority","status":"MAY"}]}],"submit_requirements":[{"name":"Verified","description":"Verified in gate by CI","status":"SATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Verified\u003dMAX AND -label:Verified\u003dMIN","fulfilled":true,"status":"PASS","passing_atoms":["label:Verified\u003dMAX"],"failing_atoms":["label:Verified\u003dMIN"],"atom_explanations":{}}},{"name":"Code-Review","description":"Code reviewed by core reviewer","status":"SATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Code-Review\u003dMAX AND -label:Code-Review\u003dMIN","fulfilled":true,"status":"PASS","passing_atoms":["label:Code-Review\u003dMAX"],"failing_atoms":["label:Code-Review\u003dMIN"],"atom_explanations":{}}},{"name":"Review-Priority","description":"Review Priority","status":"NOT_APPLICABLE","is_legacy":false,"applicability_expression_result":{"fulfilled":false,"status":"FAIL"},"submittability_expression_result":{"expression":"is:true","fulfilled":true,"status":"NOT_EVALUATED","passing_atoms":[],"failing_atoms":[],"atom_explanations":{}}},{"name":"Workflow","description":"Approved for gate by core reviewer","status":"SATISFIED","is_legacy":false,"submittability_expression_result":{"expression":"label:Workflow\u003dMAX AND -label:Workflow\u003dMIN","fulfilled":true,"status":"PASS","passing_atoms":["label:Workflow\u003dMAX"],"failing_atoms":["label:Workflow\u003dMIN"],"atom_explanations":{}}}]}
