* @param array_val The array of values to be converted to values in SparseData * @param array_pos The array of positions to be converted to runs in SparseData * @param type_of_data type of the value element * @param count The (common) size of array and array_pos * @param end The size of the desired SparseData * @param default_val The default value for positions unspecified in array_pos * @re
| 1382 | * @return A SparseData representation of an input array of doubles |
| 1383 | */ |
| 1384 | SparseData position_to_sdata(double *array_val, int64 *array_pos, |
| 1385 | Oid type_of_data, |
| 1386 | int count, int64 end, double default_val) { |
| 1387 | |
| 1388 | char * array = (char *)array_val; |
| 1389 | char * base_val = (char *)&default_val; |
| 1390 | size_t width = size_of_type(type_of_data); |
| 1391 | char *run_val=array; |
| 1392 | int64 run_len; |
| 1393 | SparseData sdata = makeSparseData(); |
| 1394 | |
| 1395 | int *index = (int*)palloc(count*sizeof(int)); |
| 1396 | for(int i = 0; i < count; ++i) |
| 1397 | index[i] = i; |
| 1398 | |
| 1399 | /* this is a temp solution that will be in place only until qsort_r |
| 1400 | * is a standard library function */ |
| 1401 | array_pos_ref = array_pos; |
| 1402 | qsort(index, count, sizeof(int), compar); |
| 1403 | |
| 1404 | sdata->type_of_data=type_of_data; |
| 1405 | if(array_pos[index[0]] > 1){ |
| 1406 | run_len = array_pos[index[0]]-1; |
| 1407 | add_run_to_sdata(base_val,run_len,width,sdata); |
| 1408 | } |
| 1409 | |
| 1410 | for (int i = 0; i<count; i++) { |
| 1411 | run_len=1; |
| 1412 | /* |
| 1413 | * Note that special double values like denormalized numbers and exceptions |
| 1414 | * like NaN are treated like any other value - if there are duplicates, the |
| 1415 | * value of the special number is preserved and they are counted. |
| 1416 | */ |
| 1417 | while ((i < count-1) && |
| 1418 | ((array_pos[index[i+1]] - array_pos[index[i]])==1) && |
| 1419 | (memcmp((array+index[i]*size_of_type(type_of_data)), |
| 1420 | (array+index[i+1]*size_of_type(type_of_data)),width)==0)) { |
| 1421 | run_len++; |
| 1422 | i++; |
| 1423 | } |
| 1424 | while ((i < count-1)&&((array_pos[index[i+1]] - array_pos[index[i]])==0)) { |
| 1425 | if ((memcmp((array+index[i]*size_of_type(type_of_data)), |
| 1426 | (array+index[i+1]*size_of_type(type_of_data)),width)==0)) { |
| 1427 | i++; |
| 1428 | } else { |
| 1429 | ereport(ERROR, |
| 1430 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 1431 | errmsg("posit_to_sdata conflicting values for the same position"))); |
| 1432 | } |
| 1433 | } |
| 1434 | run_val = array+index[i]*size_of_type(type_of_data); |
| 1435 | add_run_to_sdata(run_val,run_len,width,sdata); |
| 1436 | |
| 1437 | if(i < count-1){ |
| 1438 | run_len = array_pos[index[i+1]]-array_pos[index[i]]-1; |
| 1439 | if (run_len > 0){ |
| 1440 | add_run_to_sdata(base_val,run_len,width,sdata); |
| 1441 | } |
no test coverage detected