/* * Prepare a subplan for sharing. This creates a Materialize node, * or marks the existing Materialize or Sort node as shared. After * this, you can call share_prepared_plan() as many times as you * want to share this plan. */ Plan * prepare_plan_for_sharing(PlannerInfo *root, Plan *common) { ShareType stype; Plan *shared = common; bool xslice = false; if (IsA(common, ShareInputScan)) { shared = common->lefttree; } else if(IsA(common, Material)) { Material *m = (Material *) common; Assert(m->share_type == SHARE_NOTSHARED); Assert(m->share_id == SHARE_ID_NOT_SHARED); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } else if (IsA(common, Sort)) { Sort *s = (Sort *) common; Assert(s->share_type == SHARE_NOTSHARED); stype = xslice ? SHARE_SORT_XSLICE : SHARE_SORT; s->share_id = SHARE_ID_NOT_ASSIGNED; s->share_type = stype; } else { Path matpath; Material *m = make_material(common); shared = (Plan *) m; cost_material(&matpath, root, common->total_cost, common->plan_rows, common->plan_width); shared->startup_cost = matpath.startup_cost; shared->total_cost = matpath.total_cost; shared->plan_rows = common->plan_rows; shared->plan_width = common->plan_width; shared->dispatch = common->dispatch; shared->flow = copyObject(common->flow); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } return shared; }
/* * Return the total cost of sharing common numpartner times. * If the planner need to make a decision whether the common subplan should be shared * or should be duplicated, planner should compare the cost returned by this function * against common->total_cost * numpartners. */ Cost cost_share_plan(Plan *common, PlannerInfo *root, int numpartners) { Path sipath; Path mapath; if(IsA(common, Material) || IsA(common, Sort)) { cost_shareinputscan(&sipath, root, common->total_cost, common->plan_rows, common->plan_width); return common->total_cost + (sipath.total_cost - common->total_cost) * numpartners; } cost_material(&mapath, root, common->total_cost, common->plan_rows, common->plan_width); cost_shareinputscan(&sipath, root, mapath.total_cost, common->plan_rows, common->plan_width); return mapath.total_cost + (sipath.total_cost - mapath.total_cost) * numpartners; }
List *share_plan(PlannerInfo *root, Plan *common, int numpartners) { List *shared_nodes = NULL; ShareType stype; Plan *shared = common; bool xslice = false; int i; Assert(numpartners > 0); if(numpartners == 1) { shared_nodes = lappend(shared_nodes, common); return shared_nodes; } if (IsA(common, ShareInputScan)) { shared = common->lefttree; } else if(IsA(common, Material)) { Material *m = (Material *) common; Assert(m->share_type == SHARE_NOTSHARED); Assert(m->share_id == SHARE_ID_NOT_SHARED); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } else if (IsA(common, Sort)) { Sort *s = (Sort *) common; Assert(s->share_type == SHARE_NOTSHARED); stype = xslice ? SHARE_SORT_XSLICE : SHARE_SORT; s->share_id = SHARE_ID_NOT_ASSIGNED; s->share_type = stype; } else { Path matpath; Material *m = make_material(common); shared = (Plan *) m; cost_material(&matpath, root, common->total_cost, common->plan_rows, common->plan_width); shared->startup_cost = matpath.startup_cost; shared->total_cost = matpath.total_cost; shared->plan_rows = common->plan_rows; shared->plan_width = common->plan_width; shared->dispatch = common->dispatch; shared->flow = copyObject(common->flow); stype = xslice ? SHARE_MATERIAL_XSLICE : SHARE_MATERIAL; m->share_id = SHARE_ID_NOT_ASSIGNED; m->share_type = stype; } for(i=0; i<numpartners; ++i) { Plan *p = (Plan *) make_shareinputscan(root, shared); shared_nodes = lappend(shared_nodes, p); } return shared_nodes; }
int Rune::rune_fill_energy(Rune_Hole_Detail &hole_detail, bool is_bat, const int8_t auto_buy) { // Check hole_lvl // if (! hole_detail.level) { // return ERROR_RUNE_HOLE_FIRST_ACTIVATE; // } if (hole_detail.level >= MAX_RUNE_HOLE_LVL) { return ERROR_UNBAN_LVL_MAX; } const Rune_Hole_Lvl_Cfg *hole_lvl_cfg = CONFIG_CACHE_RUNE->find_hole_lvl_cfg(hole_detail.level + 1); if (! hole_lvl_cfg) { return ERROR_CONFIG_NOT_EXIST; } if (hole_lvl_cfg->open_level > player_self()->level()) { return ERROR_LEVEL_LIMIT; } const Item_Detail_Config *item_material_cfg = CONFIG_CACHE_ITEM->find_item(hole_lvl_cfg->material_id); if (! item_material_cfg) { return ERROR_CONFIG_NOT_EXIST; } int times = is_bat ? 1000 : 1; int need_copper = 0; int need_gold = 0; int erase_material_num = 0; int buy_material_num = 0; //if (is_bat) { // 计算批量次数 int check_res = fill_energy_times(times, hole_detail, hole_lvl_cfg, item_material_cfg, auto_buy, need_copper, need_gold, erase_material_num, buy_material_num); if (check_res) { return check_res; } //} // check money Money_Sub_Info money_info_copper(Money_Sub_Info(Money_Sub_Type(COPPER_ONLY), need_copper, MONEY_SUB_RUNE_FILL_ENERGY)); if (money_info_copper.nums > 0) { int try_res = player_self()->pack_try_sub_money(money_info_copper); if (try_res) { return try_res; } } Money_Sub_Info money_info_gold(Money_Sub_Info(Money_Sub_Type(BIND_GOLD_FIRST), need_gold, MONEY_SUB_RUNE_FILL_ENERGY)); if (money_info_gold.nums > 0) { int try_res = player_self()->pack_try_sub_money(money_info_gold); if (try_res) { return try_res; } } // check material Id_Amount cost_material(hole_lvl_cfg->material_id, erase_material_num); if (cost_material.id && cost_material.amount) { int try_res = player_self()->pack_try_erase_item(PACK_T_PACKAGE_INDEX, cost_material); if (try_res) { return try_res; } } //-------------------------- all check passed line ------------------------------------------------ /* * Sub money and items */ if (money_info_copper.nums > 0) { player_self()->pack_sub_money(money_info_copper); } if (money_info_gold.nums > 0) { player_self()->pack_sub_money(money_info_gold); } if (cost_material.id && cost_material.amount) { player_self()->pack_erase_item(PACK_T_PACKAGE_INDEX, cost_material, Lose_Item_DM_Info(ITEM_LOSE_RUNE_FILL_ENERGY)); } bool is_upgrade = false; if (item_material_cfg->special_cfg.rune_essence_energy > 0) { int remain_energy = hole_detail.energy + item_material_cfg->special_cfg.rune_essence_energy * (cost_material.amount + buy_material_num); int hole_lvl = hole_detail.level; int old_hole_lvl = hole_detail.level; const Int_Vec *p_cfg_energy_vec = CONFIG_CACHE_RUNE->hole_lvl_energy_vec(); if (!p_cfg_energy_vec || p_cfg_energy_vec->empty()) { return ERROR_CONFIG_NOT_EXIST; } // 能量(经验)转化为等级 exp_to_lvl(remain_energy, hole_lvl, MAX_RUNE_HOLE_LVL, *p_cfg_energy_vec); hole_detail.level = hole_lvl; hole_detail.energy = remain_energy; is_upgrade = hole_detail.level > old_hole_lvl ? true : false; } return 0; }