SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddssort.c File Reference

Detailed Description

Sorts an SDDS dataset by column or parameter values.

The sddssort program provides flexible sorting capabilities for SDDS datasets. Users can sort by one or more columns or parameters, perform unique row elimination, and handle multi-criteria optimization through non-dominated sorting. The program supports numeric sorting, absolute value sorting, and major order changes for row or column storage.

Usage

sddssort [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
[-column=<name>[,{increasing|decreasing}|{minimize|maximize}][,absolute]...]
[-unique[=count]]
[-nowarnings]
[-parameter=<name>[,{increasing|decreasing}]...]
[-numericHigh]
[-nonDominateSort]
[-majorOrder=row|column]
int unique(void *base, size_t n_items, size_t size, int(*compare)(const void *a, const void *b), void(*copy)(void *a, void *b))
Remove duplicate elements from a sorted array.

Options

Optional Description
-pipe Enables piping for input and/or output.
-column Specifies columns for sorting with optional modifiers.
-unique Removes duplicate rows. If count is specified, includes an IdenticalCount column.
-nowarnings Suppresses warning messages.
-parameter Specifies parameters for sorting with optional modifiers.
-numericHigh Prioritizes numeric characters in string comparisons.
-nonDominateSort Enables non-dominated sorting for numeric columns.
-majorOrder Changes the data storage order to row-major or column-major.

Specific Requirements

  • For -nonDominateSort:
    • Requires at least two columns.
    • Columns must contain numeric data types.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddssort.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"
#include "non_dominated_sort.h"
#include <unistd.h>

Go to the source code of this file.

Functions

long SDDS_SortRows (SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long non_dominate_sort)
 
long SDDS_UnsetDuplicateRows (SDDS_DATASET *SDDS_dataset, SORT_REQUEST *xsort_request, long xsort_requests, long provideIdenticalCount)
 
long SDDS_SortAll (SDDS_DATASET *SDDS_input, SDDS_DATASET *SDDS_output, SORT_REQUEST *xsort_request, long xsort_requests, SORT_REQUEST *xsort_parameter, long xsort_parameters, long uniqueRows, long provideIdenticalCount, long pipeFlags, long non_dominate_sort)
 
double * read_constr_violation (SDDS_DATASET *SDDS_dataset)
 
int main (int argc, char **argv)
 
int SDDS_CompareData (SDDS_DATASET *SDDS_dataset, short type, short absolute, void *data1, void *data2)
 
int SDDS_CompareRows (const void *vrow1, const void *vrow2)
 
long SDDS_SwapRows (SDDS_DATASET *SDDS_dataset, int64_t row1, int64_t row2)
 
int SDDS_ComparePages (const void *vpage1, const void *vpage2)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 154 of file sddssort.c.

154 {
155 SDDS_DATASET SDDS_input, SDDS_output, SDDS_tmp;
156 char *input, *output;
157 long i_arg, non_dominate_sort = 0;
158 SCANNED_ARG *s_arg;
159
160 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
161 long sort_parameters;
162 SORT_REQUEST *sort_request, *sort_parameter;
163 unsigned long pipeFlags, majorOrderFlag;
164 short columnMajorOrder = -1;
165
167 argc = scanargs(&s_arg, argc, argv);
168 if (argc < 2) {
169 bomb(NULL, USAGE);
170 }
171
172 input = output = NULL;
173 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
174 sort_request = sort_parameter = NULL;
175 pipeFlags = 0;
176 uniqueRows = provideIdenticalCount = 0;
177 for (i_arg = 1; i_arg < argc; i_arg++) {
178 if (s_arg[i_arg].arg_type == OPTION) {
179 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
180 case SET_MAJOR_ORDER:
181 majorOrderFlag = 0;
182 s_arg[i_arg].n_items--;
183 if (s_arg[i_arg].n_items > 0 &&
184 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
185 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
186 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
187 SDDS_Bomb("invalid -majorOrder syntax/values");
188 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
189 columnMajorOrder = 1;
190 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
191 columnMajorOrder = 0;
192 break;
193 case SET_NON_DOMINATE_SORT:
194 non_dominate_sort = 1;
195 break;
196 case SET_COLUMN:
197 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
198 SDDS_Bomb("invalid -column syntax");
199 sort_request = trealloc(sort_request, sizeof(*sort_request) * (sort_requests + 1));
200 sort_request[sort_requests].name = s_arg[i_arg].list[1];
201 sort_request[sort_requests].maximize_order = 0;
202 sort_request[sort_requests].decreasing_order = 0;
203 sort_request[sort_requests].absolute = 0;
204 if (s_arg[i_arg].n_items >= 3) {
205 int j;
206 for (j = 2; j < s_arg[i_arg].n_items; j++) {
207 switch (match_string(s_arg[i_arg].list[j], order_mode, 5, 0)) {
208 case 0:
209 break;
210 case 1:
211 sort_request[sort_requests].decreasing_order = 1;
212 break;
213 case 2:
214 break;
215 case 3:
216 sort_request[sort_requests].maximize_order = 1;
217 break;
218 case 4:
219 sort_request[sort_requests].absolute = 1;
220 break;
221 default:
222 fprintf(stderr, "unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
223 exit(EXIT_FAILURE);
224 break;
225 }
226 }
227 }
228 sort_requests++;
229 break;
230 case SET_PARAMETER:
231 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
232 SDDS_Bomb("invalid -parameter syntax");
233 sort_parameter = trealloc(sort_parameter, sizeof(*sort_parameter) * (sort_parameters + 1));
234 sort_parameter[sort_parameters].name = s_arg[i_arg].list[1];
235 if (s_arg[i_arg].n_items == 3) {
236 if ((sort_parameter[sort_parameters].decreasing_order = match_string(s_arg[i_arg].list[2], order_mode, 2, 0)) < 0)
237 SDDS_Bomb("unknown sort order specified--give 'increasing' or 'decreasing'");
238 } else
239 sort_parameter[sort_parameters].decreasing_order = 0;
240 sort_parameters++;
241 break;
242 case SET_NOWARNINGS:
243 noWarnings = 1;
244 break;
245 case SET_NUMERICHIGH:
246 numericHigh = 1;
247 break;
248 case SET_PIPE:
249 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
250 SDDS_Bomb("invalid -pipe syntax");
251 break;
252 case SET_UNIQUE:
253 uniqueRows = 1;
254 if (s_arg[i_arg].n_items > 1) {
255 str_tolower(s_arg[i_arg].list[1]);
256 if (s_arg[i_arg].n_items > 2 ||
257 strncmp("count", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) != 0)
258 SDDS_Bomb("invalid -unique syntax");
259 provideIdenticalCount = 1;
260 }
261 break;
262 default:
263 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
264 exit(EXIT_FAILURE);
265 break;
266 }
267 } else {
268 if (input == NULL)
269 input = s_arg[i_arg].list[0];
270 else if (output == NULL)
271 output = s_arg[i_arg].list[0];
272 else
273 SDDS_Bomb("too many filenames");
274 }
275 }
276
277 if (!sort_requests && !sort_parameters)
278 SDDS_Bomb("No sorting requests!");
279 processFilenames("sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
280 if (!SDDS_InitializeInput(&SDDS_input, input)) {
281 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
282 exit(EXIT_FAILURE);
283 }
284 if (sort_requests <= 1)
285 non_dominate_sort = 0;
286
287 if (SDDS_input.layout.popenUsed) {
288 /* SDDS library has opened the file using a command on a pipe, usually for
289 * decompression in the absence of the zlib library.
290 */
291 pid_t pid;
292 char tmpfileName[1024];
293 pid = getpid();
294 sprintf(tmpfileName, "/tmp/sddssort.%ld", (long)pid);
295 tmpfileForInternalPipe = 1;
296 if (!SDDS_InitializeCopy(&SDDS_tmp, &SDDS_input, tmpfileName, "w")) {
297 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
298 exit(EXIT_FAILURE);
299 }
300 if (columnMajorOrder != -1)
301 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
302 else
303 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
304 if (non_dominate_sort) {
305 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
306 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
307 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
308 exit(EXIT_FAILURE);
309 }
310 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
311 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
312 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
313 constDefined = 1;
314 }
315 }
316
317 if (!SDDS_WriteLayout(&SDDS_tmp)) {
318 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
319 exit(EXIT_FAILURE);
320 }
321 while (SDDS_ReadPage(&SDDS_input) > 0) {
322 if (!SDDS_CopyPage(&SDDS_tmp, &SDDS_input) || !SDDS_WritePage(&SDDS_tmp)) {
323 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
324 exit(EXIT_FAILURE);
325 }
326 }
327 if (!SDDS_Terminate(&SDDS_tmp)) {
328 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
329 exit(EXIT_FAILURE);
330 }
331 if (!SDDS_InitializeInput(&SDDS_input, tmpfileName)) {
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
333 exit(EXIT_FAILURE);
334 }
335 }
336 if (!SDDS_InitializeCopy(&SDDS_output, &SDDS_input, output, "w")) {
337 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
338 exit(EXIT_FAILURE);
339 }
340 if (columnMajorOrder != -1)
341 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
342 else
343 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
344 if (provideIdenticalCount &&
345 !SDDS_DefineSimpleColumn(&SDDS_output, "IdenticalCount", NULL, SDDS_LONG64)) {
346 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
347 exit(EXIT_FAILURE);
348 }
349 if (non_dominate_sort) {
350 if (!SDDS_DefineSimpleColumn(&SDDS_output, "Rank", NULL, SDDS_LONG) ||
351 !SDDS_DefineSimpleColumn(&SDDS_output, "CrowdingDistance", NULL, SDDS_DOUBLE)) {
352 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
353 exit(EXIT_FAILURE);
354 }
355 if (SDDS_CheckColumn(&SDDS_input, "ConstraintsViolation", NULL, SDDS_ANY_NUMERIC_TYPE, NULL) != SDDS_CHECK_OK) {
356 if (!SDDS_DefineSimpleColumn(&SDDS_output, "ConstraintsViolation", NULL, SDDS_DOUBLE))
357 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
358 constDefined = 1;
359 }
360 }
361 if (!SDDS_WriteLayout(&SDDS_output))
362 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
363 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
364 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
365 SDDS_SetError("Problem sorting data");
366 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
367 }
368 if (!SDDS_Terminate(&SDDS_input) || !SDDS_Terminate(&SDDS_output)) {
369 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
370 exit(EXIT_FAILURE);
371 }
372 if (tmpfile_used && !replaceFileAndBackUp(input, output))
373 exit(EXIT_FAILURE);
374 free_scanargs(&s_arg, argc);
375 /* if (tmpfileForInternalPipe)
376 system("rm /tmp/tmpfile"); */
377 return EXIT_SUCCESS;
378}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
Definition SDDStypes.h:49
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
char * str_tolower(char *s)
Convert a string to lower case.
Definition str_tolower.c:27

