* Addition, Scalar Product, Division between SparseData arrays * * There are a few factors to consider: * - The dimension of the left and right arguments must be the same * - We employ an algorithm that does the computation on the compressed contents * which creates a new SparseData array *------------------------------------------------------------------------------ */
| 1013 | *------------------------------------------------------------------------------ |
| 1014 | */ |
| 1015 | SparseData op_sdata_by_sdata(enum operation_t operation, |
| 1016 | SparseData left, SparseData right) |
| 1017 | { |
| 1018 | SparseData sdata = makeSparseData(); |
| 1019 | |
| 1020 | /* |
| 1021 | * Loop over the contents of the left array, operating on elements |
| 1022 | * of the right array and append a new value to the sdata when a |
| 1023 | * new unique value is generated. |
| 1024 | * |
| 1025 | * We will manage two cursors, one for each of left and right arrays |
| 1026 | */ |
| 1027 | char *liptr=left->index->data; |
| 1028 | char *riptr=right->index->data; |
| 1029 | int left_run_length, right_run_length; |
| 1030 | char *new_value,*last_new_value; |
| 1031 | int tot_run_length=-1; |
| 1032 | left_run_length = compword_to_int8(liptr); |
| 1033 | right_run_length = compword_to_int8(riptr); |
| 1034 | int left_lst=0,right_lst=0; |
| 1035 | int left_nxt=left_run_length,right_nxt=right_run_length; |
| 1036 | int nextpos = Min(left_nxt,right_nxt),lastpos=0; |
| 1037 | int i=0,j=0; |
| 1038 | size_t width = size_of_type(left->type_of_data); |
| 1039 | |
| 1040 | check_sdata_dimensions(left,right); |
| 1041 | |
| 1042 | new_value = (char *)palloc(width); |
| 1043 | last_new_value = (char *)palloc(width); |
| 1044 | |
| 1045 | while (1) |
| 1046 | { |
| 1047 | switch (operation) |
| 1048 | { |
| 1049 | case subtract: |
| 1050 | accum_sdata_result(new_value,left,i,-,right,j) |
| 1051 | break; |
| 1052 | case add: |
| 1053 | default: |
| 1054 | accum_sdata_result(new_value,left,i,+,right,j) |
| 1055 | break; |
| 1056 | case multiply: |
| 1057 | accum_sdata_result(new_value,left,i,*,right,j) |
| 1058 | break; |
| 1059 | case divide: |
| 1060 | accum_sdata_result(new_value,left,i,/,right,j) |
| 1061 | break; |
| 1062 | } |
| 1063 | /* |
| 1064 | * Potentially add a new run, depending on whether this is a |
| 1065 | * different value from the previous calculation. It may be |
| 1066 | * that this calculation has produced an identical value to |
| 1067 | * the previous, in which case we store it up, waiting for a |
| 1068 | * new value to happen. |
| 1069 | */ |
| 1070 | if (tot_run_length==-1) |
| 1071 | { |
| 1072 | memcpy(last_new_value,new_value,width); |
no test coverage detected