MediaSet::MediaSet() { terminated = false; workers = std::shared_ptr<WorkerPool> (new WorkerPool ( MEDIASET_THREADS_DEFAULT) ); thread = std::thread ( [&] () { std::unique_lock <std::recursive_mutex> lock (recMutex); while (!terminated && waitCond.wait_for (lock, collectorInterval) == std::cv_status::timeout) { if (terminated) { return; } try { doGarbageCollection(); } catch (...) { GST_ERROR ("Error during garbage collection"); } } }); }
/***************************************************************************//** ********************************************************************************/ 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); }