◆ read_constr_violation()

double * read_constr_violation ( SDDS_DATASET * SDDS_dataset)

Definition at line 952 of file sddssort.c.

952 {
953 double *const_violation = NULL, **data = NULL;
954 int32_t columns, constraints, j;
955 int64_t i, rows;
956 char **columnName = NULL;
957
958 columns = constraints = 0;
959 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
960 if (!constDefined && !(const_violation = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, "ConstraintsViolation")))
961 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
962 else {
963 if (!(columnName = (char **)SDDS_GetColumnNames(SDDS_dataset, &columns)))
964 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
965 for (i = 0; i < columns; i++) {
966 if (wild_match(columnName[i], "*Constraints*") && strcmp(columnName[i], "ConstraintsViolation") != 0) {
967 data = SDDS_Realloc(data, sizeof(*data) * (constraints + 1));
968 data[constraints] = NULL;
969 if (!(data[constraints] = (double *)SDDS_GetColumnInDoubles(SDDS_dataset, columnName[i])))
970 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
971 constraints++;
972 }
973 }
974 if (constraints) {
975 const_violation = calloc(rows, sizeof(*const_violation));
976 for (i = 0; i < rows; i++) {
977 for (j = 0; j < constraints; j++) {
978 if (data[j][i] < 0)
979 const_violation[i] += data[j][i];
980 }
981 }
982 for (j = 0; j < constraints; j++)
983 free(data[j]);
984 free(data);
985 }
986 }
987 return const_violation;
988}
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49

