Example #1
0
void OperatorDelete::pushBuffers(OperationPlan* o, bool consuming)
{
    // Loop over all flowplans
    for (OperationPlan::FlowPlanIterator i = o->beginFlowPlans(); i != o->endFlowPlans(); ++i)
    {
        // Skip flowplans we're not interested in
        if ((consuming && i->getQuantity() >= 0)
                || (!consuming && i->getQuantity() <= 0))
            continue;

        // Check if the buffer is already found on the stack
        bool found = false;
        for (vector<Buffer*>::const_reverse_iterator j = buffersToScan.rbegin();
                j != buffersToScan.rend(); ++j)
        {
            if (*j == i->getBuffer())
            {
                found = true;
                break;
            }
        }

        // Add the buffer to the stack
        if (!found) buffersToScan.push_back(const_cast<Buffer*>(i->getBuffer()));
    }

    // Recursive call for all suboperationplans
    for (OperationPlan::iterator subopplan(o); subopplan != OperationPlan::end(); ++subopplan)
        pushBuffers(&*subopplan, consuming);
}
Example #2
0
void PeggingIterator::followPegging
(const OperationPlan* op, double qty, double offset, short lvl)
{
    // Zero quantity operationplans don't have further pegging
    if (!op->getQuantity()) return;

    // For each flowplan ask the buffer to find the pegged operationplans.
    if (downstream)
        for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
                i != op->endFlowPlans(); ++i)
        {
            if (i->getQuantity() > ROUNDING_ERROR) // Producing flowplan
                i->getFlow()->getBuffer()->followPegging(*this, &*i, qty, offset, lvl+1);
        }
    else
        for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
                i != op->endFlowPlans(); ++i)
        {
            if (i->getQuantity() < -ROUNDING_ERROR) // Consuming flowplan
                i->getFlow()->getBuffer()->followPegging(*this, &*i, qty, offset, lvl+1);
        }

    // Push child operationplans on the stack.
    // The pegged quantity is equal to the ratio of the quantities of the
    // parent and child operationplan.
    for (OperationPlan::iterator j(op); j != OperationPlan::end(); ++j)
        updateStack(
            &*j,
            qty * j->getQuantity() / op->getQuantity(),
            offset * j->getQuantity() / op->getQuantity(),
            lvl+1
        );
}
Example #3
0
DECLARE_EXPORT Flow::~Flow()
{
  // Set a flag to make sure the level computation is triggered again
  HasLevel::triggerLazyRecomputation();

  // Delete existing flowplans
  if (getOperation() && getBuffer())
  {
    // Loop over operationplans
    for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i)
      // Loop over flowplans
      for(OperationPlan::FlowPlanIterator j = i->beginFlowPlans(); j != i->endFlowPlans(); )
        if (j->getFlow() == this) j.deleteFlowPlan();
        else ++j;
  }

  // Delete the flow from the operation and the buffer
  if (getOperation())
    getOperation()->flowdata.erase(this);
  if (getBuffer())
    getBuffer()->flows.erase(this);
}
Example #4
0
DECLARE_EXPORT Flow::~Flow()
{
  // Set a flag to make sure the level computation is triggered again
  HasLevel::triggerLazyRecomputation();

  // Delete existing flowplans
  if (getOperation() && getBuffer())
  {
    // Loop over operationplans
    for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i)
      // Loop over flowplans
      for(OperationPlan::FlowPlanIterator j = i->beginFlowPlans(); j != i->endFlowPlans(); )
        if (j->getFlow() == this) j.deleteFlowPlan();
        else ++j;
  }

  // Delete the flow from the operation and the buffer
  if (getOperation())
    getOperation()->flowdata.erase(this);
  if (getBuffer())
    getBuffer()->flows.erase(this);

  // Clean up alternate flows
  if (hasAlts)
  {
    // The flow has alternates.
    // Make a new flow the leading one. Or if there is only one alternate
    // present it is not marked as an alternate any more.
    unsigned short cnt = 0;
    int minprio = INT_MAX;
    Flow* newLeader = NULL;
    for (Operation::flowlist::iterator i = getOperation()->flowdata.begin();
        i != getOperation()->flowdata.end(); ++i)
      if (i->altFlow == this)
      {
        cnt++;
        if (i->priority < minprio)
        {
          newLeader = &*i;
          minprio = i->priority;
        }
      }
    if (cnt < 1)
      throw LogicException("Alternate flows update failure");
    else if (cnt == 1)
      // No longer an alternate any more
      newLeader->altFlow = NULL;
    else
    {
      // Mark a new leader flow
      newLeader->hasAlts = true;
      newLeader->altFlow = NULL;
      for (Operation::flowlist::iterator i = getOperation()->flowdata.begin();
          i != getOperation()->flowdata.end(); ++i)
        if (i->altFlow == this) i->altFlow = newLeader;
    }
  }
  if (altFlow)
  {
    // The flow is an alternate of another one.
    // If it was the only alternate, then the hasAlts flag on the parent
    // flow needs to be set back to false
    bool only_one = true;
    for (Operation::flowlist::iterator i = getOperation()->flowdata.begin();
        i != getOperation()->flowdata.end(); ++i)
      if (i->altFlow == altFlow)
      {
        only_one = false;
        break;
      }
    if (only_one) altFlow->hasAlts = false;
  }
}