SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sortfunctions.c File Reference

Detailed Description

Useful routines for sorting, compatible with qsort()

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 sortfunctions.c.

#include "mdb.h"
#include "mdb_thread.h"
#include "SDDStypes.h"

Go to the source code of this file.

Functions

int double_cmpasc (const void *a, const void *b)
 Compare two doubles in ascending order.
 
int double_abs_cmpasc (const void *a, const void *b)
 Compare the absolute values of two doubles in ascending order.
 
int double_cmpdes (const void *a, const void *b)
 Compare two doubles in descending order.
 
int double_abs_cmpdes (const void *a, const void *b)
 Compare the absolute values of two doubles in descending order.
 
void double_copy (void *a, void *b)
 
int float_cmpasc (const void *a, const void *b)
 
int float_abs_cmpasc (const void *a, const void *b)
 
int float_cmpdes (const void *a, const void *b)
 
int float_abs_cmpdes (const void *a, const void *b)
 
void float_copy (void *a, void *b)
 
int long_cmpasc (const void *a, const void *b)
 Compare two long integers in ascending order.
 
int long_abs_cmpasc (const void *a, const void *b)
 Compare the absolute values of two long integers in ascending order.
 
int long_cmpdes (const void *a, const void *b)
 
int long_abs_cmpdes (const void *a, const void *b)
 
void long_copy (void *a, void *b)
 
int string_cmpasc (const void *a, const void *b)
 Compare two strings in ascending order.
 
int string_cmpdes (const void *a, const void *b)
 
void string_copy (void *a, void *b)
 Copy a string value.
 
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.
 
void set_up_row_sort (int sort_by_column, size_t n_columns, size_t element_size, int(*compare)(const void *a, const void *b))
 Set up parameters for row-based sorting.
 
int row_compare (const void *av, const void *bv)
 Compare two rows based on the previously set sorting parameters.
 
void row_copy (void *av, void *bv)
 
int CompareStringKeyedIndex (const void *ki1, const void *ki2)
 Compare two KEYED_INDEX structures based on string keys.
 
int CompareDoubleKeyedIndex (const void *ki1, const void *ki2)
 Compare two KEYED_INDEX structures based on double keys.
 
int CompareStringKeyedGroup (const void *kg1, const void *kg2)
 Compare two KEYED_EQUIVALENT groups based on string keys.
 
int CompareDoubleKeyedGroup (const void *kg1, const void *kg2)
 Compare two KEYED_EQUIVALENT groups based on double keys.
 
KEYED_EQUIVALENT ** MakeSortedKeyGroups (long *keyGroups, long keyType, void *data, long points)
 Create sorted key groups from data.
 