◆ SDDS_CompareData()

int SDDS_CompareData ( SDDS_DATASET * SDDS_dataset,
short type,
short absolute,
void * data1,
void * data2 )

Definition at line 385 of file sddssort.c.

385 {
386 double ldouble_diff;
387 double double_diff;
388 float float_diff;
389 int32_t long_diff;
390 int64_t long64_diff;
391 short short_diff;
392 int char_diff;
393
394 if (!absolute) {
395 switch (type) {
396 case SDDS_LONGDOUBLE:
397 if ((ldouble_diff = *(long double *)data1 - *(long double *)data2) > 0)
398 return (1);
399 else if (ldouble_diff < 0)
400 return (-1);
401 return (0);
402 case SDDS_DOUBLE:
403 if ((double_diff = *(double *)data1 - *(double *)data2) > 0)
404 return (1);
405 else if (double_diff < 0)
406 return (-1);
407 return (0);
408 case SDDS_FLOAT:
409 if ((float_diff = *(float *)data1 - *(float *)data2) > 0)
410 return (1);
411 else if (float_diff < 0)
412 return (-1);
413 return (0);
414 case SDDS_LONG64:
415 if ((long64_diff = *(int64_t *)data1 - *(int64_t *)data2) > 0)
416 return (1);
417 else if (long64_diff < 0)
418 return (-1);
419 return (0);
420 case SDDS_LONG:
421 if ((long_diff = *(int32_t *)data1 - *(int32_t *)data2) > 0)
422 return (1);
423 else if (long_diff < 0)
424 return (-1);
425 return (0);
426 case SDDS_SHORT:
427 if ((short_diff = *(short *)data1 - *(short *)data2) > 0)
428 return (1);
429 else if (short_diff < 0)
430 return (-1);
431 return (0);
432 case SDDS_ULONG64:
433 if (*(uint64_t *)data1 > *(uint64_t *)data2)
434 return 1;
435 if (*(uint64_t *)data1 < *(uint64_t *)data2)
436 return -1;
437 return 0;
438 case SDDS_ULONG:
439 if (*(uint32_t *)data1 > *(uint32_t *)data2)
440 return 1;
441 if (*(uint32_t *)data1 < *(uint32_t *)data2)
442 return -1;
443 return 0;
444 case SDDS_USHORT:
445 if (*(unsigned short *)data1 > *(unsigned short *)data2)
446 return 1;
447 if (*(unsigned short *)data1 < *(unsigned short *)data2)
448 return -1;
449 return 0;
450 case SDDS_CHARACTER:
451 if ((char_diff = *(char *)data1 - *(char *)data2) > 0)
452 return (1);
453 else if (char_diff < 0)
454 return (-1);
455 return (0);
456 case SDDS_STRING:
457 if (numericHigh)
458 return (strcmp_nh(*(char **)data1, *(char **)data2));
459 else
460 return (strcmp(*(char **)data1, *(char **)data2));
461 default:
462 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
463 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
464 exit(EXIT_FAILURE);
465 }
466 } else {
467 switch (type) {
468 case SDDS_LONGDOUBLE:
469 if ((ldouble_diff = fabsl(*(long double *)data1) - fabsl(*(long double *)data2)) > 0)
470 return (1);
471 else if (ldouble_diff < 0)
472 return (-1);
473 return (0);
474 case SDDS_DOUBLE:
475 if ((double_diff = fabs(*(double *)data1) - fabs(*(double *)data2)) > 0)
476 return (1);
477 else if (double_diff < 0)
478 return (-1);
479 return (0);
480 case SDDS_FLOAT:
481 if ((float_diff = fabsf(*(float *)data1) - fabsf(*(float *)data2)) > 0)
482 return (1);
483 else if (float_diff < 0)
484 return (-1);
485 return (0);
486 case SDDS_LONG64:
487 if ((long64_diff = llabs(*(int64_t *)data1) - llabs(*(int64_t *)data2)) > 0)
488 return (1);
489 else if (long64_diff < 0)
490 return (-1);
491 return (0);
492 case SDDS_LONG:
493 if ((long_diff = labs(*(int32_t *)data1) - labs(*(int32_t *)data2)) > 0)
494 return (1);
495 else if (long_diff < 0)
496 return (-1);
497 return (0);
498 case SDDS_SHORT:
499 if ((short_diff = abs(*(short *)data1) - abs(*(short *)data2)) > 0)
500 return (1);
501 else if (short_diff < 0)
502 return (-1);
503 return (0);
504 case SDDS_ULONG64:
505 if (*(uint64_t *)data1 > *(uint64_t *)data2)
506 return (1);
507 if (*(uint64_t *)data1 < *(uint64_t *)data2)
508 return (-1);
509 return (0);
510 case SDDS_ULONG:
511 if (*(uint32_t *)data1 > *(uint32_t *)data2)
512 return (1);
513 if (*(uint32_t *)data1 < *(uint32_t *)data2)
514 return (-1);
515 return (0);
516 case SDDS_USHORT:
517 if (*(unsigned short *)data1 > *(unsigned short *)data2)
518 return (1);
519 if (*(unsigned short *)data1 < *(unsigned short *)data2)
520 return (-1);
521 return (0);
522 case SDDS_CHARACTER:
523 if ((char_diff = *(char *)data1 - *(char *)data2) > 0)
524 return (1);
525 else if (char_diff < 0)
526 return (-1);
527 return (0);
528 case SDDS_STRING:
529 if (numericHigh)
530 return (strcmp_nh(*(char **)data1, *(char **)data2));
531 else
532 return (strcmp(*(char **)data1, *(char **)data2));
533 default:
534 SDDS_SetError("Problem doing data comparison--invalid data type (SDDS_CompareData)");
535 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
536 exit(EXIT_FAILURE);
537 }
538 }
539}
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
Definition SDDStypes.h:67
#define SDDS_FLOAT
Identifier for the float data type.
Definition SDDStypes.h:43
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ULONG64
Identifier for the unsigned 64-bit integer data type.
Definition SDDStypes.h:55
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_CHARACTER
Identifier for the character data type.
Definition SDDStypes.h:91
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
Definition SDDStypes.h:79
#define SDDS_LONGDOUBLE
Identifier for the long double data type.
Definition SDDStypes.h:31
int strcmp_nh(const char *s1, const char *s2)
Compare two strings with a custom non-hierarchical ranking.
Definition wild_match.c:583

