int oph_subset_vector_free(oph_subset** subset_struct, int num) { int i; if (subset_struct) for (i=0;i<num;++i) if (subset_struct[i]) { oph_subset_free(subset_struct[i]); subset_struct[i]=NULL; } return OPH_SUBSET_LIB_OK; }
void oph_get_subarray2_deinit(UDF_INIT * initid) { //Free allocated space if (initid->ptr) { oph_get_subarray2_param *param = (oph_get_subarray2_param *) initid->ptr; if (param->measure) { free(param->measure); param->measure = NULL; } if (param->subset) { oph_subset_free(param->subset); param->subset = NULL; } if (param->flags) { free(param->flags); param->flags = NULL; } if (param->result) { free(param->result); param->result = NULL; } free(initid->ptr); initid->ptr = NULL; } }
int oph_subset_value_to_index(const char* in_cond, char* data, unsigned long long data_size, char* data_type, double offset, char* out_cond, oph_subset** out_subset) { if (!in_cond || !data || !data_size || !data_type || !out_cond) { pmesg(LOG_ERROR, __FILE__, __LINE__, "Null pointer\n"); return OPH_SUBSET_LIB_NULL_POINTER_ERR; } out_cond[0]=0; // Already allocated if (out_subset) *out_subset = NULL; double min, max; if (!strncasecmp(data_type,OPH_SUBSET_LIB_DOUBLE_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = *((double*)data); max = *(((double*)data)+data_size-1); } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_FLOAT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = (double)(*((float*)data)); max = (double)(*(((float*)data)+data_size-1)); } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_INT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = (double)(*((int*)data)); max = (double)(*(((int*)data)+data_size-1)); } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_LONG_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = (double)(*((long long*)data)); max = (double)(*(((long long*)data)+data_size-1)); } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_SHORT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = (double)(*((short*)data)); max = (double)(*(((short*)data)+data_size-1)); } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_BYTE_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { min = (double)(*((char*)data)); max = (double)(*(((char*)data)+data_size-1)); } else { pmesg(LOG_ERROR, __FILE__, __LINE__, "Unknown data type\n"); return OPH_SUBSET_LIB_DATA_ERR; } oph_subset_double* subset_double; if (oph_subset_double_init(&subset_double)) return OPH_SUBSET_LIB_SYSTEM_ERR; if (oph_subset_double_parse(in_cond, strlen(in_cond), subset_double, min, max, offset)) return OPH_SUBSET_LIB_DATA_ERR; oph_subset* subset; oph_subset_init(&subset); subset->number = subset_double->number; subset->type = (oph_subset_type*)calloc(subset->number,sizeof(oph_subset_type)); subset->start = (unsigned long long*)calloc(subset->number,sizeof(unsigned long long)); subset->end = (unsigned long long*)calloc(subset->number,sizeof(unsigned long long)); subset->stride = (unsigned long long*)calloc(subset->number,sizeof(unsigned long long)); subset->count = (unsigned long long*)calloc(subset->number,sizeof(unsigned long long)); subset->total = 0; int i, j; for (i=0;i<(int)subset->number;++i) subset->stride[i] = 1; if (!strncasecmp(data_type,OPH_SUBSET_LIB_DOUBLE_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((double*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((double*)data+j) - subset_double->start[i] < subset_double->start[i] - *((double*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((double*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((double*)data+j) - subset_double->start[i] > subset_double->start[i] - *((double*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; // The actual value is beetween j-1 (-inf if negative) and j (+inf if equal to data_size) break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((double*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if (!j && (subset_double->end[i] < *((double*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((double*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((double*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((double*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((double*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((double*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((double*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_FLOAT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((float*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((float*)data+j) - subset_double->start[i] < subset_double->start[i] - *((float*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((float*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((float*)data+j) - subset_double->start[i] > subset_double->start[i] - *((float*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((float*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if(!j && (subset_double->end[i] < *((float*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((float*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((float*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((float*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((float*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((float*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((float*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_BYTE_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((char*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((char*)data+j) - subset_double->start[i] < subset_double->start[i] - *((char*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((char*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((char*)data+j) - subset_double->start[i] > subset_double->start[i] - *((char*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((char*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if (!j && (subset_double->end[i] < *((char*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((char*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((char*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((char*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((char*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((char*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((char*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_SHORT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((short*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((short*)data+j) - subset_double->start[i] < subset_double->start[i] - *((short*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((short*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((short*)data+j) - subset_double->start[i] > subset_double->start[i] - *((short*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((short*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if (!j && (subset_double->end[i] < *((short*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((short*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((short*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((short*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((short*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((short*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((short*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_INT_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((int*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((int*)data+j) - subset_double->start[i] < subset_double->start[i] - *((int*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((int*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((int*)data+j) - subset_double->start[i] > subset_double->start[i] - *((int*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((int*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if (!j && (subset_double->end[i] < *((int*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((int*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((int*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((int*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((int*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((int*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((int*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else if (!strncasecmp(data_type,OPH_SUBSET_LIB_LONG_TYPE,OPH_SUBSET_LIB_MAX_TYPE_LENGTH)) { for (i=0;i<(int)subset->number;++i) { subset->type[i] = subset_double->type[i]; switch (subset_double->type[i]) { case OPH_SUBSET_LIB_SINGLE: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((long long*)data+j) >= subset_double->start[i]) break; if ((j<(int)data_size) && (!j || (*((long long*)data+j) - subset_double->start[i] < subset_double->start[i] - *((long long*)data+j-1)))) j++; // Non 'C'-like indexing } else { for (j=data_size-1; j>=0; --j) if (*((long long*)data+j) >= subset_double->start[i]) break; if ((j<0) || ((j<(int)data_size-1) && (*((long long*)data+j) - subset_double->start[i] > subset_double->start[i] - *((long long*)data+j+1)))) j++; j++; // Non 'C'-like indexing } subset->start[i] = subset->end[i] = j; break; case OPH_SUBSET_LIB_INTERVAL: if (min<max) { for (j=0; j<(int)data_size; ++j) if (*((long long*)data+j) >= subset_double->start[i]) break; if (j==(int)data_size) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if (!j && (subset_double->end[i] < *((int*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->start[i] = j+1; // Non 'C'-like indexing if (*((long long*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->end[i] = subset->start[i]; subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j++; j<(int)data_size; ++j) if (*((long long*)data+j) > subset_double->end[i]) break; subset->end[i] = j; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } else { for (j=data_size-1; j>=0; --j) if (*((long long*)data+j) >= subset_double->start[i]) break; if (j<0) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too high\n", subset_double->start[i]); continue; } else if ((j==(int)data_size-1) && (subset_double->end[i] < *((long long*)data+j))) { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset interval is out of dimension range: %f is too low\n", subset_double->end[i]); continue; } else { subset->end[i] = j+1; // Non 'C'-like indexing if (*((long long*)data+j) > subset_double->end[i]) // Empty set { pmesg(LOG_WARNING, __FILE__, __LINE__, "Subset cube is empty\n"); subset->start[i] = subset->end[i]; // Non 'C'-like indexing subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; continue; } for (j--; j>=0; --j) if (*((long long*)data+j) > subset_double->end[i]) break; subset->start[i] = j+2; // Non 'C'-like indexing if (subset->start[i] == subset->end[i]) subset_double->type[i] = OPH_SUBSET_LIB_SINGLE; } } break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_SYSTEM_ERR; } subset->count[i] = 1+(subset->end[i]-subset->start[i]); subset->total += subset->count[i]; } } else { pmesg(LOG_ERROR, __FILE__, __LINE__, "Unknown data type\n"); oph_subset_free(subset); oph_subset_double_free(subset_double); return OPH_SUBSET_LIB_DATA_ERR; } oph_subset_double_free(subset_double); if (!subset->total) { pmesg(LOG_DEBUG, __FILE__, __LINE__, "Subset cube is empty\n"); oph_subset_free(subset); return OPH_SUBSET_LIB_OK; } size_t len; unsigned int actual_number=0; char buffer[OPH_SUBSET_LIB_MAX_STRING_LENGTH], separator=0, found_empty=0; for (i=0;i<(int)subset->number;++i) { if (!subset->count[i]) { found_empty = 1; if (separator && (i==(int)subset->number-1) && ((len=strlen(out_cond)))) out_cond[len-1]=0; continue; } switch (subset->type[i]) { case OPH_SUBSET_LIB_SINGLE: snprintf(buffer,OPH_SUBSET_LIB_MAX_STRING_LENGTH,"%lld",subset->start[i]); break; case OPH_SUBSET_LIB_INTERVAL: snprintf(buffer,OPH_SUBSET_LIB_MAX_STRING_LENGTH,"%lld%s%lld",subset->start[i],OPH_SUBSET_LIB_PARAM_SEPARATOR,subset->end[i]); break; default: pmesg(LOG_ERROR, __FILE__, __LINE__, "Unexpected subset type\n"); oph_subset_free(subset); return OPH_SUBSET_LIB_SYSTEM_ERR; } strncat(out_cond,buffer,OPH_SUBSET_LIB_MAX_STRING_LENGTH); if (i<(int)subset->number-1) { strncat(out_cond,OPH_SUBSET_LIB_SUBSET_SEPARATOR,OPH_SUBSET_LIB_MAX_STRING_LENGTH); separator=1; } actual_number++; } if (!out_subset) oph_subset_free(subset); else { if (found_empty) // Remake subset to be exported { oph_subset* subset2; oph_subset_init(&subset2); subset2->number = actual_number; subset2->type = (oph_subset_type*)malloc(subset2->number*sizeof(oph_subset_type)); subset2->start = (unsigned long long*)malloc(subset2->number*sizeof(unsigned long long)); subset2->end = (unsigned long long*)malloc(subset2->number*sizeof(unsigned long long)); subset2->stride = (unsigned long long*)malloc(subset2->number*sizeof(unsigned long long)); subset2->count = (unsigned long long*)malloc(subset2->number*sizeof(unsigned long long)); subset2->total = subset->total; for (i=j=0;i<(int)subset->number;++i) if (subset->count[i]) { subset2->type[j] = subset->type[i]; subset2->start[j] = subset->start[i]; subset2->end[j] = subset->end[i]; subset2->stride[j] = subset->stride[i]; subset2->count[j] = subset->count[i]; j++; } oph_subset_free(subset); *out_subset = subset2; } else *out_subset = subset; } pmesg(LOG_INFO, __FILE__, __LINE__, "Subset string is '%s' when expressed as indexes\n",out_cond); return OPH_SUBSET_LIB_OK; }