bool LogicalQueryPlanRoot::GetOptimalPhysicalPlan(
    Requirement requirement, PhysicalPlanDescriptor& final_physical_plan_desc,
    const unsigned& block_size) {
  std::vector<PhysicalPlanDescriptor> candidate_physical_plan;
  Requirement current_req;
  current_req.setRequiredLocations(std::vector<NodeID>(1, collecter_node));

  Requirement merged_req;
  bool requirement_merged = current_req.tryMerge(requirement, merged_req);
  if (requirement_merged) {
    current_req = merged_req;
  }

  PhysicalPlanDescriptor physical_plan;

  /** no requirement**/
  if (child_->GetOptimalPhysicalPlan(Requirement(), physical_plan,
                                     block_size)) {
    NetworkTransfer transfer =
        current_req.requireNetworkTransfer(physical_plan.plan_context_);

    if (transfer == NONE) {
      candidate_physical_plan.push_back(physical_plan);
    } else if ((transfer == OneToOne) || (transfer == Shuffle)) {
      // why transfer is compared with OneToOne, whose type is binding_mode?
      // ---Yu

      /* the input PlanContext should be transfered in the network to meet the
       * requirement
       * TODO: implement OneToOne Exchange
       * */
      physical_plan.cost += physical_plan.plan_context_.GetAggregatedDatasize();

      ExchangeMerger::State state;
      state.block_size_ = block_size;
      state.child_ = physical_plan.plan;  // child_iterator;
      state.exchange_id_ =
          IDsGenerator::getInstance()->generateUniqueExchangeID();
      state.schema_ = GetSchema(physical_plan.plan_context_.attribute_list_);
      state.upper_id_list_.push_back(collecter_node);
      state.partition_schema_ = partition_schema::set_hash_partition(0);
      state.lower_id_list_ =
          GetInvolvedNodeID(physical_plan.plan_context_.plan_partitioner_);
      PhysicalOperatorBase* exchange = new ExchangeMerger(state);
      physical_plan.plan = exchange;
    }
  }

  /** with requirement**/
  if (child_->GetOptimalPhysicalPlan(current_req, physical_plan, block_size)) {
    candidate_physical_plan.push_back(physical_plan);
  }

  PhysicalPlanDescriptor best_plan =
      GetBestPhysicalPlanDescriptor(candidate_physical_plan);

  PhysicalPlan final_plan;
  switch (style_) {
    case kPrint: {
      ResultPrinter::State print_state(
          GetSchema(best_plan.plan_context_.attribute_list_), best_plan.plan,
          block_size, GetAttributeName(physical_plan.plan_context_));
      final_plan = new ResultPrinter(print_state);
      break;
    }
    case kPerformance: {
      PerformanceMonitor::State performance_state(
          GetSchema(best_plan.plan_context_.attribute_list_), best_plan.plan,
          block_size);
      final_plan = new PerformanceMonitor(performance_state);
    }
  }

  if (requirement_merged) {
    final_physical_plan_desc.cost = best_plan.cost;
    final_physical_plan_desc.plan_context_ = best_plan.plan_context_;
    final_physical_plan_desc.plan = final_plan;
  } else {
    NetworkTransfer transfer =
        current_req.requireNetworkTransfer(best_plan.plan_context_);

    if (transfer == NONE) {
      final_physical_plan_desc.cost = best_plan.cost;
      final_physical_plan_desc.plan_context_ = best_plan.plan_context_;
      final_physical_plan_desc.plan = final_plan;
    } else if ((transfer == OneToOne) || (transfer == Shuffle)) {
      /* the input PlanContext should be transfered in the network to meet the
       * requirement
       * TODO: implement OneToOne Exchange
       * */

      ExchangeMerger::State state;
      state.block_size_ = block_size;
      state.child_ = best_plan.plan;  // child_iterator;
      state.exchange_id_ =
          IDsGenerator::getInstance()->generateUniqueExchangeID();
      state.schema_ = GetSchema(best_plan.plan_context_.attribute_list_);
      std::vector<NodeID> upper_id_list;
      if (requirement.hasRequiredLocations()) {
        upper_id_list = requirement.getRequiredLocations();
      } else {
        if (requirement.hasRequiredPartitionFunction()) {
          /* partition function contains the number of partitions*/
          PartitionFunction* partitoin_function =
              requirement.getPartitionFunction();
          upper_id_list = std::vector<NodeID>(
              NodeTracker::GetInstance()->GetNodeIDList().begin(),
              NodeTracker::GetInstance()->GetNodeIDList().begin() +
                  partitoin_function->getNumberOfPartitions() - 1);
        } else {
          // TODO(wangli): decide the degree of parallelism
          upper_id_list = NodeTracker::GetInstance()->GetNodeIDList();
        }
      }

      state.upper_id_list_ = upper_id_list;

      assert(requirement.hasReuiredPartitionKey());

      state.partition_schema_ = partition_schema::set_hash_partition(
          this->GetIdInAttributeList(best_plan.plan_context_.attribute_list_,
                                     requirement.getPartitionKey()));
      assert(state.partition_schema_.partition_key_index >= 0);

      std::vector<NodeID> lower_id_list =
          GetInvolvedNodeID(best_plan.plan_context_.plan_partitioner_);

      state.lower_id_list_ = lower_id_list;

      PhysicalOperatorBase* exchange = new ExchangeMerger(state);
      best_plan.plan = exchange;
      best_plan.cost += best_plan.plan_context_.GetAggregatedDatasize();

      final_physical_plan_desc.cost = best_plan.cost;
      final_physical_plan_desc.plan_context_ = best_plan.plan_context_;
      final_physical_plan_desc.plan = exchange;
    }
  }

  if (requirement.passLimits(final_physical_plan_desc.cost))
    return true;
  else
    return false;
}
Beispiel #2
0
bool Filter::GetOptimalPhysicalPlan(Requirement requirement,PhysicalPlanDescriptor& physical_plan_descriptor, const unsigned & block_size){
	PhysicalPlanDescriptor physical_plan;
	std::vector<PhysicalPlanDescriptor> candidate_physical_plans;

	/* no requirement to the child*/
	if(child_->GetOptimalPhysicalPlan(Requirement(),physical_plan)){
		NetworkTransfer transfer=requirement.requireNetworkTransfer(physical_plan.dataflow);
		if(transfer==NONE){
			ExpandableBlockStreamFilter::State state;
			state.block_size_=block_size;
			state.child_=physical_plan.plan;
			state.qual_=qual_;
			state.colindex_=colindex_;
			state.comparator_list_=comparator_list_;
			state.v_ei_=exprArray_;
			Dataflow dataflow=getDataflow();
			state.schema_=getSchema(dataflow.attribute_list_);
			BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state);
			physical_plan.plan=filter;
			candidate_physical_plans.push_back(physical_plan);
		}
		else if((transfer==OneToOne)||(transfer==Shuffle)){
			/* the input data flow should be transfered in the network to meet the requirement
			 * TODO: implement OneToOne Exchange
			 * */
			ExpandableBlockStreamFilter::State state_f;
			state_f.block_size_=block_size;
			state_f.child_=physical_plan.plan;
			state_f.v_ei_=exprArray_;
			state_f.qual_=qual_;
			state_f.colindex_=colindex_;
			state_f.comparator_list_=comparator_list_;
			Dataflow dataflow=getDataflow();
			state_f.schema_=getSchema(dataflow.attribute_list_);
			BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state_f);
			physical_plan.plan=filter;

			physical_plan.cost+=physical_plan.dataflow.getAggregatedDatasize();

			ExpandableBlockStreamExchangeEpoll::State state;
			state.block_size_=block_size;
			state.child_=physical_plan.plan;//child_iterator;
			state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID();
			state.schema_=getSchema(physical_plan.dataflow.attribute_list_);

			std::vector<NodeID> upper_id_list;
			if(requirement.hasRequiredLocations()){
				upper_id_list=requirement.getRequiredLocations();
			}
			else{
				if(requirement.hasRequiredPartitionFunction()){
					/* partition function contains the number of partitions*/
					PartitionFunction* partitoin_function=requirement.getPartitionFunction();
					upper_id_list=std::vector<NodeID>(NodeTracker::getInstance()->getNodeIDList().begin(),NodeTracker::getInstance()->getNodeIDList().begin()+partitoin_function->getNumberOfPartitions()-1);
				}
				else{
					//TODO: decide the degree of parallelism
					upper_id_list=NodeTracker::getInstance()->getNodeIDList();
				}
			}
			state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list);

			assert(requirement.hasReuiredPartitionKey());

			state.partition_schema_=partition_schema::set_hash_partition(this->getIndexInAttributeList(physical_plan.dataflow.attribute_list_,requirement.getPartitionKey()));
			assert(state.partition_schema_.partition_key_index>=0);

			std::vector<NodeID> lower_id_list=getInvolvedNodeID(physical_plan.dataflow.property_.partitioner);

			state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list);


			BlockStreamIteratorBase* exchange=new ExpandableBlockStreamExchangeEpoll(state);

			physical_plan.plan=exchange;

		}
		candidate_physical_plans.push_back(physical_plan);
	}


	if(child_->GetOptimalPhysicalPlan(requirement,physical_plan)){
		ExpandableBlockStreamFilter::State state;
		state.block_size_=block_size;
		state.child_=physical_plan.plan;
		state.v_ei_=exprArray_;
		state.qual_=qual_;
		state.colindex_=colindex_;
		state.comparator_list_=comparator_list_;
		Dataflow dataflow=getDataflow();
		state.schema_=getSchema(dataflow.attribute_list_);
		BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state);
		physical_plan.plan=filter;
		candidate_physical_plans.push_back(physical_plan);
	}

	physical_plan_descriptor=getBestPhysicalPlanDescriptor(candidate_physical_plans);

	if(requirement.passLimits(physical_plan_descriptor.cost))
		return true;
	else
		return false;

}
Beispiel #3
0
bool LogicalFilter::GetOptimalPhysicalPlan(
    Requirement requirement, PhysicalPlanDescriptor& physical_plan_descriptor,
    const unsigned& block_size) {
  PhysicalPlanDescriptor physical_plan;
  std::vector<PhysicalPlanDescriptor> candidate_physical_plans;

  /* no requirement to the child*/
  if (child_->GetOptimalPhysicalPlan(Requirement(), physical_plan)) {
    NetworkTransfer transfer =
        requirement.requireNetworkTransfer(physical_plan.plan_context_);
    if (NONE == transfer) {
      PhysicalFilter::State state;
      state.block_size_ = block_size;
      state.child_ = physical_plan.plan;
      state.qual_ = condi_;
      state.column_id_ = column_id_;
      PlanContext plan_context = GetPlanContext();
      state.schema_ = GetSchema(plan_context.attribute_list_);
      PhysicalOperatorBase* filter = new PhysicalFilter(state);
      physical_plan.plan = filter;
      candidate_physical_plans.push_back(physical_plan);
    } else if ((OneToOne == transfer) || (Shuffle == transfer)) {
      /**
       * The input plan context should be transfered in the network to meet the
       * requirement.
       * TODO(wangli): Implement OneToOne Exchange
       * */
      PhysicalFilter::State state_f;
      state_f.block_size_ = block_size;
      state_f.child_ = physical_plan.plan;
      state_f.qual_ = condi_;
      state_f.column_id_ = column_id_;
      PlanContext plan_context = GetPlanContext();
      state_f.schema_ = GetSchema(plan_context.attribute_list_);
      PhysicalOperatorBase* filter = new PhysicalFilter(state_f);
      physical_plan.plan = filter;

      physical_plan.cost += physical_plan.plan_context_.GetAggregatedDatasize();

      ExchangeMerger::State state;
      state.block_size_ = block_size;
      state.child_ = physical_plan.plan;  // child_iterator;
      state.exchange_id_ =
          IDsGenerator::getInstance()->generateUniqueExchangeID();
      state.schema_ = GetSchema(physical_plan.plan_context_.attribute_list_);

      std::vector<NodeID> upper_id_list;
      if (requirement.hasRequiredLocations()) {
        upper_id_list = requirement.getRequiredLocations();
      } else {
        if (requirement.hasRequiredPartitionFunction()) {
          // Partition function contains the number of partitions.
          PartitionFunction* partitoin_function =
              requirement.getPartitionFunction();
          upper_id_list = std::vector<NodeID>(
              NodeTracker::GetInstance()->GetNodeIDList().begin(),
              NodeTracker::GetInstance()->GetNodeIDList().begin() +
                  partitoin_function->getNumberOfPartitions() - 1);
        } else {
          // TODO(wangli): decide the degree of parallelism
          upper_id_list = NodeTracker::GetInstance()->GetNodeIDList();
        }
      }
      state.upper_id_list_ = upper_id_list;

      assert(requirement.hasReuiredPartitionKey());

      state.partition_schema_ =
          partition_schema::set_hash_partition(this->GetIdInAttributeList(
              physical_plan.plan_context_.attribute_list_,
              requirement.getPartitionKey()));
      assert(state.partition_schema_.partition_key_index >= 0);

      std::vector<NodeID> lower_id_list =
          GetInvolvedNodeID(physical_plan.plan_context_.plan_partitioner_);

      state.lower_id_list_ = lower_id_list;

      PhysicalOperatorBase* exchange = new ExchangeMerger(state);

      physical_plan.plan = exchange;
    }
    candidate_physical_plans.push_back(physical_plan);
  }

  if (child_->GetOptimalPhysicalPlan(requirement, physical_plan)) {
    PhysicalFilter::State state;
    state.block_size_ = block_size;
    state.child_ = physical_plan.plan;
    state.column_id_ = column_id_;
    PlanContext plan_context = GetPlanContext();
    state.schema_ = GetSchema(plan_context.attribute_list_);
    PhysicalOperatorBase* filter = new PhysicalFilter(state);
    physical_plan.plan = filter;
    candidate_physical_plans.push_back(physical_plan);
  }

  physical_plan_descriptor =
      GetBestPhysicalPlanDescriptor(candidate_physical_plans);

  if (requirement.passLimits(physical_plan_descriptor.cost))
    return true;
  else
    return false;
}