◆ SDDS_ComparePages()

int SDDS_ComparePages ( const void * vpage1,
const void * vpage2 )

Definition at line 778 of file sddssort.c.

778 {
779 /* I'm assuming that a double is large enough to store any of the data types,
780 * including a pointer
781 */
782 static int32_t page1, page2;
783 long i;
784 int comparison;
785
786 page1 = *(int32_t *)vpage1;
787 page2 = *(int32_t *)vpage2;
788
789 for (i = 0; i < sort_parameters; i++) {
790 if ((comparison = SDDS_CompareData(SDDS_sortpage, sort_parameter[i].type, sort_parameter[i].absolute,
791 (void *)&(sort_parameter[i].data[page1]), (void *)&(sort_parameter[i].data[page2])))) {
792 /* if (sort_parameter[i].type==SDDS_STRING) {
793 * free(*((char**)&(sort_parameter[i].data[page1])));
794 * free(*((char**)&(sort_parameter[i].data[page2])));
795 * } */
796 return (sort_parameter[i].decreasing_order ? -comparison : comparison);
797 }
798 /* if (sort_parameter[i].type==SDDS_STRING) {
799 * free(*((char**)&(sort_parameter[i].data[page1])));
800 * free(*((char**)&(sort_parameter[i].data[page2])));
801 * } */
802 }
803 return (0);
804}