long FindMatchingKeyGroup (KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
 Find a matching key group for a search key.
 
long * sort_and_return_index (void *data, long type, long rows, long increaseOrder)
 Sort data and return the sorted index.
 
int strcmp_skip (const char *s1, const char *s2, const char *skip)
 Compare two strings while skipping specified characters.
 

Function Documentation

◆ CompareDoubleKeyedGroup()

int CompareDoubleKeyedGroup ( const void * kg1,
const void * kg2 )

Compare two KEYED_EQUIVALENT groups based on double keys.

This function compares the first double key of two KEYED_EQUIVALENT groups.

Parameters
kg1Pointer to the first KEYED_EQUIVALENT group.
kg2Pointer to the second KEYED_EQUIVALENT group.
Returns
int Returns -1 if kg1 < kg2, 1 if kg1 > kg2, or 0 if equal.

Definition at line 347 of file sortfunctions.c.

347 {
348 double diff;
349 if ((diff = (*(KEYED_EQUIVALENT *)kg1).equivalent[0]->doubleKey - (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->doubleKey)) {
350 if (diff < 0)
351 return -1;
352 return 1;
353 }
354 return 0;
355}

◆ CompareDoubleKeyedIndex()

int CompareDoubleKeyedIndex ( const void * ki1,
const void * ki2 )

Compare two KEYED_INDEX structures based on double keys.

This function compares two KEYED_INDEX structures using their doubleKey fields. If the double keys are identical and orderIndices is set, it compares based on rowIndex.

Parameters
ki1Pointer to the first KEYED_INDEX.
ki2Pointer to the second KEYED_INDEX.
Returns
int Returns -1 if ki1 < ki2, 1 if ki1 > ki2, or based on rowIndex if keys are equal.

Definition at line 313 of file sortfunctions.c.

313 {
314 double diff;
315 if ((diff = (*(const KEYED_INDEX *)ki1).doubleKey - (*(const KEYED_INDEX *)ki2).doubleKey)) {
316 if (diff < 0)
317 return -1;
318 return 1;
319 }
320 if (orderIndices)
321 return (*(const KEYED_INDEX *)ki1).rowIndex - (*(const KEYED_INDEX *)ki2).rowIndex;
322 return 0;
323}

◆ CompareStringKeyedGroup()

int CompareStringKeyedGroup ( const void * kg1,
const void * kg2 )

Compare two KEYED_EQUIVALENT groups based on string keys.

This function compares the first string key of two KEYED_EQUIVALENT groups.

Parameters
kg1Pointer to the first KEYED_EQUIVALENT group.
kg2Pointer to the second KEYED_EQUIVALENT group.
Returns
int Returns the result of strcmp on the first string keys.

Definition at line 334 of file sortfunctions.c.

334 {
335 return strcmp((*(KEYED_EQUIVALENT *)kg1).equivalent[0]->stringKey, (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->stringKey);
336}

◆ CompareStringKeyedIndex()

int CompareStringKeyedIndex ( const void * ki1,
const void * ki2 )

Compare two KEYED_INDEX structures based on string keys.

This function compares two KEYED_INDEX structures using their stringKey fields. If the string keys are identical and orderIndices is set, it compares based on rowIndex.

Parameters
ki1Pointer to the first KEYED_INDEX.
ki2Pointer to the second KEYED_INDEX.
Returns
int Returns a negative value if ki1 < ki2, positive if ki1 > ki2, or based on rowIndex if keys are equal.

Definition at line 294 of file sortfunctions.c.

294 {
295 int value;
296 if ((value = strcmp((*(const KEYED_INDEX *)ki1).stringKey, (*(const KEYED_INDEX *)ki2).stringKey)))
297 return value;
298 if (orderIndices)
299 return (*(const KEYED_INDEX *)ki1).rowIndex - (*(const KEYED_INDEX *)ki2).rowIndex;
300 return value;
301}

◆ double_abs_cmpasc()

int double_abs_cmpasc ( const void * a,
const void * b )

Compare the absolute values of two doubles in ascending order.

This function compares the absolute values of two double values pointed to by a and b.

Parameters
aPointer to the first double.
bPointer to the second double.
Returns
int Returns -1 if |*a| < |*b|, 1 if |*a| > |*b|, and 0 if equal.

Definition at line 44 of file sortfunctions.c.

44 {
45 double diff;
46
47 diff = fabs(*((double *)b)) - fabs(*((double *)a));
48 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
49}

◆ double_abs_cmpdes()

int double_abs_cmpdes ( const void * a,
const void * b )

Compare the absolute values of two doubles in descending order.

This function compares the absolute values of two double values pointed to by a and b in descending order.

Parameters
aPointer to the first double.
bPointer to the second double.
Returns
int Returns 1 if |*a| < |*b|, -1 if |*a| > |*b|, and 0 if equal.

Definition at line 76 of file sortfunctions.c.

76 {
77 double diff;
78
79 diff = fabs(*((double *)b)) - fabs(*((double *)a));
80 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
81}

◆ double_cmpasc()

int double_cmpasc ( const void * a,
const void * b )

Compare two doubles in ascending order.

This function compares two double values pointed to by a and b.

Parameters
aPointer to the first double.
bPointer to the second double.
Returns
int Returns -1 if *a < *b, 1 if *a > *b, and 0 if equal.

Definition at line 28 of file sortfunctions.c.

28 {
29 double diff;
30
31 diff = *((double *)b) - *((double *)a);
32 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
33}

◆ double_cmpdes()

int double_cmpdes ( const void * a,
const void * b )

Compare two doubles in descending order.

This function compares two double values pointed to by a and b in descending order.

Parameters
aPointer to the first double.
bPointer to the second double.
Returns
int Returns 1 if *a < *b, -1 if *a > *b, and 0 if equal.

Definition at line 60 of file sortfunctions.c.

60 {
61 double diff;
62
63 diff = *((double *)b) - *((double *)a);
64 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
65}

◆ double_copy()

void double_copy ( void * a,
void * b )

Definition at line 83 of file sortfunctions.c.

83 {
84
85 *((double *)a) = *((double *)b);
86}

◆ FindMatchingKeyGroup()

long FindMatchingKeyGroup ( KEYED_EQUIVALENT ** keyGroup,
long keyGroups,
long keyType,
void * searchKeyData,
long reuse )

Find a matching key group for a search key.

This function searches for a key group that matches the provided search key.

Parameters
keyGroupArray of key groups.
keyGroupsNumber of key groups.
keyTypeThe type of key (e.g., SDDS_STRING or SDDS_DOUBLE).
searchKeyDataPointer to the search key data.
reuseFlag indicating whether to allow reuse of key groups.
Returns
long Returns the row index of the matching key group or -1 if not found.

Definition at line 450 of file sortfunctions.c.

451 {
452 KEYED_EQUIVALENT searchKey;
453 KEYED_INDEX keyedIndex;
454 KEYED_INDEX *equivalent[1];
455 long rowIndex, i;
456
457 equivalent[0] = &keyedIndex;
458 searchKey.equivalent = equivalent;
459 searchKey.equivalents = 1;
460 searchKey.nextIndex = 0;
461 if (keyType == SDDS_STRING) {
462 keyedIndex.stringKey = *(char **)searchKeyData;
463 mdb_thread_lock(&keyed_group_lock);
464 i = binaryIndexSearch((void **)keyGroup, keyGroups, (void *)&searchKey, CompareStringKeyedGroup, 0);
465 } else {
466 keyedIndex.doubleKey = *(double *)searchKeyData;
467 mdb_thread_lock(&keyed_group_lock);
468 i = binaryIndexSearch((void **)keyGroup, keyGroups, (void *)&searchKey, CompareDoubleKeyedGroup, 0);
469 }
470 if (i < 0 || keyGroup[i]->nextIndex >= keyGroup[i]->equivalents) {
471 mdb_thread_unlock(&keyed_group_lock);
472 return -1;
473 }
474 rowIndex = keyGroup[i]->equivalent[keyGroup[i]->nextIndex]->rowIndex;
475 if (!reuse)
476 keyGroup[i]->nextIndex += 1;
477 mdb_thread_unlock(&keyed_group_lock);
478 return rowIndex;
479}
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
long binaryIndexSearch(void **array, long members, void *key, int(*compare)(const void *c1, const void *c2), long bracket)
Searches for a key in a sorted array of pointers using binary search.
Definition binsert.c:98
int CompareDoubleKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on double keys.
int CompareStringKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on string keys.

◆ float_abs_cmpasc()

int float_abs_cmpasc ( const void * a,
const void * b )

Definition at line 95 of file sortfunctions.c.

95 {
96 float diff;
97
98 diff = fabsf(*((float *)b)) - fabsf(*((float *)a));
99 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
100}

◆ float_abs_cmpdes()

int float_abs_cmpdes ( const void * a,
const void * b )

Definition at line 109 of file sortfunctions.c.

109 {
110 float diff;
111
112 diff = fabsf(*((float *)b)) - fabsf(*((float *)a));
113 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
114}

◆ float_cmpasc()

int float_cmpasc ( const void * a,
const void * b )

Definition at line 88 of file sortfunctions.c.

88 {
89 float diff;
90
91 diff = *((float *)b) - *((float *)a);
92 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
93}

◆ float_cmpdes()

int float_cmpdes ( const void * a,
const void * b )

Definition at line 102 of file sortfunctions.c.

102 {
103 float diff;
104
105 diff = *((float *)b) - *((float *)a);
106 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
107}

◆ float_copy()

void float_copy ( void * a,
void * b )

Definition at line 116 of file sortfunctions.c.

116 {
117 *((float *)a) = *((float *)b);
118}

◆ long_abs_cmpasc()

int long_abs_cmpasc ( const void * a,
const void * b )

Compare the absolute values of two long integers in ascending order.

This function compares the absolute values of two int32_t values pointed to by a and b.

Parameters
aPointer to the first long integer.
bPointer to the second long integer.
Returns
int Returns -1 if |*a| < |*b|, 1 if |*a| > |*b|, and 0 if equal.

Definition at line 144 of file sortfunctions.c.

144 {
145 int32_t diff;
146 diff = labs(*((int32_t *)b)) - labs(*((int32_t *)a));
147 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
148}

◆ long_abs_cmpdes()

int long_abs_cmpdes ( const void * a,
const void * b )

Definition at line 156 of file sortfunctions.c.

156 {
157 long diff;
158 diff = labs(*((long *)a)) - labs(*((long *)b));
159 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
160}

◆ long_cmpasc()

int long_cmpasc ( const void * a,
const void * b )

Compare two long integers in ascending order.

This function compares two int32_t values pointed to by a and b.

Parameters
aPointer to the first long integer.
bPointer to the second long integer.
Returns
int Returns -1 if *a < *b, 1 if *a > *b, and 0 if equal.

Definition at line 129 of file sortfunctions.c.

129 {
130 int32_t diff;
131 diff = *((int32_t *)b) - *((int32_t *)a);
132 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
133}

◆ long_cmpdes()

int long_cmpdes ( const void * a,
const void * b )

Definition at line 150 of file sortfunctions.c.

150 {
151 long diff;
152 diff = *((long *)a) - *((long *)b);
153 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
154}

◆ long_copy()

void long_copy ( void * a,
void * b )

Definition at line 162 of file sortfunctions.c.

162 {
163 *((long *)a) = *((long *)b);
164}

◆ MakeSortedKeyGroups()

KEYED_EQUIVALENT ** MakeSortedKeyGroups ( long * keyGroups,
long keyType,
void * data,
long points )

Create sorted key groups from data.

This function generates sorted groups of keys from the provided data based on the specified key type.

Parameters
keyGroupsPointer to store the number of key groups created.
keyTypeThe type of key (e.g., SDDS_STRING or SDDS_DOUBLE).
dataPointer to the data to be grouped.
pointsNumber of data points.
Returns
KEYED_EQUIVALENT** Returns an array of pointers to KEYED_EQUIVALENT structures.

Definition at line 368 of file sortfunctions.c.

368 {
369 KEYED_EQUIVALENT **keyedEquiv = NULL;
370 static MDB_THREAD_LOCAL KEYED_INDEX *keyedIndex = NULL;
371 long iEquiv, i2, j;
372 long i1;
373
374 if (!points)
375 return 0;
376 if (keyedIndex)
377 free(keyedIndex);
378 if (!(keyedIndex = (KEYED_INDEX *)malloc(sizeof(*keyedIndex) * points)) ||
379 !(keyedEquiv = (KEYED_EQUIVALENT **)malloc(sizeof(*keyedEquiv) * points))) {
380 fprintf(stderr, "memory allocation failure");
381 exit(1);
382 }
383 if (keyType == SDDS_STRING) {
384 char **string;
385 string = data;
386 for (i1 = 0; i1 < points; i1++) {
387 keyedIndex[i1].stringKey = string[i1];
388 keyedIndex[i1].rowIndex = i1;
389 }
390 orderIndices = 1; /* subsort by source row index */
391 qsort((void *)keyedIndex, points, sizeof(*keyedIndex), CompareStringKeyedIndex);
392 orderIndices = 0; /* ignore index in comparisons */
393 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
394 for (i2 = i1 + 1; i2 < points; i2++) {
395 if (CompareStringKeyedIndex(keyedIndex + i1, keyedIndex + i2))
396 break;
397 }
398 if (!(keyedEquiv[iEquiv] = (KEYED_EQUIVALENT *)malloc(sizeof(KEYED_EQUIVALENT))) ||
399 !(keyedEquiv[iEquiv]->equivalent = (KEYED_INDEX **)malloc(sizeof(KEYED_INDEX *) * (i2 - i1)))) {
400 fprintf(stderr, "memory allocation failure");
401 exit(1);
402 }
403 keyedEquiv[iEquiv]->equivalents = i2 - i1;
404 keyedEquiv[iEquiv]->nextIndex = 0;
405 for (j = 0; i1 < i2; i1++, j++)
406 keyedEquiv[iEquiv]->equivalent[j] = keyedIndex + i1;
407 }
408 } else {
409 double *value;
410 value = data;
411 for (i1 = 0; i1 < points; i1++) {
412 keyedIndex[i1].doubleKey = value[i1];
413 keyedIndex[i1].rowIndex = i1;
414 }
415 orderIndices = 1; /* subsort by source row index */
416 qsort((void *)keyedIndex, points, sizeof(*keyedIndex), CompareDoubleKeyedIndex);
417 orderIndices = 0; /* ignore index in comparisons */
418 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
419 for (i2 = i1 + 1; i2 < points; i2++) {
420 if (CompareDoubleKeyedIndex(keyedIndex + i1, keyedIndex + i2))
421 break;
422 }
423 if (!(keyedEquiv[iEquiv] = (KEYED_EQUIVALENT *)malloc(sizeof(KEYED_EQUIVALENT))) ||
424 !(keyedEquiv[iEquiv]->equivalent = (KEYED_INDEX **)malloc(sizeof(KEYED_INDEX *) * (i2 - i1)))) {
425 fprintf(stderr, "memory allocation failure");
426 exit(1);
427 }
428 keyedEquiv[iEquiv]->equivalents = i2 - i1;
429 keyedEquiv[iEquiv]->nextIndex = 0;
430 for (j = 0; i1 < i2; i1++, j++)
431 keyedEquiv[iEquiv]->equivalent[j] = keyedIndex + i1;
432 }
433 }
434 *keyGroups = iEquiv;
435 return keyedEquiv;
436}
int CompareDoubleKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on double keys.
int CompareStringKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on string keys.

◆ row_compare()

int row_compare ( const void * av,
const void * bv )

Compare two rows based on the previously set sorting parameters.

This static function is used internally to compare two rows during sorting.

Parameters
avPointer to the first row.
bvPointer to the second row.
Returns
int Result of the comparison.

Definition at line 263 of file sortfunctions.c.

263 {
264 char **a, **b;
265 a = (char **)av;
266 b = (char **)bv;
267 return ((*item_compare)(*a + size_of_element * column_to_compare,
268 *b + size_of_element * column_to_compare));
269}

◆ row_copy()

void row_copy ( void * av,
void * bv )

Definition at line 271 of file sortfunctions.c.

271 {
272 void **a, **b;
273 void *ptr;
274 a = (void **)av;
275 b = (void **)bv;
276 ptr = *a;
277 *a = *b;
278 *b = ptr;
279}

◆ set_up_row_sort()

void set_up_row_sort ( int sort_by_column,
size_t n_columns,
size_t element_size,
int(* compare )(const void *a, const void *b) )

Set up parameters for row-based sorting.

This function initializes the sorting parameters for sorting 2D data by rows based on a specified column.

Parameters
sort_by_columnThe column index to sort by.
n_columnsTotal number of columns.
element_sizeSize of each element in a row.
compareFunction pointer to the comparison function.

Definition at line 242 of file sortfunctions.c.

246 {
247 if ((column_to_compare = sort_by_column) >= (number_of_columns = n_columns))
248 bomb("column out of range in set_up_row_sort()", NULL);
249 size_of_element = element_size;
250 if (!(item_compare = compare))
251 bomb("null function pointer in set_up_row_sort()", NULL);
252}
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26

◆ sort_and_return_index()

long * sort_and_return_index ( void * data,
long type,
long rows,
long increaseOrder )

Sort data and return the sorted index.

This function sorts the provided data based on the specified type and order, and returns an array of indices representing the sorted order.

Parameters
dataPointer to the data to be sorted.
typeThe data type (e.g., SDDS_STRING, SDDS_DOUBLE).
rowsNumber of rows in the data.
increaseOrderIf non-zero, sort in increasing order; otherwise, sort in decreasing order.
Returns
long* Returns an array of indices representing the sorted order, or NULL on failure.

Definition at line 492 of file sortfunctions.c.

492 {
493 long *index = NULL;
494 long i, keyGroups, i1, j, istart, jstart, i2, j2;
495 KEYED_EQUIVALENT **keyGroup;
496 char **tmpstring = NULL;
497 double *tmpdata = NULL;
498
499 if (!rows || !data)
500 return 0;
501 index = (long *)malloc(sizeof(*index) * rows);
502 switch (type) {
503 case SDDS_STRING:
504 tmpstring = (char **)data;
505 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_STRING, tmpstring, rows);
506 break;
507 default:
508 if (type == SDDS_DOUBLE)
509 tmpdata = (double *)data;
510 else {
511 tmpdata = calloc(sizeof(*tmpdata), rows);
512 for (i = 0; i < rows; i++) {
513 switch (type) {
514 case SDDS_SHORT:
515 tmpdata[i] = *((short *)data + i);
516 break;
517 case SDDS_USHORT:
518 tmpdata[i] = *((unsigned short *)data + i);
519 break;
520 case SDDS_LONG:
521 tmpdata[i] = *((int32_t *)data + i);
522 break;
523 case SDDS_ULONG:
524 tmpdata[i] = *((uint32_t *)data + i);
525 break;
526 case SDDS_CHARACTER:
527 tmpdata[i] = *((unsigned char *)data + i);
528 break;
529 case SDDS_FLOAT:
530 tmpdata[i] = *((float *)data + i);
531 break;
532 default:
533 fprintf(stderr, "Invalid data type given!\n");
534 exit(1);
535 break;
536 }
537 }
538 }
539 keyGroup = MakeSortedKeyGroups(&keyGroups, SDDS_DOUBLE, tmpdata, rows);
540 if (type != SDDS_DOUBLE)
541 free(tmpdata);
542 break;
543 }
544 i1 = 0;
545 if (increaseOrder) {
546 istart = 0;
547 } else {
548 istart = keyGroups - 1;
549 }
550 for (i = istart, i2 = 0; i2 < keyGroups; i2++) {
551 if (increaseOrder) {
552 jstart = 0;
553 } else {
554 jstart = keyGroup[i]->equivalents - 1;
555 }
556 for (j = jstart, j2 = 0; j2 < keyGroup[i]->equivalents; j2++) {
557 switch (type) {
558 case SDDS_STRING:
559 ((char **)data)[i1] = keyGroup[i]->equivalent[j]->stringKey;
560 break;
561 case SDDS_DOUBLE:
562 ((double *)data)[i1] = keyGroup[i]->equivalent[j]->doubleKey;
563 break;
564 case SDDS_FLOAT:
565 ((float *)data)[i1] = (float)keyGroup[i]->equivalent[j]->doubleKey;
566 break;
567 case SDDS_LONG:
568 ((int32_t *)data)[i1] = (int32_t)keyGroup[i]->equivalent[j]->doubleKey;
569 break;
570 case SDDS_ULONG:
571 ((uint32_t *)data)[i1] = (uint32_t)keyGroup[i]->equivalent[j]->doubleKey;
572 break;
573 case SDDS_SHORT:
574 ((short *)data)[i1] = (short)keyGroup[i]->equivalent[j]->doubleKey;
575 break;
576 case SDDS_USHORT:
577 ((unsigned short *)data)[i1] = (unsigned short)keyGroup[i]->equivalent[j]->doubleKey;
578 break;
579 case SDDS_CHARACTER:
580 ((char *)data)[i1] = (unsigned char)keyGroup[i]->equivalent[j]->doubleKey;
581 break;
582 default:
583 fprintf(stderr, "Invalid data type given!\n");
584 exit(1);
585 break;
586 }
587 index[i1] = keyGroup[i]->equivalent[j]->rowIndex;
588 i1++;
589 if (increaseOrder)
590 j++;
591 else
592 j--;
593 }
594 if (increaseOrder)
595 i++;
596 else
597 i--;
598 }
599 for (i = 0; i < keyGroups; i++) {
600 free(keyGroup[i]->equivalent);
601 free(keyGroup[i]);
602 }
603 free(keyGroup);
604 return index;
605}
#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_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#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_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.

