Follow-up to #2448765: Element::children sort order undefined and slower than it could be - This makes tests fail in PHP7.
The other issue turned Element::children() into a stable sort (preserving the order in case of equal weight).

For a stable sort we don't need the funky float weights.
I suspect this group sort is better. Simpler for sure, faster maybe.

Lets just see if it passes.

CommentFileSizeAuthor
#19 D8-2522712-19-FAIL-Element-children-stable-sort-3.patch3.95 KBdonquixote
#19 D8-2522712-19-Element-children-stable-sort-3.patch3.53 KBdonquixote
#15 D8-2522712-15-FAIL-Element-children-stable-sort-3.patch3.95 KBdonquixote
#15 D8-2522712-15-Element-children-stable-sort-3.patch3.95 KBdonquixote
#14 D8-2522712-14-FAIL-Element-children-stable-sort-3.patch3.95 KBdonquixote
#14 D8-2522712-14-Element-children-stable-sort-3.patch3.95 KBdonquixote
#11 D8-2522712-11-FAIL-vs-11-Element-children-stable-sort-3.interdiff.txt2.23 KBdonquixote
#11 D8-2522712-11-Element-children-stable-sort-3.patch3.53 KBdonquixote
#11 D8-2522712-11-vs-10-Element-children-stable-sort-3.interdiff.txt1.82 KBdonquixote
#11 D8-2522712-11-FAIL-Element-children-stable-sort-3.patch3.95 KBdonquixote
#10 D8-2522712-10-Element-children-stable-sort-3.patch3.55 KBdonquixote
#10 D8-2522712-10-vs-9-Element-children-stable-sort-3.interdiff.txt656 bytesdonquixote
#9 D8-2522712-Element-children-stable-sort-3.patch3.5 KBdonquixote
#5 D8-2448765-4-Element-children-stable-sort-2.interdiff.txt4.53 KBdonquixote
#5 D8-2448765-4-Element-children-stable-sort-2.patch7.46 KBdonquixote
#5 D8-2448765-4-Element-children-stable-sort-1.interdiff.txt4.54 KBdonquixote
#5 D8-2448765-4-Element-children-stable-sort-1.patch7.35 KBdonquixote
#4 D8-2448765-4-Element-children-stable-sort-w1000.interdiff.txt3.08 KBdonquixote
#4 D8-2448765-4-Element-children-stable-sort-w1000.patch3.38 KBdonquixote
#4 D8-2448765-4-Element-children-stable-sort-2-w1000.interdiff.txt2.87 KBdonquixote
#4 D8-2448765-4-Element-children-stable-sort-2-w1000.patch3.49 KBdonquixote
#2 D8-2448765-1-Element-children-stable-sort.interdiff.txt629 bytesdonquixote
#2 D8-2448765-1-Element-children-stable-sort.patch2.93 KBdonquixote
D8-2448765-Element-children-stable-sort.patch3.1 KBdonquixote

Comments

Status: Needs review » Needs work

The last submitted patch, D8-2448765-Element-children-stable-sort.patch, failed testing.

donquixote’s picture

Status: Needs work » Needs review
StatusFileSize
new2.93 KB
new629 bytes

Forgot to set $elements['#sorted'] = TRUE.

Status: Needs review » Needs work

The last submitted patch, 2: D8-2448765-1-Element-children-stable-sort.patch, failed testing.

donquixote’s picture

Two new versions of the patch.

We need to keep the factor 1000 on the weight, otherwise the checkboxes and radios won't work correctly.
A follow-up patch will change checkboxes and radios so they no longer need this.

donquixote’s picture

Changed the checkboxes and radios, so we can remove the factor 1000 from the weight.

donquixote’s picture

The last submitted patch, 4: D8-2448765-4-Element-children-stable-sort-2-w1000.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 5: D8-2448765-4-Element-children-stable-sort-2.patch, failed testing.

donquixote’s picture

Status: Needs work » Needs review
StatusFileSize
new3.5 KB