◆ SDDS_CompareRows()

int SDDS_CompareRows ( const void * vrow1,
const void * vrow2 )

Definition at line 541 of file sddssort.c.

541 {
542 /* I'm assuming that a double is large enough to store any of the data types,
543 * including a pointer
544 */
545 static double data1, data2;
546 static int64_t row1, row2;
547 long i;
548 int comparison;
549 void *p1, *p2;
550 row1 = *(int64_t *)vrow1;
551 row2 = *(int64_t *)vrow2;
552
553 for (i = 0; i < sort_requests; i++) {
554 if (!SDDS_GetValueByAbsIndex(SDDS_sort, sort_request[i].index, row1, &data1) ||
555 !SDDS_GetValueByAbsIndex(SDDS_sort, sort_request[i].index, row2, &data2)) {
556 SDDS_SetError("Problem getting value for sort (SDDS_CompareRows)");
557 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
558 exit(EXIT_FAILURE);
559 }
560 if ((comparison = SDDS_CompareData(SDDS_sort, sort_request[i].type, sort_request[i].absolute,
561 (void *)&data1, (void *)&data2))) {
562 if (sort_request[i].type == SDDS_STRING) {
563 p1 = &data1;
564 p2 = &data2;
565 free(*((char **)p1));
566 free(*((char **)p2));
567 // free(*((char**)&data1));
568 // free(*((char**)&data2));
569 }
570 return (sort_request[i].decreasing_order ? -comparison : comparison);
571 }
572 if (sort_request[i].type == SDDS_STRING) {
573 p1 = &data1;
574 p2 = &data2;
575 free(*((char **)p1));
576 free(*((char **)p2));
577 // free(*((char**)&data1));
578 // free(*((char**)&data2));
579 }
580 }
581 return (0);
582}
void * SDDS_GetValueByAbsIndex(SDDS_DATASET *SDDS_dataset, int32_t column_index, int64_t row_index, void *memory)
Retrieves the value from a specified column and absolute row index, optionally storing it in provided...

◆ SDDS_SortAll()

long SDDS_SortAll ( SDDS_DATASET * SDDS_input,
SDDS_DATASET * SDDS_output,
SORT_REQUEST * xsort_request,
long xsort_requests,
SORT_REQUEST * xsort_parameter,
long xsort_parameters,
long uniqueRows,
long provideIdenticalCount,
long pipeFlags,
long non_dominate_sort )

Definition at line 806 of file sddssort.c.