◆ strcmp_skip()

int strcmp_skip ( const char * s1,
const char * s2,
const char * skip )

Compare two strings while skipping specified characters.

This function compares two null-terminated strings s1 and s2, ignoring any characters found in the skip string.

Parameters
s1Pointer to the first string.
s2Pointer to the second string.
skipString containing characters to be skipped during comparison.
Returns
int Returns a negative value if s1 < s2, a positive value if s1 > s2, and 0 if equal.

Definition at line 617 of file sortfunctions.c.

617 {
618 do {
619 if (*s1 != *s2) {
620 while (*s1 && strchr(skip, *s1))
621 s1++;
622 while (*s2 && strchr(skip, *s2))
623 s2++;
624 if (*s1 != *s2)
625 return *s1 - *s2;
626 }
627 s1++;
628 s2++;
629 } while (*s1 && *s2);
630 return *s1 - *s2;
631}

◆ string_cmpasc()

int string_cmpasc ( const void * a,
const void * b )

Compare two strings in ascending order.

This function compares two null-terminated strings pointed to by a and b using strcmp.

Parameters
aPointer to the first string.
bPointer to the second string.
Returns
int Returns a negative value if *a < *b, a positive value if *a > *b, and 0 if equal.

Definition at line 175 of file sortfunctions.c.

