Beispiel #1
0
/*
 * Compare two sort list items, according to the sort specs.
 */
int
list_coll(struct sort_list_item **ss1, struct sort_list_item **ss2)
{

	return (list_coll_offset(ss1, ss2, 0));
}
Beispiel #2
0
static void
run_sort_level_next(struct sort_level *sl)
{
	struct sort_level *slc;
	size_t i, sln, tosort_num;

	if (sl->sublevels) {
		sort_free(sl->sublevels);
		sl->sublevels = NULL;
	}

	switch (sl->tosort_num){
	case 0:
		goto end;
	case (1):
		sl->sorted[sl->start_position] = sl->tosort[0];
		sort_left_dec(1);
		goto end;
	case (2):
		if (list_coll_offset(&(sl->tosort[0]), &(sl->tosort[1]),
		    sl->level) > 0) {
			sl->sorted[sl->start_position++] = sl->tosort[1];
			sl->sorted[sl->start_position] = sl->tosort[0];
		} else {
			sl->sorted[sl->start_position++] = sl->tosort[0];
			sl->sorted[sl->start_position] = sl->tosort[1];
		}
		sort_left_dec(2);

		goto end;
	default:
		if (TINY_NODE(sl) || (sl->level > 15)) {
			listcoll_t func;

			func = get_list_call_func(sl->level);

			sl->leaves = sl->tosort;
			sl->leaves_num = sl->tosort_num;
			sl->leaves_sz = sl->leaves_num;
			sl->leaves = sort_realloc(sl->leaves,
			    (sizeof(struct sort_list_item *) *
			    (sl->leaves_sz)));
			sl->tosort = NULL;
			sl->tosort_num = 0;
			sl->tosort_sz = 0;
			sl->sln = 0;
			sl->real_sln = 0;
			if (sort_opts_vals.sflag) {
				if (mergesort(sl->leaves, sl->leaves_num,
				    sizeof(struct sort_list_item *),
				    (int(*)(const void *, const void *)) func) == -1)
					/* NOTREACHED */
					err(2, "Radix sort error 3");
			} else
				qsort(sl->leaves, sl->leaves_num,
				    sizeof(struct sort_list_item *),
				    (int(*)(const void *, const void *)) func);

			memcpy(sl->sorted + sl->start_position,
			    sl->leaves, sl->leaves_num *
			    sizeof(struct sort_list_item*));

			sort_left_dec(sl->leaves_num);

			goto end;
		} else {
			sl->tosort_sz = sl->tosort_num;
			sl->tosort = sort_realloc(sl->tosort,
			    sizeof(struct sort_list_item*) * (sl->tosort_sz));
		}
	}

	sl->sln = 256;
	sl->sublevels = sort_malloc(slsz);
	memset(sl->sublevels, 0, slsz);

	sl->real_sln = 0;

	tosort_num = sl->tosort_num;
	for (i = 0; i < tosort_num; ++i)
		place_item(sl, i);

	sort_free(sl->tosort);
	sl->tosort = NULL;
	sl->tosort_num = 0;
	sl->tosort_sz = 0;

	if (sl->leaves_num > 1) {
		if (keys_num > 1) {
			if (sort_opts_vals.sflag) {
				mergesort(sl->leaves, sl->leaves_num,
				    sizeof(struct sort_list_item *),
				    (int(*)(const void *, const void *)) list_coll);
			} else {
				qsort(sl->leaves, sl->leaves_num,
				    sizeof(struct sort_list_item *),
				    (int(*)(const void *, const void *)) list_coll);
			}
		} else if (!sort_opts_vals.sflag && sort_opts_vals.complex_sort) {
			qsort(sl->leaves, sl->leaves_num,
			    sizeof(struct sort_list_item *),
			    (int(*)(const void *, const void *)) list_coll_by_str_only);
		}
	}

	sl->leaves_sz = sl->leaves_num;
	sl->leaves = sort_realloc(sl->leaves, (sizeof(struct sort_list_item *) *
	    (sl->leaves_sz)));

	if (!reverse_sort) {
		memcpy(sl->sorted + sl->start_position, sl->leaves,
		    sl->leaves_num * sizeof(struct sort_list_item*));
		sl->start_position += sl->leaves_num;
		sort_left_dec(sl->leaves_num);

		sort_free(sl->leaves);
		sl->leaves = NULL;
		sl->leaves_num = 0;
		sl->leaves_sz = 0;

		sln = sl->sln;

		for (i = 0; i < sln; ++i) {
			slc = sl->sublevels[i];

			if (slc) {
				slc->sorted = sl->sorted;
				slc->start_position = sl->start_position;
				sl->start_position += slc->tosort_num;
				if (SMALL_NODE(slc))
					run_sort_level_next(slc);
				else
					push_ls(slc);
				sl->sublevels[i] = NULL;
			}
		}

	} else {
		size_t n;

		sln = sl->sln;

		for (i = 0; i < sln; ++i) {
			n = sln - i - 1;
			slc = sl->sublevels[n];

			if (slc) {
				slc->sorted = sl->sorted;
				slc->start_position = sl->start_position;
				sl->start_position += slc->tosort_num;
				if (SMALL_NODE(slc))
					run_sort_level_next(slc);
				else
					push_ls(slc);
				sl->sublevels[n] = NULL;
			}
		}

		memcpy(sl->sorted + sl->start_position, sl->leaves,
		    sl->leaves_num * sizeof(struct sort_list_item*));
		sort_left_dec(sl->leaves_num);
	}

end:
	free_sort_level(sl);
}