Skip to content

Commit c29b1a4

Browse files
yenslifeHuadesuwa
authored andcommitted
Check if sorting implementation is stable
Introduced node numbering in qtest.c to evaluate the stability of q_sort's sorting algorithm. When the algorithm encounters two nodes with the same value, it searches for the address of the node record in the nodes array. It then compares the found node to the current node (cur). If the found node is the same as the current node, it indicates that these two duplicate nodes have not been swapped in position after sorting. However, if the found node is cur->next, it means that the position of the nodes has been swapped. That is, the sorting implementation is unstable. The performance of the testing code was evaluated by measuring the elapsed time for q_sort's operation on different numbers of nodes with duplicate values. Node counts ranging from 1000 to 500,000 were examined. Specifically, for the 1000-node count, the elapsed time was recorded as 0.0279 seconds, and for the 500,000-node count, it was 61.44 seconds. For the 100,000-node count, the elapsed time was 2.45 seconds. The elapsed time showed a significant increase starting from the 100,000-node count, underscoring potential performance issues with larger datasets. This method relies on auxiliary data structures to track node pointers and their original order, avoiding alterations to the structure in queue.h. However, stability testing is limited to a maximum of 100,000 elements (MAX_NODES) to address potential performance concerns.
1 parent 492908e commit c29b1a4

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

qtest.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,23 @@ bool do_sort(int argc, char *argv[])
595595
error_check();
596596

597597
set_noallocate_mode(true);
598+
599+
/* If the number of elements is too large, it may take a long time to check the
600+
* stability of the sort. So, MAX_NODES is used to limit the number of elements
601+
* to check the stability of the sort. */
602+
#define MAX_NODES 100000
603+
struct list_head *nodes[MAX_NODES];
604+
unsigned no = 0;
605+
if (current && current->size && current->size <= MAX_NODES) {
606+
element_t *entry;
607+
list_for_each_entry (entry, current->q, list)
608+
nodes[no++] = &entry->list;
609+
} else if (current && current->size > MAX_NODES)
610+
report(1,
611+
"Warning: Skip checking the stability of the sort because the "
612+
"number of elements %d is too large, exceeds the limit %d.",
613+
current->size, MAX_NODES);
614+
598615
if (current && exception_setup(true))
599616
q_sort(current->q, descend);
600617
exception_cancel();
@@ -619,8 +636,32 @@ bool do_sort(int argc, char *argv[])
619636
ok = false;
620637
break;
621638
}
639+
/* Ensure the stability of the sort */
640+
if (current->size <= MAX_NODES &&
641+
!strcmp(item->value, next_item->value)) {
642+
bool unstable = false;
643+
for (unsigned i = 0; i < MAX_NODES; i++) {
644+
if (nodes[i] == cur_l->next) {
645+
unstable = true;
646+
break;
647+
}
648+
if (nodes[i] == cur_l) {
649+
break;
650+
}
651+
}
652+
if (unstable) {
653+
report(
654+
1,
655+
"ERROR: Not stable sort. The duplicate strings \"%s\" "
656+
"are not in the same order.",
657+
item->value);
658+
ok = false;
659+
break;
660+
}
661+
}
622662
}
623663
}
664+
#undef MAX_NODES
624665

625666
q_show(3);
626667
return ok && !error_check();

0 commit comments

Comments
 (0)