808 {
809 long i, j, k, pages;
810 int32_t *xsort_page_index;
811 char s[1024];
812 SDDS_DATASET *tmp_datasets;
813
814 tmp_datasets = NULL;
815 SDDS_sortpage = SDDS_inputx;
816 sort_parameter = xsort_parameter;
817 sort_parameters = xsort_parameters;
818 sort_request = xsort_request;
819 sort_requests = xsort_requests;
820 xsort_page_index = NULL;
821 pages = i = j = k = 0;
822 for (i = 0; i < sort_parameters; i++) {
823 if ((sort_parameter[i].index = SDDS_GetParameterIndex(SDDS_sortpage, sort_parameter[i].name)) < 0) {
824 sprintf(s, "Unable to get parameter value--parameter name \"%s\" is not recognized(SDDS_GetParameterIndex)", sort_parameter[i].name);
825 SDDS_SetError(s);
826 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
827 return (0);
828 }
829 sort_parameter[i].type = SDDS_GetParameterType(SDDS_sortpage, sort_parameter[i].index);
830 }
831 if (sort_parameters) {
832 if (xpipeFlags == 0 && !SDDS_sortpage->layout.gzipFile)
834 for (i = 0; i < sort_parameters; i++)
835 sort_parameter[i].data = NULL;
836 while (SDDS_ReadPage(SDDS_sortpage) > 0) {
837 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
838 /* copy each page of sortpage into tmp_datasets indexed by the pages, i.e.
839 * tmp_datasets[pages] contains only one page */
840 tmp_datasets = realloc(tmp_datasets, sizeof(*tmp_datasets) * (pages + 1));
841 if (!SDDS_InitializeCopy(&tmp_datasets[pages], SDDS_sortpage, NULL, "m")) {
842 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
843 return (0);
844 }
845 if (!SDDS_CopyPage(&tmp_datasets[pages], SDDS_sortpage)) {
846 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
847 return (0);
848 }
849 }
850 for (i = 0; i < sort_parameters; i++) {
851 sort_parameter[i].data = realloc(sort_parameter[i].data, sizeof(*sort_parameter[i].data) * (pages + 1));
852
853 if (!SDDS_GetParameterByIndex(SDDS_sortpage, sort_parameter[i].index, &(sort_parameter[i].data[pages]))) {
854 SDDS_SetError("Problem getting parameter value for sort (SDDS_SortAll)");
855 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
856 exit(EXIT_FAILURE);
857 }
858 }
859 pages++;
860 }
861 /* sort pages by parameter */
862 xsort_page_index = tmalloc(sizeof(*xsort_page_index) * pages);
863 for (k = 0; k < pages; k++)
864 xsort_page_index[k] = k;
865 if (pages > 1)
866 qsort((void *)xsort_page_index, pages, sizeof(*xsort_page_index), SDDS_ComparePages);
867
868 /* sort_page_index=xsort_page_index; */
869 for (i = 0; i < pages; i++) {
870 j = xsort_page_index[i];
871 if (xpipeFlags || SDDS_sortpage->layout.gzipFile) {
872 if (!SDDS_CopyPage(SDDS_outputx, &tmp_datasets[j])) {
873 SDDS_SetError("Problem copying data from memory");
874 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
875 exit(EXIT_FAILURE);
876 }
877 if (!SDDS_Terminate(&tmp_datasets[j])) {
878 SDDS_SetError("Problem terminate datasets");
879 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
880 exit(EXIT_FAILURE);
881 }
882 } else {
883 if (!SDDS_GotoPage(SDDS_sortpage, j + 1)) {
884 SDDS_SetError("Problem goto page");
885 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
886 exit(EXIT_FAILURE);
887 }
888 if (SDDS_ReadPage(SDDS_sortpage) < 1) {
889 SDDS_SetError("Problem read page");
890 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
891 exit(EXIT_FAILURE);
892 }
893 if (!SDDS_CopyPage(SDDS_outputx, SDDS_sortpage)) {
894 SDDS_SetError("Problem copying data");
895 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
896 exit(EXIT_FAILURE);
897 }
898 }
899 if (sort_requests) {
900 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
901 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
902 SDDS_SetError("Problem performing sort");
903 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
904 exit(EXIT_FAILURE);
905 }
906 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
907 SDDS_SetError("Problem marking duplicate rows.");
908 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
909 exit(EXIT_FAILURE);
910 }
911 }
912 }
913 if (!SDDS_WritePage(SDDS_outputx)) {
914 SDDS_SetError("Problem writing data to output file");
915 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
916 exit(EXIT_FAILURE);
917 }
918 }
919 } else {
920 while (SDDS_ReadPage(SDDS_inputx) > 0) {
921 if (!SDDS_CopyPage(SDDS_outputx, SDDS_inputx)) {
922 SDDS_SetError("Problem copying data for output file");
923 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
924 exit(EXIT_FAILURE);
925 }
926 if (SDDS_CountRowsOfInterest(SDDS_outputx) > 0) {
927 if (!SDDS_SortRows(SDDS_outputx, sort_request, sort_requests, non_dominate_sort)) {
928 SDDS_SetError("Problem performing sort");
929 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
930 exit(EXIT_FAILURE);
931 }
932 if (uniqueRows && !SDDS_UnsetDuplicateRows(SDDS_outputx, sort_request, sort_requests, provideIdenticalCount)) {
933 SDDS_SetError("Problem marking duplicate rows.");
934 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
935 exit(EXIT_FAILURE);
936 }
937 }
938 if (!SDDS_WritePage(SDDS_outputx)) {
939 SDDS_SetError("Problem writing data to output file");
940 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
941 exit(EXIT_FAILURE);
942 }
943 }
944 }
945 if (tmp_datasets)
946 free(tmp_datasets);
947 if (xsort_page_index)
948 free(xsort_page_index);
949 return 1;
950}
int32_t SDDS_SetDefaultIOBufferSize(int32_t newValue)
Definition SDDS_binary.c:66
void * SDDS_GetParameterByIndex(SDDS_DATASET *SDDS_dataset, int32_t index, void *memory)
Retrieves the value of a specified parameter by its index from the current data table of a data set.
int32_t SDDS_GotoPage(SDDS_DATASET *SDDS_dataset, int32_t page_number)
Sets the current page of the SDDS dataset to the specified page number.
int32_t SDDS_GetParameterType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a parameter in the SDDS dataset by its index.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ SDDS_SortRows()