Slightly different approach.
Instead of multiplying by 1000, we can simply convert to string to preserve float weights.
This means we no longer need to do anything about Checkboxes - although we can simplify it later.

The difference to previous patches is quite big, I won't post an interdiff.

donquixote’s picture

No need to remove this comment..

donquixote’s picture

D8-2522712-11
A few minor changes to the patch from #10.

D8-2522712-11-FAIL
Attempt to optimize, expected to fail.
This should work in theory, but there is a problem with FilterFormatEditForm / FilterFormatFormBase.
With this patch, the vertical tabs don't show up.
Somehow the "detail" elements in the render array are references. The Element::children() rearranging (unset + reinsert) destroys those references. However, the optimization in D8-2522712-11-FAIL does only rearrange some, but not all, of the children. The remaining children remain as references, which causes them to disappear.
This has to be analysed in a separate issue.

The last submitted patch, 11: D8-2522712-11-FAIL-Element-children-stable-sort-3.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 11: D8-2522712-11-Element-children-stable-sort-3.patch, failed testing.

donquixote’s picture

Duh. Wrong direction.

donquixote’s picture

Status: Needs work » Needs review

The last submitted patch, 15: D8-2522712-15-Element-children-stable-sort-3.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 15: D8-2522712-15-FAIL-Element-children-stable-sort-3.patch, failed testing.

donquixote’s picture

donquixote’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 19: D8-2522712-19-FAIL-Element-children-stable-sort-3.patch, failed testing.

donquixote’s picture

Status: Needs work » Needs review

Great!
The patch that is meant to work passes the tests. Back to "Needs review".

The other patch is expected to fail, until #2527762: FilterFormatEditForm vertical tabs not working without #weight. is fixed.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

fabianx’s picture

I appreciate the effort. Could you help out to create re-usable helper functions in #2466097: uasort() does NOT preserve sort order, but core assumes so (Element::children, css sort, ...), please?

It is really bad that we need to write the same code again and again ...

donquixote’s picture

@Fabianx: Ok, as a first step, I did post an ignorant comment over there. Not helping, I guess.

donquixote’s picture

@Fabianx: Looking at this again, and also the other issue.

My conclusion for now:
Render arrays are really a special cup of tea. Besides the sorting problem, we need to distinguish element children vs element properties (starting with '#'). And then there is the reference issue described in #11.

I think it is better for performance and for transparency to have a dedicated one-off sort implementation for this specific case. So, exactly what is being proposed in this issue.

This said, I do agree we want reusable sort functions for other cases.
In most of the examples, we are comparing item weights. The items can be arrays or objects, and the weight is e.g. $item['#weight'] or $item->getWeight().

So far the approach in the other issue seemed to be to have a stable equivalent to PHP's native uasort(), with a comparison callback. Poor performance can be expected with this approach.

Instead, we should first extract all the weights, sort the keys by weight (stable), and then build the sorted array of items.
There are different ways to implement this. The idea is mostly the same, but there is difference in the detail. We need to find out which one is faster.

In fact we can have more than one function. E.g. one to sort by $item[$weight_key], another to sort by $item->$weightMethodName(), another to sort by $weight_callback($item). Maybe special variation with a hardcoded weight method name, e.g. $item->getWeight().

I personally think this does not belong in Drupal core, but in a 3rd party library.
But even if we do it in Drupal, we should have one dedicated issue + patch + commit which only adds this function with a bunch of tests, and does not fix all the instances where we want to use it. The latter should rather be a separate issue + patch + commit.
The existing issue, #2466097: uasort() does NOT preserve sort order, but core assumes so (Element::children, css sort, ...), is already far too long.
Better start new, I'd say: "Implement a stable-sort-by-weight function".

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Version: 9.5.x-dev » 10.1.x-dev
Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs issue summary update

This issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge require as a guide.

Tagging for an issue summary update for what needs to be done in D10

Reading #26 are you saying this and https://www.drupal.org/project/drupal/issues/2466097 should be consolidated?

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.