//--------------------------------------------------------------- // START FUNC DECL int f1opf2( char *tbl, char *f1, char *str_op_spec, char *f2 ) // STOP FUNC DECL { int status = 0; char *f1_X = NULL; size_t f1_nX = 0; char *nn_f1_X = NULL; size_t nn_f1_nX = 0; char *sz_f1_X = NULL; size_t sz_f1_nX = 0; FLD_TYPE *f1_meta = NULL, *nn_f1_meta = NULL, *sz_f1_meta = NULL; long long nR; int tbl_id = INT_MIN, f1_id = INT_MIN, nn_f1_id = INT_MIN, sz_f1_id = INT_MIN; int f2_id = INT_MIN, nn_f2_id = INT_MIN, sz_f2_id = INT_MIN; char str_meta_data[1024]; int f1type; char *op = NULL, *str_val = NULL; FILE *ofp = NULL; char *opfile = NULL; FILE *nn_ofp = NULL; char *nn_opfile = NULL; FILE *sz_ofp = NULL; char *sz_opfile = NULL; char *xform_enum = NULL, *hash_algo = NULL; //---------------------------------------------------------------- if ( ( tbl == NULL ) || ( *tbl == '\0' ) ) { go_BYE(-1); } if ( ( f1 == NULL ) || ( *f1 == '\0' ) ) { go_BYE(-1); } if ( ( f2 == NULL ) || ( *f2 == '\0' ) ) { go_BYE(-1); } if ( ( str_op_spec == NULL ) || ( *str_op_spec == '\0' ) ) { go_BYE(-1); } zero_string(str_meta_data, 1024); //-------------------------------------------------------- status = extract_name_value(str_op_spec, "op=", ":", &op); cBYE(status); if ( op == NULL ) { go_BYE(-1); } //-------------------------------------------------------- status = chk_if_ephemeral(&f2); cBYE(status); status = is_tbl(tbl, &tbl_id); cBYE(status); chk_range(tbl_id, 0, g_n_tbl); nR = g_tbl[tbl_id].nR; status = is_fld(NULL, tbl_id, f1, &f1_id); cBYE(status); chk_range(f1_id, 0, g_n_fld); f1_meta = &(g_fld[f1_id]); status = rs_mmap(f1_meta->filename, &f1_X, &f1_nX, 0); cBYE(status); // Get nn field for f1 if if it exists nn_f1_id = g_fld[f1_id].nn_fld_id; if ( nn_f1_id >= 0 ) { nn_f1_meta = &(g_fld[nn_f1_id]); status = rs_mmap(nn_f1_meta->filename, &nn_f1_X, &nn_f1_nX, 0); cBYE(status); } //--------------------------------------------- status = mk_ifldtype(f1_meta->fldtype, &f1type); /* TODO: Why do we get an error for 'char string' ? */ // If f1 type is 'char string', then get sz field if ( strcmp(f1_meta->fldtype, "char string") == 0 ) { sz_f1_id = g_fld[f1_id].sz_fld_id; chk_range(sz_f1_id, 0, g_n_fld); sz_f1_meta = &(g_fld[sz_f1_id]); status = rs_mmap(sz_f1_meta->filename, &sz_f1_X, &sz_f1_nX, 0); cBYE(status); } //-------------------------------------------------------- if ( strcmp(op, "xform") == 0 ) { bool is_some_null; status = open_temp_file(&ofp, &opfile, 0); cBYE(status); status = open_temp_file(&nn_ofp, &nn_opfile, 0); cBYE(status); status = open_temp_file(&sz_ofp, &sz_opfile, 0); cBYE(status); status = str_xform(nR, f1_X, (int *)sz_f1_X, nn_f1_X, str_op_spec, ofp, nn_ofp, sz_ofp, &is_some_null); cBYE(status); fclose_if_non_null(ofp); fclose_if_non_null(nn_ofp); fclose_if_non_null(sz_ofp); sprintf(str_meta_data, "filename=%s:fldtype=char string:n_sizeof=0", opfile); status = add_fld(tbl, f2, str_meta_data, &f2_id); cBYE(status); status = add_aux_fld(tbl, f2, sz_opfile, "sz", &sz_f2_id); cBYE(status); if ( is_some_null ) { status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id); cBYE(status); } else { unlink(nn_opfile); } } else if ( strcmp(op, "hash") == 0 ) { int hash_len; char *endptr = NULL; status = extract_name_value(str_op_spec, "len=", ":", &str_val); cBYE(status); if ( str_val == NULL ) { go_BYE(-1); } hash_len = strtol(str_val, &endptr, 10); if ( *endptr != '\0' ) { go_BYE(-1); } status = extract_name_value(str_op_spec, "hash_algo=", ":", &hash_algo); cBYE(status); status = open_temp_file(&ofp, &opfile, 0); cBYE(status); status = f1opf2_hash(hash_algo, nR, f1_X, f1_nX, (int *)sz_f1_X, f1_meta->n_sizeof, nn_f1_X, hash_len, ofp); cBYE(status); fclose_if_non_null(ofp); sprintf(str_meta_data, "filename=%s", opfile); switch ( hash_len ) { case 4 : strcat(str_meta_data, ":fldtype=int:n_sizeof=4"); break; case 8 : strcat(str_meta_data, ":fldtype=long long:n_sizeof=8"); break; default : go_BYE(-1); break; } fclose_if_non_null(ofp); status = add_fld(tbl, f2, str_meta_data, &f2_id); cBYE(status); } else if ( ( strcmp(op, "conv") == 0 ) || ( strcmp(op, "dateconv" ) == 0 ) || ( strcmp(op, "bitcount" ) == 0 ) || ( strcmp(op, "sqrt" ) == 0 ) || ( strcmp(op, "!" ) == 0 ) || ( strcmp(op, "++" ) == 0 ) || ( strcmp(op, "--" ) == 0 ) || ( strcmp(op, "~" ) == 0 ) ) { status = vec_f1opf2(nR, f1type, str_meta_data, f1_X, nn_f1_X, sz_f1_X, op, str_op_spec, &opfile, &nn_opfile); cBYE(status); status = add_fld(tbl, f2, str_meta_data, &f2_id); cBYE(status); if ( nn_opfile != NULL ) { status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id); cBYE(status); } } else if ( strcmp(op, "shift") == 0 ) { int ival; char *endptr = NULL; status = extract_name_value(str_op_spec, "val=", ":", &str_val); cBYE(status); ival = strtol(str_val, &endptr, 10); if ( *endptr != '\0' ) { fprintf(stderr, "invalid shift specifier = [%s] \n", str_val); go_BYE(-1); } if ( ( ival == 0 ) || ( ival > MAX_SHIFT ) || ( ival < -MAX_SHIFT ) || (ival >= nR )) { fprintf(stderr, "shift = [%d] is out of bounds \n", ival); go_BYE(-1); } status = open_temp_file(&ofp, &opfile, 0); cBYE(status); status = open_temp_file(&nn_ofp, &nn_opfile, 0); cBYE(status); status = f1opf2_shift(f1_X, nn_f1_X, nR, f1_meta->fldtype, ival, ofp, nn_ofp); cBYE(status); fclose_if_non_null(ofp); fclose_if_non_null(nn_ofp); sprintf(str_meta_data, "filename=%s:fldtype=%s:n_sizeof=%d",opfile, f1_meta->fldtype, f1_meta->n_sizeof); status = add_fld(tbl, f2, str_meta_data, &f2_id); cBYE(status); status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id); cBYE(status); } else if ( strcmp(op, "cum") == 0 ) { /* TODO: Document. If you do a cum, resultant field is all def */ char *new_fld_type = NULL; int optype, n_sizeof; char *str_reset_on = NULL, *str_reset_to = NULL, *endptr = NULL; long long reset_on = 0, reset_to = 0; bool is_reset = false; status = extract_name_value(str_op_spec, "newtype=", ":", &new_fld_type); cBYE(status); status = extract_name_value(str_op_spec, "reset_on=", ":", &str_reset_on); cBYE(status); if ( str_reset_on != NULL ) { reset_on = strtoll(str_reset_on, &endptr, 10); if ( *endptr != '\0' ) { go_BYE(-1); } is_reset = true; status = extract_name_value(str_op_spec, "reset_to=", ":", &str_reset_to); cBYE(status); if ( str_reset_to == NULL ) { go_BYE(-1); } reset_to = strtoll(str_reset_to, &endptr, 10); if ( *endptr != '\0' ) { go_BYE(-1); } } if ( new_fld_type == NULL ) { optype = f1type; new_fld_type = strdup(f1_meta->fldtype); n_sizeof = f1_meta->n_sizeof; } else { if ( strcmp(new_fld_type, "int") == 0 ) { optype = FLDTYPE_INT; n_sizeof = sizeof(int); } else if ( strcmp(new_fld_type, "long long") == 0 ) { optype = FLDTYPE_LONGLONG; n_sizeof = sizeof(long long); } else { go_BYE(-1); } } status = f1opf2_cum(f1_X, nR, f1type, optype, is_reset, reset_on, reset_to, &opfile); cBYE(status); sprintf(str_meta_data, "filename=%s:fldtype=%s:n_sizeof=%d",opfile, new_fld_type, n_sizeof); status = add_fld(tbl, f2, str_meta_data, &f2_id); cBYE(status); free_if_non_null(new_fld_type); free_if_non_null(str_reset_on); free_if_non_null(str_reset_to); } else { fprintf(stderr, "Invalid op = [%s] \n", op); go_BYE(-1); } BYE: fclose_if_non_null(ofp); fclose_if_non_null(nn_ofp); g_write_to_temp_dir = false; rs_munmap(f1_X, f1_nX); rs_munmap(nn_f1_X, nn_f1_nX); rs_munmap(sz_f1_X, sz_f1_nX); free_if_non_null(op); free_if_non_null(xform_enum); free_if_non_null(hash_algo); free_if_non_null(str_val); free_if_non_null(opfile); free_if_non_null(nn_opfile); free_if_non_null(sz_opfile); return(status); }
// START FUNC DECL int exec_comp_expr( int tbl_id, TBL_REC_TYPE tbl_rec, COMP_EXPR_TYPE *comp_expr, int n_comp_expr ) // STOP FUNC DECL { int status = 0; // Following used to combine f_to_s and f1f2_to_s double l_partsum_0_F8; long long l_partsum_0_I8, l_partsum_1_I8; double partsum_0_F8[MAX_STATEMENTS_IN_COMP_EXPR]; long long partsum_0_I8[MAX_STATEMENTS_IN_COMP_EXPR]; long long partsum_1_I8[MAX_STATEMENTS_IN_COMP_EXPR]; long long partsum_2_I8[MAX_STATEMENTS_IN_COMP_EXPR]; bool is_numer_set[MAX_STATEMENTS_IN_COMP_EXPR]; #define BUFLEN 32 #define RSLT_BUF_SIZE 1024 char op[BUFLEN]; bool is_null; char rslt_buf[RSLT_BUF_SIZE]; char buf0[RSLT_BUF_SIZE]; char buf1[RSLT_BUF_SIZE]; char buf2[RSLT_BUF_SIZE]; zero_string(rslt_buf, RSLT_BUF_SIZE); zero_string(buf0, RSLT_BUF_SIZE); zero_string(buf1, RSLT_BUF_SIZE); zero_string(buf2, RSLT_BUF_SIZE); long long time_per_expr[MAX_STATEMENTS_IN_COMP_EXPR]; long long t_before, t_after; for ( int i = 0; i < MAX_STATEMENTS_IN_COMP_EXPR; i++ ) { time_per_expr[i] = 0; } if ( n_comp_expr <= 1 ) { go_BYE(-1); } for ( int i = 0; i < MAX_STATEMENTS_IN_COMP_EXPR; i++ ) { // numerator assigned inside loop partsum_0_I8[i] = 0; partsum_0_F8[i] = 0; partsum_1_I8[i] = 0; partsum_2_I8[i] = 0; is_numer_set[i] = false; } // determine number of blocks and block size. Last block may be bigger. int block_size = COMP_EXPR_BLOCK_SIZE; // block_size = 5; // TODO P0 Just for debugging if ( n_comp_expr <= 1 ) { go_BYE(-1); } long long nR = tbl_rec.nR; int num_blocks = nR / block_size; if ( num_blocks == 0 ) { num_blocks = 1; } for ( int b = 0; b < num_blocks; b++ ) { long long lb = block_size * b; long long ub = lb + block_size; if ( b == ( num_blocks-1) ) { ub = nR; } long long eff_nR = ub - lb; for ( int i = 0; i < n_comp_expr; i++ ) { t_before = get_time_usec(); long long *cntI8 = NULL; long long dst_nR; char *f1_X = NULL, *nn_f1_X = NULL; long long f1nR = 0; FLD_TYPE f1type; char *f2_X = NULL, *nn_f2_X = NULL; long long f2nR = 0; FLD_TYPE f2type; char *f3_X = NULL, *nn_f3_X = NULL; long long f3nR = 0; FLD_TYPE f3type; char *f4_X = NULL, *nn_f4_X = NULL; long long f4nR = 0; FLD_TYPE f4type; int *src_fld = NULL; zero_string(op, BUFLEN); char *str_op_spec = comp_expr[i].op_spec; char *str_scalar = comp_expr[i].scalar; // NOTE ASSUMPTION THAT nn is stored as I1 and not as B status = offset_pointers(tbl_id, comp_expr, i, 0, lb, &f1nR, &f1type, &f1_X, &nn_f1_X); cBYE(status); status = offset_pointers(tbl_id, comp_expr, i, 1, lb, &f2nR, &f2type, &f2_X, &nn_f2_X); cBYE(status); status = offset_pointers(tbl_id, comp_expr, i, 2, lb, &f3nR, &f3type, &f3_X, &nn_f3_X); cBYE(status); status = offset_pointers(tbl_id, comp_expr, i, 3, lb, &f4nR, &f4type, &f4_X, &nn_f4_X); cBYE(status); /* START: Some additional checking on pointers */ switch ( comp_expr[i].op ) { case op_count : case op_countf : case op_f1f2opf3 : case op_f1opf2f3 : break; default : /* there is no f3 field for these operations */ if ( f3_X != NULL ) { go_BYE(-1); } if ( nn_f3_X != NULL ) { go_BYE(-1); } if ( f3type != undef_fldtype ) { go_BYE(-1); } break; } switch ( comp_expr[i].op ) { case op_countf : break; default : /* there is no f4 field for these operations */ if ( f4_X != NULL ) { go_BYE(-1); } if ( nn_f4_X != NULL ) { go_BYE(-1); } if ( f4type != undef_fldtype ) { go_BYE(-1); } break; } /* STOP: Some additional checking on pointers */ int nT = 1; switch ( comp_expr[i].op ) { case op_f1s1opf2 : status = vec_f1s1opf2(eff_nR, f1type, f1_X, nn_f1_X, str_scalar, str_op_spec, f2_X, nn_f2_X, f2type); break; case op_f1opf2f3 : go_BYE(-1); // TODO: P2 To be implemented break; case op_f1f2opf3 : status = vec_f1f2opf3(eff_nR, f1type, f2type, f1_X, nn_f1_X, f2_X, nn_f2_X, str_op_spec, f3type, f3_X, nn_f3_X); break; case op_f1opf2 : status = extract_S(str_op_spec, "op=[", "]", op, BUFLEN, &is_null); cBYE(status); if ( is_null ) { go_BYE(-1); } status = vec_f1opf2(eff_nR, f1type, f1_X, nn_f1_X, op, f2_X, nn_f2_X, f2type); break; case op_countf : // fld1 is src fld // fld2 is fk to outtbl // fld3 is cfld // fld4 is cnt in outtbl src_fld = (int *)f1_X; cntI8 = (long long *)f4_X; dst_nR = f4nR; if ( b == 0 ) { assign_const_I8(cntI8, dst_nR, 0); } if ( f3_X != NULL ) { switch ( f2type ) { case I1 : status = compute_nT_for_count(eff_nR, dst_nR, &nT); cBYE(status); if ( nT == 1 ) { status = countf_nn_I1(src_fld, (char *)f1_X, eff_nR, f3_X, cntI8, dst_nR, false); cBYE(status); } else { status = par_countf_cfld_I1(src_fld, (char *)f2_X, eff_nR, f3_X, cntI8, dst_nR, nT); cBYE(status); } break; case I2 : if ( nT == 1 ) { status = countf_nn_I2(src_fld, (short *)f2_X, eff_nR, f3_X, cntI8, dst_nR, false); cBYE(status); } else { status = par_countf_cfld_I2(src_fld, (short *)f2_X, eff_nR, f3_X, cntI8, dst_nR, nT); cBYE(status); } break; case I4 : status = countf_nn_I4(src_fld, (int *)f2_X, eff_nR, f3_X, cntI8, dst_nR, false); break; case I8 : status = countf_nn_I8(src_fld, (long long *)f2_X, eff_nR, f3_X, cntI8, dst_nR, false); break; default : go_BYE(-1); break; } } else { switch ( f2type ) { case I1 : if ( nT == 1 ) { status = countf_I1(src_fld, (char *)f2_X, eff_nR, cntI8, dst_nR, false); } else { status = par_countf_I1(src_fld, (char *)f2_X, eff_nR, cntI8, dst_nR, nT); cBYE(status); } break; case I2 : status = countf_I2(src_fld, (short *)f2_X, eff_nR, cntI8, dst_nR, false); break; case I4 : status = countf_I4(src_fld, (int *)f2_X, eff_nR, cntI8, dst_nR, false); break; case I8 : status = countf_I8(src_fld, (long long *)f2_X, eff_nR, cntI8, dst_nR, false); break; default : go_BYE(-1); break; } } cBYE(status); break; case op_count : // fld1 is fk to outtbl // fld2 is cfld // fld3 is cnt in outtbl cntI8 = (long long *)f3_X; dst_nR = f3nR; if ( b == 0 ) { assign_const_I8(cntI8, dst_nR, 0); } if ( f2_X != NULL ) { switch ( f1type ) { case I1 : status = compute_nT_for_count(eff_nR, dst_nR, &nT); cBYE(status); if ( nT == 1 ) { status = count_nn_I1((char *)f1_X, eff_nR, f2_X, cntI8, dst_nR, false); cBYE(status); } else { status = par_count_cfld_I1((char *)f1_X, eff_nR, f2_X, cntI8, dst_nR, nT); cBYE(status); } break; case I2 : if ( nT == 1 ) { status = count_nn_I2((short *)f1_X, eff_nR, f2_X, cntI8, dst_nR, false); cBYE(status); } else { status = par_count_cfld_I2((short *)f1_X, eff_nR, f2_X, cntI8, dst_nR, nT); cBYE(status); } break; case I4 : status = count_nn_I4((int *)f1_X, eff_nR, f2_X, cntI8, dst_nR, false); break; case I8 : status = count_nn_I8((long long *)f1_X, eff_nR, f2_X, cntI8, dst_nR, false); break; default : go_BYE(-1); break; } } else { switch ( f1type ) { case I1 : if ( nT == 1 ) { status = count_I1((char *)f1_X, eff_nR, cntI8, dst_nR, false); } else { status = par_count_I1((char *)f1_X, eff_nR, cntI8, dst_nR, nT); cBYE(status); } break; case I2 : status = count_I2((short *)f1_X, eff_nR, cntI8, dst_nR, false); break; case I4 : status = count_I4((int *)f1_X, eff_nR, cntI8, dst_nR, false); break; case I8 : status = count_I8((long long *)f1_X, eff_nR, cntI8, dst_nR, false); break; default : go_BYE(-1); break; } } cBYE(status); break; case op_f_to_s : status = vec_f_to_s(f1_X, f1type, nn_f1_X, eff_nR, str_op_spec, rslt_buf, RSLT_BUF_SIZE); // Combine buffers across invocations status = read_nth_val(rslt_buf, ":", 0, buf0, RSLT_BUF_SIZE); cBYE(status); status = read_nth_val(rslt_buf, ":", 1, buf1, RSLT_BUF_SIZE); cBYE(status); status = stoI8(buf1, &l_partsum_1_I8); cBYE(status); if ( l_partsum_1_I8 < 0 ) { go_BYE(-1); } if ( l_partsum_1_I8 > 0 ) { partsum_1_I8[i] += l_partsum_1_I8; switch ( f1type ) { case I1 : case I2 : case I4 : case I8 : status = stoI8(buf0, &l_partsum_0_I8); cBYE(status); if ( is_numer_set[i] == false ) { is_numer_set[i] = true; partsum_0_I8[i] = l_partsum_0_I8; } else { if ( strcmp(str_op_spec, "min") == 0 ) { partsum_0_I8[i] = min(partsum_0_I8[i], l_partsum_0_I8); } else if ( strcmp(str_op_spec, "max") == 0 ) { partsum_0_I8[i] = max(partsum_0_I8[i], l_partsum_0_I8); } else if ( strcmp(str_op_spec, "sum") == 0 ) { partsum_0_I8[i] += l_partsum_0_I8; } else { go_BYE(-1); } } break; case F4 : case F8 : status = stoF8(buf0, &l_partsum_0_F8); cBYE(status); if ( is_numer_set[i] == false ) { is_numer_set[i] = true; partsum_0_F8[i] = l_partsum_0_F8; } else { if ( strcmp(str_op_spec, "min") == 0 ) { partsum_0_F8[i] = min(partsum_0_F8[i], l_partsum_0_F8); } else if ( strcmp(str_op_spec, "max") == 0 ) { partsum_0_F8[i] = max(partsum_0_F8[i], l_partsum_0_F8); } else if ( strcmp(str_op_spec, "sum") == 0 ) { partsum_0_F8[i] += l_partsum_0_F8; } else { go_BYE(-1); } } break; default : go_BYE(-1); break; } } break; case op_f1f2_to_s : status = core_f1f2_to_s(str_op_spec, f1_X, f1type, f2_X, f2type, eff_nR, rslt_buf, RSLT_BUF_SIZE); cBYE(status); // Combine buffers across invocations status = read_nth_val(rslt_buf, ":", 0, buf0, RSLT_BUF_SIZE); cBYE(status); status = read_nth_val(rslt_buf, ":", 1, buf1, RSLT_BUF_SIZE); cBYE(status); status = read_nth_val(rslt_buf, ":", 2, buf2, RSLT_BUF_SIZE); cBYE(status); // Note that processing for f1f2_to_s is much simpler than // f_to_s because we support much fewer options //------------------------------ long long tempI8; status = stoI8(buf0, &tempI8); cBYE(status); partsum_0_I8[i] += tempI8; //------------------------------ status = stoI8(buf1, &tempI8); cBYE(status); if ( tempI8 < 0 ) { go_BYE(-1); } partsum_1_I8[i] += tempI8; //------------------------------ status = stoI8(buf2, &tempI8); cBYE(status); if ( tempI8 <= 0 ) { go_BYE(-1); } partsum_2_I8[i] += tempI8; //------------------------------ break; default : go_BYE(-1); break; } t_after = get_time_usec(); time_per_expr[i] += (t_after - t_before); } } // Print out scalar variables if any for ( int i = 0; i < n_comp_expr; i++ ) { // DBG fprintf(stderr, "time[%d] = %lld \n", i, time_per_expr[i]); switch ( comp_expr[i].op ) { case op_f_to_s : if ( is_numer_set[i] == true ) { FLD_TYPE f1type = comp_expr[i].fld[0].fldtype; switch ( f1type ) { case I1 : case I2 : case I4 : case I8 : fprintf(stdout, "%s=%lld:%lld\n", comp_expr[i].env_var, partsum_0_I8[i], partsum_1_I8[i]); break; case F4 : case F8 : fprintf(stdout, "%s=%lf:%lld\n", comp_expr[i].env_var, partsum_0_F8[i], partsum_1_I8[i]); break; default : go_BYE(-1); break; } } else { fprintf(stdout, "%s=0:0\n", comp_expr[i].env_var); } break; case op_f1f2_to_s : fprintf(stdout, "%s=%lld:%lld:%lld\n", comp_expr[i].env_var, partsum_0_I8[i], partsum_1_I8[i], partsum_2_I8[i]); break; default : // nothing to do break; } } BYE: return status ; }