long SDDS_SortRows ( SDDS_DATASET * SDDS_dataset,
SORT_REQUEST * xsort_request,
long xsort_requests,
long non_dominate_sort )

Definition at line 609 of file sddssort.c.

609 {
610 int64_t i, j, k, rows;
611 int64_t *row_location;
612 char s[1024];
613 double **data = NULL, *dist = NULL, *const_violation = NULL;
614 int32_t *rank = NULL;
615 population pop;
616 long *maximize = NULL;
617
618 SDDS_sort = SDDS_dataset;
619 sort_request = xsort_request;
620 sort_requests = xsort_requests;
621 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
622 return (0);
623
624 for (i = 0; i < sort_requests; i++) {
625 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
626 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
627 SDDS_SetError(s);
628 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
629 return (0);
630 }
631 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
632 }
633 if (non_dominate_sort) {
634 data = (double **)malloc(sizeof(*data) * sort_requests);
635 maximize = (long *)malloc(sizeof(*maximize) * sort_requests);
636 for (i = 0; i < sort_requests; i++) {
637 if (sort_request[i].type == SDDS_STRING) {
638 fprintf(stderr, "Non-dominated sort is not available for string column.\n");
639 exit(EXIT_FAILURE);
640 }
641 if (!(data[i] = (double *)SDDS_GetColumnInDoubles(SDDS_sort, sort_request[i].name))) {
642 SDDS_SetError("Problem performing sort");
643 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
644 exit(EXIT_FAILURE);
645 }
646 maximize[i] = sort_request[i].maximize_order;
647 }
648 const_violation = read_constr_violation(SDDS_sort);
649 fill_population(&pop, rows, sort_requests, data, maximize, const_violation);
650 sort_row_index = non_dominated_sort(&pop);
651 rank = (int32_t *)malloc(sizeof(*rank) * rows);
652 dist = (double *)malloc(sizeof(*dist) * rows);
653 if (!const_violation)
654 const_violation = calloc(rows, sizeof(*const_violation));
655 for (i = 0; i < rows; i++) {
656 rank[i] = pop.ind[sort_row_index[i]].rank;
657 dist[i] = pop.ind[sort_row_index[i]].crowd_dist;
658 const_violation[i] = pop.ind[sort_row_index[i]].constr_violation;
659 }
660 free_pop_mem(&pop);
661 for (i = 0; i < sort_requests; i++)
662 free(data[i]);
663 free(data);
664 free(maximize);
665 } else {
666 sort_row_index = tmalloc(sizeof(*sort_row_index) * rows);
667 for (i = 0; i < rows; i++)
668 sort_row_index[i] = i;
669 /* After this sort, sort_row_index will contain the indices of the rows
670 * in sorted order
671 */
672 qsort((void *)sort_row_index, rows, sizeof(*sort_row_index), SDDS_CompareRows);
673
674 /* create an array to give the location in the sort_row_index array of
675 * a particular row
676 */
677#if defined(DEBUG)
678 fprintf(stderr, "new row order:\n");
679 for (i = 0; i < rows; i++)
680 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", i, sort_row_index[i]);
681 fprintf(stderr, "\n");
682#endif
683 }
684 row_location = tmalloc(sizeof(*sort_row_index) * rows);
685 for (i = 0; i < rows; i++)
686 row_location[sort_row_index[i]] = i;
687 for (i = 0; i < rows; i++) {
688 if ((j = sort_row_index[i]) != i) {
689 /* move this row from position i to position j, where it belongs */
690 if (!SDDS_SwapRows(SDDS_sort, i, j)) {
691 SDDS_SetError("Problem swapping rows after index sort (SDDS_SortRows");
692 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
693 exit(EXIT_FAILURE);
694 }
695 /* adjust the indices to reflect the swap */
696 sort_row_index[i] = i;
697 k = row_location[i];
698 row_location[i] = i;
699 sort_row_index[k] = j;
700 row_location[j] = k;
701 }
702#if defined(DEBUG)
703 fprintf(stderr, "new row order:\n");
704 for (j = 0; j < rows; j++)
705 fprintf(stderr, "%" PRId64 " %" PRId64 "\n", j, sort_row_index[j]);
706 fprintf(stderr, "\n");
707#endif
708 }
709 if (non_dominate_sort) {
710 if (SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, rank, rows, "Rank", NULL) != 1 ||
711 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, dist, rows, "CrowdingDistance", NULL) != 1 ||
712 SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, const_violation, rows, "ConstraintsViolation", NULL) != 1) {
713 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
714 exit(EXIT_FAILURE);
715 }
716 free(rank);
717 free(dist);
718 free(const_violation);
719 }
720 free(sort_row_index);
721 free(row_location);
722 return 1;
723}
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
int64_t * non_dominated_sort(population *new_pop)
Performs non-dominated sorting on a population and assigns ranks and crowding distances.
void fill_population(population *pop, long rows, long columns, double **columnValue, long *maximize, double *const_violation)
Initializes and fills the population structure with individuals and their objective values.
void free_pop_mem(population *pop)
Frees all dynamically allocated memory associated with a population.

