Пример #1
0
void
initialise_months(void)
{
	const nl_item item[12] = { ABMON_1, ABMON_2, ABMON_3, ABMON_4,
	    ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10,
	    ABMON_11, ABMON_12 };
	unsigned char *tmp;
	size_t len;

	if (MB_CUR_MAX == 1) {
		if (cmonths == NULL) {
			unsigned char *m;

			cmonths = sort_malloc(sizeof(unsigned char*) * 12);
			for (int i = 0; i < 12; i++) {
				cmonths[i] = NULL;
				tmp = (unsigned char *) nl_langinfo(item[i]);
				if (debug_sort)
					printf("month[%d]=%s\n", i, tmp);
				if (*tmp == '\0')
					continue;
				m = sort_strdup(tmp);
				len = strlen(tmp);
				for (unsigned int j = 0; j < len; j++)
					m[j] = toupper(m[j]);
				cmonths[i] = m;
			}
		}

	} else {
		if (wmonths == NULL) {
			wchar_t *m;

			wmonths = sort_malloc(sizeof(wchar_t *) * 12);
			for (int i = 0; i < 12; i++) {
				wmonths[i] = NULL;
				tmp = (unsigned char *) nl_langinfo(item[i]);
				if (debug_sort)
					printf("month[%d]=%s\n", i, tmp);
				if (*tmp == '\0')
					continue;
				len = strlen(tmp);
				m = sort_malloc(SIZEOF_WCHAR_STRING(len + 1));
				if (mbstowcs(m, (char*)tmp, len) ==
				    ((size_t) - 1)) {
					sort_free(m);
					continue;
				}
				m[len] = L'\0';
				for (unsigned int j = 0; j < len; j++)
					m[j] = towupper(m[j]);
				wmonths[i] = m;
			}
		}
	}
}
Пример #2
0
static void
add_to_sublevel(struct sort_level *sl, struct sort_list_item *item, int indx)
{
	struct sort_level *ssl;

	ssl = sl->sublevels[indx];

	if (ssl == NULL) {
		ssl = sort_malloc(sizeof(struct sort_level));
		memset(ssl, 0, sizeof(struct sort_level));

		ssl->level = sl->level + 1;
		sl->sublevels[indx] = ssl;

		++(sl->real_sln);
	}

	if (++(ssl->tosort_num) > ssl->tosort_sz) {
		ssl->tosort_sz = ssl->tosort_num + 128;
		ssl->tosort = sort_realloc(ssl->tosort,
		    sizeof(struct sort_list_item*) * (ssl->tosort_sz));
	}

	ssl->tosort[ssl->tosort_num - 1] = item;
}
Пример #3
0
/*
 * Allocate a new binary string of specified size
 */
struct bwstring *
bwsalloc(size_t sz)
{
	struct bwstring *ret;

	if (MB_CUR_MAX == 1)
		ret = sort_malloc(sizeof(struct bwstring) + 1 + sz);
	else
		ret = sort_malloc(sizeof(struct bwstring) +
		    SIZEOF_WCHAR_STRING(sz + 1));
	ret->len = sz;

	if (MB_CUR_MAX == 1)
		ret->data.cstr[ret->len] = '\0';
	else
		ret->data.wstr[ret->len] = L'\0';

	return (ret);
}
Пример #4
0
/*
 * Allocate keys array
 */
struct keys_array *
keys_array_alloc(void)
{
	struct keys_array *ka;
	size_t sz;

	sz = keys_array_size();
	ka = sort_malloc(sz);
	memset(ka, 0, sz);

	return (ka);
}
Пример #5
0
/*
 * Initialize a sort list item
 */
struct sort_list_item *
sort_list_item_alloc(void)
{
	struct sort_list_item *si;
	size_t sz;

	sz = sizeof(struct sort_list_item) + keys_array_size();
	si = sort_malloc(sz);
	memset(si, 0, sz);

	return (si);
}
Пример #6
0
static void
run_sort(struct sort_list_item **base, size_t nmemb)
{
	struct sort_level *sl;

#if defined(SORT_THREADS)
	size_t nthreads_save = nthreads;
	if (nmemb < MT_SORT_THRESHOLD)
		nthreads = 1;

	if (nthreads > 1) {
		pthread_mutexattr_t mattr;

		pthread_mutexattr_init(&mattr);
		pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ADAPTIVE_NP);

		pthread_mutex_init(&g_ls_mutex, &mattr);
		pthread_mutex_init(&sort_left_mutex, &mattr);

		pthread_mutexattr_destroy(&mattr);

		sem_init(&mtsem, 0, 0);

	}
#endif

	sl = sort_malloc(sizeof(struct sort_level));
	memset(sl, 0, sizeof(struct sort_level));

	sl->tosort = base;
	sl->tosort_num = nmemb;
	sl->tosort_sz = nmemb;

#if defined(SORT_THREADS)
	sort_left = nmemb;
#endif

	run_top_sort_level(sl);

	free_sort_level(sl);

#if defined(SORT_THREADS)
	if (nthreads > 1) {
		sem_destroy(&mtsem);
		pthread_mutex_destroy(&g_ls_mutex);
		pthread_mutex_destroy(&sort_left_mutex);
	}
	nthreads = nthreads_save;
#endif
}
Пример #7
0
/*
 * Push sort level to the stack
 */
static inline void
push_ls(struct sort_level* sl)
{
	struct level_stack *new_ls;

	new_ls = sort_malloc(sizeof(struct level_stack));
	new_ls->sl = sl;

#if defined(SORT_THREADS)
	if (nthreads > 1)
		pthread_mutex_lock(&g_ls_mutex);
#endif

	new_ls->next = g_ls;
	g_ls = new_ls;

#if defined(SORT_THREADS)
	if (nthreads > 1)
		pthread_mutex_unlock(&g_ls_mutex);
#endif
}
Пример #8
0
static void
run_top_sort_level(struct sort_level *sl)
{
	struct sort_level *slc;

	reverse_sort = sort_opts_vals.kflag ? keys[0].sm.rflag :
	    default_sort_mods->rflag;

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

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

	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);
		}
	}

	if (!reverse_sort) {
		memcpy(sl->tosort + 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);

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

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

	} else {
		size_t n;

		for (size_t i = 0; i < sl->sln; ++i) {

			n = sl->sln - i - 1;
			slc = sl->sublevels[n];

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

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

		sort_left_dec(sl->leaves_num);
	}

#if defined(SORT_THREADS)
	if (nthreads < 2) {
#endif
		run_sort_cycle_st();
#if defined(SORT_THREADS)
	} else {
		size_t i;

		for(i = 0; i < nthreads; ++i) {
			pthread_attr_t attr;
			pthread_t pth;

			pthread_attr_init(&attr);
			pthread_attr_setdetachstate(&attr,
			    PTHREAD_DETACHED);

			pthread_create(&pth, &attr, sort_thread, NULL);

			pthread_attr_destroy(&attr);
		}

		for(i = 0; i < nthreads; ++i)
			sem_wait(&mtsem);
	}
#endif /* defined(SORT_THREADS) */
}
Пример #9
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);
}