コード例 #1
0
ファイル: simple_lazy_temp_seq.cpp プロジェクト: alyst/zorba
bool SimpleLazyTempSeqIter::next(store::Item_t& result)
{
  if (theCurPos < theEndPos && theTempSeq->containsItem(xs_integer(theCurPos+1)))
  {
    theTempSeq->getItem(xs_integer(++theCurPos), result);
    return true;
  }
  else
  {
    result = NULL;
    return false;
  }
}
コード例 #2
0
bool ForIterator::nextImpl(store::Item_t& aResult, PlanState& aPlanState) const 
{
  ForState* lState;
  store::Item_t lItem;
      
  DEFAULT_STACK_INIT(ForState, lState, aPlanState);

  while (consumeNext(aResult, theChild0, aPlanState)) 
  {
    while (consumeNext(lItem, theChild1, aPlanState)) 
    {
      bindVariables(lItem, theVarRefs, aPlanState);

      if (theHasPosVars) 
      {
        store::Item_t lPosItem;
        GENV_ITEMFACTORY->createInteger(lPosItem,
                                        xs_integer(lState->incReturnPosition()));
        bindVariables(lPosItem, thePosVarRefs, aPlanState);
      }
      STACK_PUSH(true, lState);
    }

    lState->resetPosition();

    theChild1->reset(aPlanState);
  }

  STACK_END(lState);
}
コード例 #3
0
ファイル: window_iterator.cpp プロジェクト: buchenberg/zorba
/***************************************************************************//**
  The theMaxNeededHistory has to be determined by the compiler e.g. for
  $seq[$startPos - 4] cases
********************************************************************************/
void WindowIterator::doGarbageCollection(WindowState* state) const
{
  if (theMaxNeededHistory != MAX_HISTORY)
  {
    if (state->theOpenWindows.empty())
    {
      if (state->theCurInputPos > theMaxNeededHistory)
        state->theDomainSeq->
        purgeUpTo(xs_integer(state->theCurInputPos - theMaxNeededHistory));
    }
    else
    {
      int64_t purgeTo =
      state->theOpenWindows.front().theStartPos - theMaxNeededHistory;

      if (purgeTo > 0)
        state->theDomainSeq->purgeUpTo(xs_integer(purgeTo));
    }
  }
}
コード例 #4
0
ファイル: window_iterator.cpp プロジェクト: buchenberg/zorba
/*******************************************************************************
  Binds the variables outside the window clause.

  @param planState The PlanState
  @param inputSeq The underlying input sequence
  @param pos The position of the current item within the input sequence
                   (counting starts with 1).
********************************************************************************/
void WindowVars::bindExtern(
    PlanState& planState,
    const store::TempSeq_t& inputSeq,
    const ulong pos) const
{
  store::Item_t item;

  if (!theCurOuterVars.empty())
  {
    inputSeq->getItem(xs_integer(pos), item);

    bindVariables(item, theCurOuterVars, planState);
  }

  if (!thePrevOuterVars.empty())
  {
    if (pos > 1)
      inputSeq->getItem(xs_integer(pos - 1), item);
    else
      item = NULL;

    bindVariables(item, thePrevOuterVars, planState);
  }

  if (!theNextOuterVars.empty())
  {
    inputSeq->getItem(xs_integer(pos + 1), item);

    bindVariables(item, theNextOuterVars, planState);
  }

  if (!thePosOuterVars.empty())
  {
    GENV_ITEMFACTORY->createInteger(item, Integer(pos));

    bindVariables(item, thePosOuterVars, planState);
  }
}
コード例 #5
0
ファイル: plan_iterator.cpp プロジェクト: cezarfx/zorba
bool PlanIterator::count(store::Item_t& result, PlanState& planState) const
{
  store::Item_t item;
  xs_integer count(0);

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  while (consumeNext(item, this, planState))
  {
    ++count;
  }

  STACK_PUSH(GENV_ITEMFACTORY->createInteger(result, xs_integer(count)), state);
  STACK_END(state);
}
コード例 #6
0
ファイル: simple_lazy_temp_seq.cpp プロジェクト: alyst/zorba
/*******************************************************************************
  Reads the whole Sequence from beginning to end; it is allowed to have several
  concurrent iterators on the same TempSeq.

  @return Iterator which iterates over the complete TempSeq
********************************************************************************/
store::Iterator_t SimpleLazyTempSeq::getIterator() const
{
  return new SimpleLazyTempSeqIter(this,
                                   xs_integer(1),
                                   xs_integer(std::numeric_limits<long>::max()));
}
コード例 #7
0
ファイル: simple_lazy_temp_seq.cpp プロジェクト: alyst/zorba
xs_integer SimpleLazyTempSeq::getSize() const
{
  ZORBA_ASSERT(false);
  return xs_integer(thePurgedUpTo + theItems.size());
}
コード例 #8
0
ファイル: window_iterator.cpp プロジェクト: buchenberg/zorba
/***************************************************************************//**

********************************************************************************/
bool WindowIterator::nextImpl(store::Item_t& aResult, PlanState& planState) const
{
  store::Iterator_t iterator;

  WindowState* state;
  DEFAULT_STACK_INIT(WindowState, state, planState);

  // Pull the next tuple from the input stream
  while (consumeNext(aResult, theTupleIter, planState))
  {
    // Create the temp sequence where to materialize the result of the domain
    // expr (lazily if theLazyEval flag is true).
    iterator = new PlanIteratorWrapper(theInputIter, planState);
    state->theDomainSeq = GENV_STORE.createTempSeq(iterator, theLazyEval);

    // Its clever to switch quite early to avoid a lot of if-else statements
    if (theWindowType == WindowIterator::SLIDING)
    {
      // Get the next item from the domain sequence
      // TODO: can the xs_integer be hoisted?
      while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
      {
        // If the current item satisfies the start condition, create a candidate
        // window starting at the current domain item.
        if (theStartClause.evaluate(planState,
                                    state->theDomainSeq,
                                    state->theCurInputPos))
        {
          state->theOpenWindows.push_back(WindowDef(state->theCurInputPos));
        }

        // For each candidate window, check if the current domain item satisfies
        // the end condition. Notice that before evaluating the end condition
        // expr, we must rebind the internal vars of the start condition, because
        // those varaibles may be refrenced in the end cond expr.
        state->theCurWindow = state->theOpenWindows.begin();

        while ( state->theCurWindow != state->theOpenWindows.end() )
        {
          if (state->theCurWindow->theEndPos == 0)
          {
            theStartClause.bindIntern(planState,
                                      state->theDomainSeq,
                                      state->theCurWindow->theStartPos);

            ulong lCurPos = state->theCurInputPos;
            if ( theEndClause.evaluate(planState,
                                       state->theDomainSeq,
                                       lCurPos))
            {
              state->theCurWindow->theEndPos = lCurPos;
            }
          }

          ++state->theCurWindow;
        }

        // Try to return closed windows to the consumer iterator. Notice that
        // windows must be sorted according to the position of their starting
        // items in the domain sequence. So, we can return a closed window only
        // if it appears as the first window in state->theOpenWindows.
        state->theCurWindow = state->theOpenWindows.begin();

        while (!state->theOpenWindows.empty())
        {
          if (state->theCurWindow->theEndPos != 0)
          {
            // The current window is closed and its starting item is before the
            // stating items of all other windows (open or closed) in the domain
            // sequence. So, (a) bind the window var and the external vars of 
            // the start and end conditions, (b) remove the window from the set
            // of candidate windows, (c) purge from the domain temp seq any item
            // that we know for sure they will not be needed in subsequent 
            // evaluations of the start and/or end conditions, and (d) return to
            // the caller a new tuple that consists of the current input tuple
            // augmented with one column per variable that was bound in this step.
            theStartClause.bindExtern(planState,
                                      state->theDomainSeq,
                                      state->theCurWindow->theStartPos);

            theEndClause.bindExtern(planState,
                                    state->theDomainSeq,
                                    state->theCurWindow->theEndPos);

            bindVariable(planState,
                         state->theDomainSeq,
                         state->theCurWindow->theStartPos,
                         state->theCurWindow->theEndPos);

            state->theCurWindow = state->theOpenWindows.erase(state->theCurWindow);

            //doGarbageCollection(state);

            if (theTreatIter)
            {
              store::Item_t tmp;
              while (consumeNext(tmp, theTreatIter, planState))
              {
                ;
              }

              theTreatIter->reset(planState);
            }

            STACK_PUSH(true, state);
          }
          else
          {
            break;
          }
        }

        ++state->theCurInputPos;
      }
    }
    else //Tumpling window
    {
      // Doing this switch now also avoids further overhad
      if (theEndClause.theHasEndClause)
      {
        while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
        {
          if (state->theOpenWindows.empty() &&
              theStartClause.evaluate(planState,
                                      state->theDomainSeq,
                                      state->theCurInputPos))
          {
            theStartClause.bindExtern(planState,
                                      state->theDomainSeq,
                                      state->theCurInputPos);

            state->theOpenWindows.push_back(state->theCurInputPos);
          }

          if ( !state->theOpenWindows.empty() &&
               theEndClause.evaluate(planState,
                                     state->theDomainSeq,
                                     state->theCurInputPos))
          {
            theEndClause.bindExtern(planState,
                                    state->theDomainSeq,
                                    state->theCurInputPos);

            bindVariable(planState,
                         state->theDomainSeq,
                         state->theOpenWindows[0].theStartPos,
                         state->theCurInputPos);

            state->theOpenWindows.pop_back();

            assert(state->theOpenWindows.empty());

            if (theTreatIter)
            {
              store::Item_t tmp;
              while (consumeNext(tmp, theTreatIter, planState))
              {
                ;
              }

              theTreatIter->reset(planState);
            }

            STACK_PUSH(true, state);

            doGarbageCollection(state);
          }

          ++state->theCurInputPos;
        }
      }
      else
      {
        while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
        {
          if (theStartClause.evaluate(planState,
                                      state->theDomainSeq,
                                      state->theCurInputPos))
          {
            if (!state->theOpenWindows.empty())
            {
              //In no case there should be more than 1 position inside
              assert(state->theOpenWindows.size() == 1);

              theStartClause.bindExtern(planState,
                                        state->theDomainSeq,
                                        state->theOpenWindows[0].theStartPos);

              bindVariable(planState,
                           state->theDomainSeq,
                           state->theOpenWindows[0].theStartPos,
                           state->theCurInputPos  - 1);

              state->theOpenWindows.pop_back();

              assert(state->theOpenWindows.empty());

              if (theTreatIter)
              {
                store::Item_t tmp;
                while (consumeNext(tmp, theTreatIter, planState))
                {
                  ;
                }

                theTreatIter->reset(planState);
              }

              STACK_PUSH(true, state);

              --state->theCurInputPos;
              doGarbageCollection(state);
              ++state->theCurInputPos;
            }

            state->theOpenWindows.push_back(state->theCurInputPos);
          }

          ++state->theCurInputPos;
        }
      }
    }

    // Check if we have open and/or closed windows
    state->theCurWindow = state->theOpenWindows.begin();

    while (state->theCurWindow != state->theOpenWindows.end())
    {
      if (!theEndClause.theOnlyEnd || state->theCurWindow->theEndPos != 0)
      {
        if (state->theCurWindow->theEndPos == 0)
          state->theCurWindow->theEndPos = state->theCurInputPos - 1;

        bindVariable(planState,
                     state->theDomainSeq,
                     state->theOpenWindows[0].theStartPos,
                     state->theCurWindow->theEndPos);

        theStartClause.bindExtern(planState,
                                  state->theDomainSeq,
                                  state->theOpenWindows[0].theStartPos);

        theEndClause.bindExtern(planState,
                                state->theDomainSeq,
                                state->theCurWindow->theEndPos);

        state->theCurWindow = state->theOpenWindows.erase(state->theCurWindow);

        if (theTreatIter)
        {
          store::Item_t tmp;
          while (consumeNext(tmp, theTreatIter, planState))
          {
            ;
          }

          theTreatIter->reset(planState);
        }

        STACK_PUSH(true, state);
      }
      else
      {
        ++state->theCurWindow;
      }
    }

    theInputIter->reset(planState);
    state->reset(planState);
  }

  STACK_PUSH(false, state);
  STACK_END(state);
}