◆ SDDS_SwapRows()

long SDDS_SwapRows ( SDDS_DATASET * SDDS_dataset,
int64_t row1,
int64_t row2 )

Definition at line 584 of file sddssort.c.

584 {
585#define SWAP_BUFFER_SIZE 16
586 static char buffer[SWAP_BUFFER_SIZE];
587 void **data;
588 long i, size;
589 data = SDDS_dataset->data;
590#if defined(DEBUG)
591 fprintf(stderr, "swapping row %" PRId64 " with row %" PRId64 "\n", row1, row2);
592#endif
593 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
594 if ((size = SDDS_GetTypeSize(SDDS_dataset->layout.column_definition[i].type)) > SWAP_BUFFER_SIZE) {
595 SDDS_SetError("Unable to swap rows--swap buffer is too small (SDDS_SwapRows)");
596 return (0);
597 }
598#if defined(DEBUG)
599 if (SDDS_dataset->layout.column_definition[i].type == SDDS_STRING)
600 fprintf(stderr, " %s <--> %s\n", *(char **)((char *)(data[i]) + row1 * size), *(char **)((char *)(data[i]) + row2 * size));
601#endif
602 memcpy((char *)buffer, (char *)(data[i]) + row1 * size, size);
603 memcpy((char *)(data[i]) + row1 * size, (char *)(data[i]) + row2 * size, size);
604 memcpy((char *)(data[i]) + row2 * size, (char *)buffer, size);
605 }
606 return (1);
607}
int32_t SDDS_GetTypeSize(int32_t type)
Retrieves the size in bytes of a specified SDDS data type.

◆ SDDS_UnsetDuplicateRows()

long SDDS_UnsetDuplicateRows ( SDDS_DATASET * SDDS_dataset,
SORT_REQUEST * xsort_request,
long xsort_requests,
long provideIdenticalCount )

Definition at line 725 of file sddssort.c.

725 {
726 int64_t rows, i, j;
727 int64_t *identicalCount;
728 int32_t *rowFlag;
729 char s[1024];
730
731 SDDS_sort = SDDS_dataset;
732 sort_request = xsort_request;
733 sort_requests = xsort_requests;
734
735 for (i = 0; i < sort_requests; i++) {
736 if ((sort_request[i].index = SDDS_GetColumnIndex(SDDS_sort, sort_request[i].name)) < 0) {
737 sprintf(s, "column name \"%s\" is not recognized(SDDS_GetColumnIndex)", sort_request[i].name);
738 SDDS_SetError(s);
739 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
740 return 0;
741 }
742 sort_request[i].type = SDDS_GetColumnType(SDDS_sort, sort_request[i].index);
743 }
744
745 if ((rows = SDDS_CountRowsOfInterest(SDDS_sort)) < 0)
746 return (0);
747
748 rowFlag = tmalloc(sizeof(*rowFlag) * rows);
749 identicalCount = tmalloc(sizeof(*identicalCount) * rows);
750 for (i = 0; i < rows; i++)
751 rowFlag[i] = identicalCount[i] = 1;
752
753 for (i = 0; i < rows - 1; i++) {
754 if (!rowFlag[i])
755 continue;
756 for (j = i + 1; j < rows; j++) {
757 if (rowFlag[j]) {
758 if (SDDS_CompareRows(&i, &j) == 0) {
759 identicalCount[i] += 1;
760 rowFlag[j] = 0;
761 } else
762 break;
763 }
764 }
765 }
766 if (!SDDS_AssertRowFlags(SDDS_sort, SDDS_FLAG_ARRAY, rowFlag, rows))
767 return 0;
768 if (provideIdenticalCount && !SDDS_SetColumn(SDDS_sort, SDDS_SET_BY_NAME, identicalCount, rows, "IdenticalCount"))
769 return 0;
770 free(rowFlag);
771 return 1;
772}
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.