From 862930b2e4358e9a1b5ef5324de8cef84be49a87 Mon Sep 17 00:00:00 2001 From: xyz32 Date: Thu, 23 Oct 2025 17:16:07 -0400 Subject: [PATCH] perf-enhancement: Add Vector_sort function w/ context support Consolidates vector sorting functions as mentioned in issue #1785. Implements Highlander Rule by providing single sorting function. Features: - Context-aware comparison functions for sorting logic - Hybrid algo: insertion sort <=16 elements, quicksort >16 elements - Backward compatible. Existing functions unchanged - NULL-safe context handling Performance benefits: - Algo selection based on array sizing - Faster inserts on large arrays than w/ pure insertion sort - Standard 16 element thresh for algo switching This address issue #1785 w/o breaking existing code. Future commits can migrate call sites to use Vector_sort gradually (if merged) --- Vector.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ Vector.h | 4 ++++ 2 files changed, 55 insertions(+) diff --git a/Vector.c b/Vector.c index edb89dfd6..99b63fde9 100644 --- a/Vector.c +++ b/Vector.c @@ -167,6 +167,44 @@ static void insertionSort(Object** array, int left, int right, Object_Compare co } } +static void insertionSortWithContext(Object** array, int left, int right, Object_CompareWithContext compare, void* context) { + for (int i = left + 1; i <= right; i++) { + Object* t = array[i]; + int j = i - 1; + while (j >= left) { + if (compare(array[j], t, context) <= 0) + break; + array[j + 1] = array[j]; + j--; + } + array[j + 1] = t; + } +} + +static int partitionWithContext(Object** array, int left, int right, int pivotIndex, Object_CompareWithContext compare, void* context) { + const Object* pivotValue = array[pivotIndex]; + swap(array, pivotIndex, right); + int storeIndex = left; + for (int i = left; i < right; i++) { + if (compare(array[i], pivotValue, context) <= 0) { + swap(array, i, storeIndex); + storeIndex++; + } + } + swap(array, storeIndex, right); + return storeIndex; +} + +static void quickSortWithContext(Object** array, int left, int right, Object_CompareWithContext compare, void* context) { + if (left >= right) + return; + + int pivotIndex = left + (right - left) / 2; + int pivotNewIndex = partitionWithContext(array, left, right, pivotIndex, compare, context); + quickSortWithContext(array, left, pivotNewIndex - 1, compare, context); + quickSortWithContext(array, pivotNewIndex + 1, right, compare, context); +} + void Vector_quickSortCustomCompare(Vector* this, Object_Compare compare) { assert(compare); assert(Vector_isConsistent(this)); @@ -174,6 +212,19 @@ void Vector_quickSortCustomCompare(Vector* this, Object_Compare compare) { assert(Vector_isConsistent(this)); } +void Vector_sort(Vector* this, Object_CompareWithContext compare, void* context) { + assert(compare); + assert(Vector_isConsistent(this)); + + if (this->items <= 16) { + insertionSortWithContext(this->array, 0, this->items - 1, compare, context); + } else { + quickSortWithContext(this->array, 0, this->items - 1, compare, context); + } + + assert(Vector_isConsistent(this)); +} + void Vector_insertionSort(Vector* this) { assert(this->type->compare); assert(Vector_isConsistent(this)); diff --git a/Vector.h b/Vector.h index 95617eda9..5e451d7ea 100644 --- a/Vector.h +++ b/Vector.h @@ -35,6 +35,10 @@ void Vector_delete(Vector* this); void Vector_prune(Vector* this); +typedef int(*Object_CompareWithContext)(const void*, const void*, void* context); + +void Vector_sort(Vector* this, Object_CompareWithContext compare, void* context); + void Vector_quickSortCustomCompare(Vector* this, Object_Compare compare); static inline void Vector_quickSort(Vector* this) { Vector_quickSortCustomCompare(this, this->type->compare);