<commit_before>/*-------------------------------------------------------------------------
 *
 * sort.c
 *	  sort of data inside columns
 *
 * Portions Copyright (c) 2017-2021 <NAME>
 *
 * IDENTIFICATION
 *	  src/sort.c
 *
 *-------------------------------------------------------------------------
 */

#include <stdlib.h>
#include <string.h>

#include "pspg.h"

static int
compar_num_asc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_DOUBLE)
	{
		if (sda->info == INFO_DOUBLE)
			return sda->d - sdb->d;
		else
			return 1;
	}
	else
	{
		if (sda->info == INFO_DOUBLE)
			return -1;
		else
			return 0;
	}
}

static int
compar_num_desc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_DOUBLE)
	{
		if (sda->info == INFO_DOUBLE)
			return sdb->d - sda->d;
		else
			return 1;
	}
	else
	{
		if (sda->info == INFO_DOUBLE)
			return -1;
		else
			return 0;
	}
}

void
sort_column_num(SortData *sortbuf, int rows, bool desc)
{

	qsort(sortbuf, rows, sizeof(SortData), desc ? compar_num_desc : compar_num_asc);
}

static int
compar_text_asc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_STRXFRM)
	{
		if (sda->info == INFO_STRXFRM)
			return strcmp(sda->strxfrm, sdb->strxfrm);<commit_msg>fix sort of big numeric values (or values with units GB, TB)<commit_after>/*-------------------------------------------------------------------------
 *
 * sort.c
 *	  sort of data inside columns
 *
 * Portions Copyright (c) 2017-2021 <NAME>
 *
 * IDENTIFICATION
 *	  src/sort.c
 *
 *-------------------------------------------------------------------------
 */

#include <stdlib.h>
#include <string.h>

#include "pspg.h"

static inline int
signof(double n)
{
	if (n < 0)
		return -1;
	else if (n > 0)
		return 1;
	else
		return 0;
}

static int
compar_num_asc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_DOUBLE)
	{
		if (sda->info == INFO_DOUBLE)
			/*
			 * Without using signof function there is possible problem with
			 * mapping of 8bytes double to 4bytes int (the sign of result value
			 * after casting can be wrong).
			 */
			return signof(sda->d - sdb->d);
		else
			return 1;
	}
	else
	{
		if (sda->info == INFO_DOUBLE)
			return -1;
		else
			return 0;
	}
}

static int
compar_num_desc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_DOUBLE)
	{
		if (sda->info == INFO_DOUBLE)
			return signof(sdb->d - sda->d);
		else
			return 1;
	}
	else
	{
		if (sda->info == INFO_DOUBLE)
			return -1;
		else
			return 0;
	}
}

void
sort_column_num(SortData *sortbuf, int rows, bool desc)
{

	qsort(sortbuf, rows, sizeof(SortData), desc ? compar_num_desc : compar_num_asc);
}

static int
compar_text_asc(const void *a, const void *b)
{
	SortData   *sda = (SortData *) a;
	SortData   *sdb = (SortData *) b;

	if (sdb->info == INFO_STRXFRM)
	{
		if (sda->info == INFO_STRXFRM)
			return strcmp(sda->strxfrm, sdb->strxfrm);
{'fraction_non_alphanumeric': 0.22260380892912895, 'fraction_numerical': 0.010927255697783328, 'mean_word_length': 2.1566502463054187, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3245334', 'n_tokens_mistral': 1318, 'n_tokens_neox': 1225, 'n_words': 319}