175 {
176 return (strcmp(*((char **)a), *((char **)b)));
177}

◆ string_cmpdes()

int string_cmpdes ( const void * a,
const void * b )

Definition at line 179 of file sortfunctions.c.

179 {
180 return (strcmp(*((char **)b), *((char **)a)));
181}

◆ string_copy()

void string_copy ( void * a,
void * b )

Copy a string value.

This function copies the string from the source pointed to by b to the destination pointed to by a. If the destination buffer is large enough, it uses strcpy_ss; otherwise, it allocates memory using cp_str.

Parameters
aDestination pointer where the string will be copied.
bSource pointer from where the string will be copied.

Definition at line 192 of file sortfunctions.c.

192 {
193 if ((long)strlen(*((char **)a)) >= (long)strlen(*((char **)b)))
194 strcpy_ss(*((char **)a), *((char **)b));
195 else
196 cp_str(((char **)a), *((char **)b));
197}
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34

◆ unique()

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.

This function iterates through a sorted array and removes duplicate items based on the provided comparison function.

Parameters
basePointer to the first element of the array.
n_itemsNumber of items in the array.
sizeSize of each element in the array.
compareFunction pointer to the comparison function.
copyFunction pointer to the copy function.
Returns
int Returns the new number of unique items in the array.

Definition at line 211 of file sortfunctions.c.

213 {
214 long i, j;
215
216 for (i = 0; i < n_items - 1; i++) {
217 if ((*compare)((char *)base + i * size, (char *)base + (i + 1) * size) == 0) {
218 for (j = i + 1; j < n_items - 1; j++)
219 (*copy)((char *)base + j * size, (char *)base + (j + 1) * size);
220 n_items--;
221 i--;
222 }
223 }
224 return (n_items);
225}