-
Notifications
You must be signed in to change notification settings - Fork 8k
Fix SORT_REGULAR with new transitive comparison functions #20517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Introduces localized transitive comparators (including array/object recursion and HashTable helpers) so SORT_REGULAR sorting and array_unique() can enforce consistent ordering without touching zend_compare(). The sort entry points now detect when mixed numeric string semantics are needed and delegate to php_array_sort_regular(), while array_unique() switches to the same comparator when required. Fixes: phpGH-20262
Implement scalar/string fast paths and enum/object ordering rules so both regular and transitive SORT_REGULAR comparators skip redundant zend_compare() calls. Introduce php_array_compare_non_numeric_strings() and dedicated transitive string/number helpers to minimize numeric parsing.
Avoid temporary zend_string allocations in `compare_long_to_string()` and `compare_double_to_string()` by using stack buffers, and streamline `zendi_smart_strcmp()` with non-numeric short-circuits plus single-pass numeric parsing to cut redundant work in general comparisons.
- Introduce the transitive-aware compare_long/double/string helpers in Zend. - Switch array sorts and array_unique to use them and adjust php_hash_values_need_transitivity().
Girgias
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Various comments and questions and this needs a rebase as I refactored the sorting code to remove a bunch of duplication.
|
@Girgias thank you for taking the time to provide the careful review! Looks like I was able to capture your sorting code refactor when I created this new branch. I'll push a fresh commit what I addressed in your code comments. Thanks again for the help! |
- Call zend_compare_symbol_tables() for array pairs and keep the enum-specific path without the ZEND_UNCOMPARABLE check. - Point the regular key/data variants directly at their impls via DEFINE_SORT_VARIANTS_USING(), retaining php_array_hash_compare_transitive() as the required compare_func_t adapter. - Make php_hash_has_string_keys() const-qualified and keep php_array_compare_transitive() for nested arrays/objects/enums while scalar fast paths stay in the main comparator.
Summary
Fixes #20262 by making
SORT_REGULARfall back to a fully transitive comparator whenever loose comparisons would otherwise be non-transitive (e.g. numeric strings vs numeric zvals). That keeps duplicates grouped soarray_unique()and the sort family behave consistently.Highlights
php_array_sort_regular()fast path so only the arrays that need this comparator pay for it.array_unique()to call the fast path automatically when required.sort()andarray_unique()