Skip to content

Commit 017ec7d

Browse files
authored
Merge pull request #177 from yenslife/stable-sort-test
Check if sorting implementation is stable
2 parents 9bda828 + b0aa080 commit 017ec7d

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)