16#include "mdb_thread.h"
31 diff = *((
double *)b) - *((
double *)a);
32 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
47 diff = fabs(*((
double *)b)) - fabs(*((
double *)a));
48 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
63 diff = *((
double *)b) - *((
double *)a);
64 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
79 diff = fabs(*((
double *)b)) - fabs(*((
double *)a));
80 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
83void double_copy(
void *a,
void *b) {
85 *((
double *)a) = *((
double *)b);
88int float_cmpasc(
const void *a,
const void *b) {
91 diff = *((
float *)b) - *((
float *)a);
92 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
95int float_abs_cmpasc(
const void *a,
const void *b) {
98 diff = fabsf(*((
float *)b)) - fabsf(*((
float *)a));
99 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
102int float_cmpdes(
const void *a,
const void *b) {
105 diff = *((
float *)b) - *((
float *)a);
106 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
109int float_abs_cmpdes(
const void *a,
const void *b) {
112 diff = fabsf(*((
float *)b)) - fabsf(*((
float *)a));
113 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
116void float_copy(
void *a,
void *b) {
117 *((
float *)a) = *((
float *)b);
131 diff = *((int32_t *)b) - *((int32_t *)a);
132 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
146 diff = labs(*((int32_t *)b)) - labs(*((int32_t *)a));
147 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
150int long_cmpdes(
const void *a,
const void *b) {
152 diff = *((
long *)a) - *((
long *)b);
153 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
156int long_abs_cmpdes(
const void *a,
const void *b) {
158 diff = labs(*((
long *)a)) - labs(*((
long *)b));
159 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
162void long_copy(
void *a,
void *b) {
163 *((
long *)a) = *((
long *)b);
176 return (strcmp(*((
char **)a), *((
char **)b)));
179int string_cmpdes(
const void *a,
const void *b) {
180 return (strcmp(*((
char **)b), *((
char **)a)));
193 if ((
long)strlen(*((
char **)a)) >= (
long)strlen(*((
char **)b)))
196 cp_str(((
char **)a), *((
char **)b));
211int unique(
void *base,
size_t n_items,
size_t size,
212 int (*compare)(
const void *a,
const void *b),
213 void (*copy)(
void *a,
void *b)) {
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);
227static MDB_THREAD_LOCAL int (*item_compare)(
const void *a,
const void *b);
228static MDB_THREAD_LOCAL
int column_to_compare;
229static MDB_THREAD_LOCAL
int size_of_element;
230static MDB_THREAD_LOCAL
int number_of_columns;
246 int (*compare)(
const void *a,
const void *b)) {
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);
267 return ((*item_compare)(*a + size_of_element * column_to_compare,
268 *b + size_of_element * column_to_compare));
271void row_copy(
void *av,
void *bv) {
281static MDB_THREAD_LOCAL
long orderIndices;
282static MDB_THREAD_LOCK keyed_group_lock = MDB_THREAD_LOCK_INITIALIZER;
296 if ((value = strcmp((*(
const KEYED_INDEX *)ki1).stringKey, (*(
const KEYED_INDEX *)ki2).stringKey)))
299 return (*(
const KEYED_INDEX *)ki1).rowIndex - (*(
const KEYED_INDEX *)ki2).rowIndex;
315 if ((diff = (*(
const KEYED_INDEX *)ki1).doubleKey - (*(
const KEYED_INDEX *)ki2).doubleKey)) {
321 return (*(
const KEYED_INDEX *)ki1).rowIndex - (*(
const KEYED_INDEX *)ki2).rowIndex;
335 return strcmp((*(KEYED_EQUIVALENT *)kg1).equivalent[0]->stringKey, (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->stringKey);
349 if ((diff = (*(KEYED_EQUIVALENT *)kg1).equivalent[0]->doubleKey - (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->doubleKey)) {
369 KEYED_EQUIVALENT **keyedEquiv = NULL;
370 static MDB_THREAD_LOCAL KEYED_INDEX *keyedIndex = NULL;
378 if (!(keyedIndex = (KEYED_INDEX *)malloc(
sizeof(*keyedIndex) * points)) ||
379 !(keyedEquiv = (KEYED_EQUIVALENT **)malloc(
sizeof(*keyedEquiv) * points))) {
380 fprintf(stderr,
"memory allocation failure");
386 for (i1 = 0; i1 < points; i1++) {
387 keyedIndex[i1].stringKey =
string[i1];
388 keyedIndex[i1].rowIndex = i1;
393 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
394 for (i2 = i1 + 1; i2 < points; i2++) {
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");
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;
411 for (i1 = 0; i1 < points; i1++) {
412 keyedIndex[i1].doubleKey = value[i1];
413 keyedIndex[i1].rowIndex = i1;
418 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
419 for (i2 = i1 + 1; i2 < points; i2++) {
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");
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;
451 void *searchKeyData,
long reuse) {
452 KEYED_EQUIVALENT searchKey;
453 KEYED_INDEX keyedIndex;
454 KEYED_INDEX *equivalent[1];
457 equivalent[0] = &keyedIndex;
458 searchKey.equivalent = equivalent;
459 searchKey.equivalents = 1;
460 searchKey.nextIndex = 0;
462 keyedIndex.stringKey = *(
char **)searchKeyData;
463 mdb_thread_lock(&keyed_group_lock);
466 keyedIndex.doubleKey = *(
double *)searchKeyData;
467 mdb_thread_lock(&keyed_group_lock);
470 if (i < 0 || keyGroup[i]->nextIndex >= keyGroup[i]->equivalents) {
471 mdb_thread_unlock(&keyed_group_lock);
474 rowIndex = keyGroup[i]->equivalent[keyGroup[i]->nextIndex]->rowIndex;
476 keyGroup[i]->nextIndex += 1;
477 mdb_thread_unlock(&keyed_group_lock);
494 long i, keyGroups, i1, j, istart, jstart, i2, j2;
495 KEYED_EQUIVALENT **keyGroup;
496 char **tmpstring = NULL;
497 double *tmpdata = NULL;
501 index = (
long *)malloc(
sizeof(*index) * rows);
504 tmpstring = (
char **)data;
509 tmpdata = (
double *)data;
511 tmpdata = calloc(
sizeof(*tmpdata), rows);
512 for (i = 0; i < rows; i++) {
515 tmpdata[i] = *((
short *)data + i);
518 tmpdata[i] = *((
unsigned short *)data + i);
521 tmpdata[i] = *((int32_t *)data + i);
524 tmpdata[i] = *((uint32_t *)data + i);
527 tmpdata[i] = *((
unsigned char *)data + i);
530 tmpdata[i] = *((
float *)data + i);
533 fprintf(stderr,
"Invalid data type given!\n");
548 istart = keyGroups - 1;
550 for (i = istart, i2 = 0; i2 < keyGroups; i2++) {
554 jstart = keyGroup[i]->equivalents - 1;
556 for (j = jstart, j2 = 0; j2 < keyGroup[i]->equivalents; j2++) {
559 ((
char **)data)[i1] = keyGroup[i]->equivalent[j]->stringKey;
562 ((
double *)data)[i1] = keyGroup[i]->equivalent[j]->doubleKey;
565 ((
float *)data)[i1] = (float)keyGroup[i]->equivalent[j]->doubleKey;
568 ((int32_t *)data)[i1] = (int32_t)keyGroup[i]->equivalent[j]->doubleKey;
571 ((uint32_t *)data)[i1] = (uint32_t)keyGroup[i]->equivalent[j]->doubleKey;
574 ((
short *)data)[i1] = (short)keyGroup[i]->equivalent[j]->doubleKey;
577 ((
unsigned short *)data)[i1] = (
unsigned short)keyGroup[i]->equivalent[j]->doubleKey;
580 ((
char *)data)[i1] = (
unsigned char)keyGroup[i]->equivalent[j]->doubleKey;
583 fprintf(stderr,
"Invalid data type given!\n");
587 index[i1] = keyGroup[i]->equivalent[j]->rowIndex;
599 for (i = 0; i < keyGroups; i++) {
600 free(keyGroup[i]->equivalent);
617int strcmp_skip(
const char *s1,
const char *s2,
const char *skip) {
620 while (*s1 && strchr(skip, *s1))
622 while (*s2 && strchr(skip, *s2))
629 }
while (*s1 && *s2);
SDDS Data Types Definitions.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
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.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
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.
int CompareDoubleKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on double keys.
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 double_abs_cmpasc(const void *a, const void *b)
Compare the absolute values of two doubles in ascending order.
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.
int double_cmpdes(const void *a, const void *b)
Compare two doubles in descending order.
int CompareStringKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on string keys.
int long_cmpasc(const void *a, const void *b)
Compare two long integers in ascending order.
int double_cmpasc(const void *a, const void *b)
Compare two doubles in ascending order.
int CompareDoubleKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on double keys.
long * sort_and_return_index(void *data, long type, long rows, long increaseOrder)
Sort data and return the sorted index.
int long_abs_cmpasc(const void *a, const void *b)
Compare the absolute values of two long integers in ascending order.
int CompareStringKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on string keys.
int string_cmpasc(const void *a, const void *b)
Compare two strings in ascending order.
int row_compare(const void *av, const void *bv)
Compare two rows based on the previously set sorting parameters.
long FindMatchingKeyGroup(KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
Find a matching key group for a search key.
int double_abs_cmpdes(const void *a, const void *b)
Compare the absolute values of two doubles in descending order.
void string_copy(void *a, void *b)
Copy a string value.
int strcmp_skip(const char *s1, const char *s2, const char *skip)
Compare two strings while skipping specified characters.
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.