Example #1
0
File: main.cpp Project: CCJY/coliru
 // this 
 inline void scheduler_loop() {
     std::unique_ptr<Priority> pCurrentPrty;
     for (;;) {
         std::unique_lock<std::mutex> lock(queue_mutex);
         // wait for some task to get queued or for the atomic 
         // isActive flag to become inactive
         condition.wait(lock, [this, &pCurrentPrty] {
             if (!mTasks.empty() && 
                 pCurrentPrty && pCurrentPrty->getPriorityStr() != 
                 mTasks.top().getPriority().getPriorityStr() && 
                 pCurrentPrty->getPriorityStr().length() != 
                 mTasks.top().getPriority().getPriorityStr().length()) {
                 std::cout << "priority change" << std::endl;
             }
             return (!mTasks.empty() || !isActive.load());
         });
         // only exit when no more tasks on the queue
         if (!isActive.load() && mTasks.empty()) {
             return;
         }
         // update the top priority job that is currently running
         pCurrentPrty = std::make_unique<Priority>(mTasks.top().getPriority());
         // move next task off the priority queue
         auto nextTask(std::move(mTasks.top()));
         pCurrentPrty = std::make_unique<Priority>(nextTask.getPriority());
         // queue housekeeping
         mTasks.pop();
         // release the lock allowing new entries to be queued
         lock.unlock();
         // execute the task forwarding stored arguments with the call
         // this is the magic that works inside a thread pool
         // _Ret operator()(_Types... _Args) const 
         nextTask();
     }
 }
int main() {
    scanf("%d %d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d %d %d", &a, &b, &t);
        adj[a].push_back(std::make_pair(b, t));
        adj[b].push_back(std::make_pair(a, t));
    }
    
    dist[0] = 0;
    q.push(std::make_pair(0, 0));
    for (int i = 1; i < n; i++) {
        dist[i] = 0x3f3f3f3f;
        q.push(std::make_pair(-dist[i], i));
    }
    
    while (!q.empty()) {
        std::tie(cur_dist, cur_index) = q.top(); q.pop();
        cur_dist *= -1;
        vis[cur_index] = 1;
        for (std::pair<int, int> p : adj[cur_index]) {
            if (!vis[p.first]) {
                const int alt = cur_dist + p.second;
                if (alt < dist[p.first]) {
                    dist[p.first] = alt;
                    q.push(std::make_pair(-alt, p.first));
                }
            }
        }
    }

    dist2[0] = 0;
    q.push(std::make_pair(0, n - 1));
    for (int i = 0; i < n - 1; i++) {
        dist2[i] = 0x3f3f3f3f;
        q.push(std::make_pair(-dist2[i], i));
    }

    while (!q.empty()) {
        std::tie(cur_dist, cur_index) = q.top(); q.pop();
        cur_dist *= -1;
        vis2[cur_index] = 1;
        for (std::pair<int, int> p : adj[cur_index]) {
            if (!vis2[p.first]) {
                const int alt = cur_dist + p.second;
                if (alt < dist2[p.first]) {
                    dist2[p.first] = alt;
                    q.push(std::make_pair(-alt, p.first));
                }
            }
        }
    }
    
    for (int i = 0; i < n; i++) {
        ans = std::max(ans, dist[i] + dist2[i]);
    }
    printf("%d\n", ans);
}
// preferences should be a member
wns::scheduler::ConnectionID
ProportionalFair::getNextConnection(SchedulerStatePtr schedulerState,
                                    std::priority_queue<UserPreference> preferences)
{
    wns::scheduler::ConnectionID next = -1;

    while (!preferences.empty())
    {
        int priority = schedulerState->currentState->getCurrentPriority();
        const float preference = preferences.top().first;
        const UserID user = preferences.top().second;
        MESSAGE_SINGLE(NORMAL, logger, "Selected user="******"Selected connection with CID="<<next);
            return next;
        }
        preferences.pop();
    }
    return next;
}
Example #4
0
void DifferenceCut::rankImages (std::vector<RowSpan>& spans, std::priority_queue<Ranker>& ordered) {
  assert(ordered.empty());
  float score, dist;
  const unsigned char *Itest, *Iavoid;
  Vec3i Vtest, Vavoid;
  int x, y, index;

  for (unsigned int i=0; i<_images.size(); ++i) {
    score = 0;
    ImageAbs* im = _images[i];
    for (unsigned int j=0; j<spans.size(); ++j) {
      x = spans[j]._x; y = spans[j]._y;
      for (int s=0; s<spans[j]._num; ++s) {
	index = y*_w + x + s;
	Itest = im->data(x+s,y);
	Iavoid = _imptr(_labels[index], Coord(x+s,y));
	Vtest.Set(Itest[0], Itest[1], Itest[2]);
	Vavoid.Set(Iavoid[0], Iavoid[1], Iavoid[2]);
	dist = sqrt(Vtest.distanceTo2(Vavoid));
	//printf("%f\n",dist);
	if (dist > 25)
	  score += 25.;
	else
	  score += dist;
      }
    }
    printf("Image %d, score %f\n",i, score);
    ordered.push(Ranker(i,score));
  }
}
Example #5
0
int main(void)
{
	scanf("%u %u", &words, &maxLength);
	for(unsigned int w = 0; w < words; ++ w)
	{
		scanf("%s", word);
		sWord[w] = std::string(word);
		que.push(sWord[w]);
	}

	while(!que.empty() && que.top().length() <= maxLength)
	{
		act = que.top();
		que.pop();
		if(isPalindrome(act))
		{
			++ result;
			if(result == 835454957)
				result = 0;
		}

		for(unsigned int w = 0; w < words; ++ w)
			que.push(act + " " + sWord[w]);
	}

	printf("%u\n", result);


	return 0;
}
Example #6
0
PLUGIN_EXPORT int PLUGIN_CALL
	AmxUnload(AMX * amx) 
{
	std::priority_queue<struct timer_s *, std::deque<struct timer_s *>, TimerCompare>
		cleaned;
	// Destroy all the timers for this mode.
	while (!gTimers.empty())
	{
		struct timer_s *
			next = gTimers.top();
		gTimers.pop();
		if (next->amx == amx)
		{
			// Ending, remove from the map also.
			gHandles.erase(next->id);
		}
		else
		{
			// Not ending, leave it be.
			cleaned.push(next);
		}
	}
	gTimers = cleaned;
	for (int i = 0; i != 17; ++i)
	{
		if (gAMXFiles[i] == amx)
		{
			gAMXFiles[i] = 0;
			break;
		}
	}
	return AMX_ERR_NONE;
}
			/**
			 * decode next alignment
			 *
			 * @param algn reference to alignment object to be filled
			 * @return true iff next alignment could be read, false when no more alignments are available
			 **/
			bool readAlignment(libmaus::bambam::BamAlignment & algn)
			{
				if ( Q.empty() )
					return false;
				
				uint64_t const t = Q.top();
				Q.pop();
				
				libmaus::bambam::BamAlignment::D_array_type T = algn.D;
				
				algn.D = data[t].D;
				algn.blocksize = data[t].blocksize;
				
				data[t].D = T;
				data[t].blocksize = 0;
				
				if ( index[t].second-- )
				{
					#if !defined(NDEBUG)
					bool const alok = 
					#endif
					        libmaus::bambam::BamDecoder::readAlignmentGz(*(streams[t]),data[t],0,false);
					        
					#if !defined(NDEBUG)
					assert ( alok );
					#endif
					
					Q.push(t);
				}
					
				return true;
			}
Example #8
0
void dijkstra() {
	std::fill(d + 1, d + n + 1, INF);
	for (int i = 1; i <= n; i++) {
		if (!w[i]) continue;
		heap.push((Heapnode){d[i] = 0, i});
	}
	while (!heap.empty()) {
		Heapnode top = heap.top(); heap.pop();
		if (v[top.node]) continue;
		v[top.node] = true;
		for (int i = h[top.node]; i; i = e[i].next)
			if (!v[e[i].node] && d[e[i].node] > top.dist + e[i].dist) {
				d[e[i].node] = top.dist + e[i].dist;
				p[e[i].node] = top.node;
				heap.push((Heapnode){d[e[i].node], e[i].node});
			}
	}
	s = 0;
	for (int i = 1, cnt = 0; i <= n; i++) {
		if (!w[i]) continue;
		c[i] = ++s;
	}
	for (int i = 1; i <= n; i++) {
		if (w[i]) continue;
		fa[getfa(i)] = getfa(p[i]);
	}
	for (int i = 1; i <= n; i++) {
		if (w[i]) continue;
		c[i] = c[getfa(i)];
	}
}
Example #9
0
	Node::Ptr pop() {
		if (queue.empty())
			return Node::Ptr();
		Node::Ptr result = queue.top();
		queue.pop();
		return result;
	}
Example #10
0
int main() {
	freopen("F.in", "r", stdin);
	while (scanf("%d%d", &n, &m) == 2 && n && m) {
		for (int i = 1; i <= n; i++) {
			scanf("%s", map[i] + 1);
		}
		scanf("%d%d", &sx, &sy);
		scanf("%d%d", &ex, &ey);
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++) {
				v[i][j] = false;
				d[i][j] = INF;
			}
		heap.push(std::make_pair(d[sx][sy] = 0, std::make_pair(sx, sy)));
		while (!heap.empty()) {
			std::pair<int, std::pair<int, int> > top = heap.top(); heap.pop();
			if (v[top.second.first][top.second.second]) continue;
			v[top.second.first][top.second.second] = true;
			for (int dir = 0; dir < 4; dir++) {
				int nx = top.second.first + dx[dir];
				int ny = top.second.second + dy[dir];
				if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
				int cost = map[nx][ny] == '.';
				if (!v[nx][ny] && d[nx][ny] > d[top.second.first][top.second.second] + cost) {
					d[nx][ny] = d[top.second.first][top.second.second] + cost;
					heap.push(std::make_pair(d[nx][ny], std::make_pair(nx, ny)));
				}
			}
		}
		printf("%d\n", d[ex][ey]);
	}
	return 0;
}
Example #11
0
	Node::Ptr peek() const
	{
		if (queue.empty())
			return Node::Ptr();
		Node::Ptr result = queue.top();
		return result;
	}
Example #12
0
 void operator<<(std::priority_queue<_Tp,Range,Compare> lhs)
 {
         for(;!lhs.empty();){
                 std::cout<<lhs.top()<<token;
                 lhs.pop();
         }
         std::cout<<last_token<<std::flush;
 }
//Maintains the size of the priority queue at the specified size with each push
//For now this function is for priority queue that is in ascending order, top is smallest.
void pushPriorityQueueBounded(std::priority_queue<int, std::vector<int>, std::greater<int> >  &pq,
                              int newElement, unsigned long priorityQueueBound)
{
   if(pq.empty() || newElement > pq.top())
      pq.push(newElement);
   if(pq.size() > priorityQueueBound)
      pq.pop();
}
int main(){
	int n;
	while(scanf("%d",&n)!=EOF){
		int i;
		int flag1=1,flag2=1,flag3=1;
		while(!ty1.empty())ty1.pop();
		while(!ty2.empty())ty2.pop();
		while(!ty3.empty())ty3.pop();
		int order,x;
		for(i=1;i<=n;i++){
			scanf("%d%d",&order,&x);
			if(order==1){
				ty3.push(x);
				ty2.push(x);
				ty1.push(x);
				}
			else {
				if(flag3&&!ty3.empty()){
					if(ty3.top()==x)ty3.pop();
					else flag3=0;
					}
				else flag3=0;
				
				if(flag2&&!ty2.empty()){
					if(ty2.top()==x)ty2.pop();
					else flag2=0;
					}
				else flag2=0;
				
				if(flag1&&!ty1.empty()){
					if(ty1.front()==x)ty1.pop();
					else flag1=0;
					}
				else flag1=0;
				}
			}
		int sum=flag1+flag2+flag3;
		if(sum>=2)printf("not sure\n");
		else if(sum==0)printf("impossible\n");
		else if(flag1)printf("queue\n");
		else if(flag2)printf("priority queue\n");
		else printf("stack\n"); 
		}
	return 0;
	}
Example #15
0
double NextTime()
{
    //std::lock_guard<std::mutex> lock(MUTEX);
    if( QUEUE.empty() ) {
        return 0;
    } else {
        return QUEUE.top();
    }
}
Example #16
0
    bool do_search(const TMap& map, const TCoords& start_p, const TCoords& finish_p)
    {
        static struct { int x, y, d; } dirs[] =
        { { -1, -1, 14 },{ 0, -1, 10 },{ 1, -1, 14 },{ -1, 0, 10 },{ 1, 0, 10 },{ -1, 1, 14 },{ 0, 1, 10 },{ 1, 1, 14 } };
        memset(attrs, 0, sizeof(Attributes) * H * W);
        while (!opened.empty()) opened.pop();

        AttrsPtr current = opened_push(start_p, cost_estimate(start_p, finish_p));
        while (!opened.empty())
        {
            current = opened_pop();
            if (current.pos.x == finish_p.x && current.pos.y == finish_p.y)
                return true;
            for (int i = 0; i < 8; ++i)
            {
                int dx = dirs[i].x;
                int dy = dirs[i].y;
                TCoords npos;
                npos.x = current.pos.x + dx;
                npos.y = current.pos.y + dy;
                if (!inbound(npos.x, npos.y) || map.isobstacle(npos.x, npos.y))
                    continue;
                size_t ni = index2d(npos.x, npos.y);
                if (attrs[ni].state == st_Closed)
                    continue;
                TWeight t_gscore = current.pa->gscore + dirs[i].d;
                if (attrs[ni].state == st_Wild)
                {
                    opened_push(npos, t_gscore + cost_estimate(npos, finish_p));
                }
                else
                {
                    if (t_gscore >= attrs[ni].gscore)
                        continue;
                    rearrange(&attrs[ni], t_gscore + cost_estimate(npos, finish_p));
                }
                attrs[ni].ofsx = dx;
                attrs[ni].ofsy = dy;
                attrs[ni].gscore = t_gscore;
            }
        }
        return false;
    }
Example #17
0
void simulation::run () {

    while (! eventQueue.empty ()) {

        event * nextEvent = eventQueue.top ();
        eventQueue.pop ();
        time = nextEvent->time;
        nextEvent->processEvent ();
        delete nextEvent;
    }
}
Example #18
0
// Output the Queue
void display(std::priority_queue<Node>& q){ // reverse
  std::vector<Node> v;
  v.reserve(K);
  while (!q.empty()){  
    v.push_back(q.top());
    q.pop();  
  } 
  for(int i=K;i>0;i--){
    PrintfNode(v[i-1]);
  }
}
Example #19
0
int main(){
	int n;
	while(scanf("%d",&n)!=EOF&&n){
		while(!L.empty())L.pop();
		int i,res=0,t;
		num x,y;
		for(i=1;i<=n;i++){
			scanf("%d",&t);
			L.push( (num){t} );
			}
		while(L.size()>1){
			x=L.top();L.pop();
			y=L.top();L.pop();
			res+=x.x+y.x;
			if(L.empty())break;
			L.push( (num){x.x+y.x} );
			}
		printf("%d\n",res);
		}
	return 0;
	}
Example #20
0
//init Data
void InitData(){

  ruled_waypoint.waypoints.clear();
  plan_path.poses.clear();
  plan_poses.poses.clear();
  closelist.clear();
  map.clear();
  Astar_count = 0;

  while (!openlist.empty()){
    openlist.pop();
  }

}
Example #21
0
void Cleanup(std::priority_queue<Board*, std::vector<Board*>,
    QueueCompareClass> &pq, std::vector<Board*> to_delete) {

    for (unsigned int i = 0; i < to_delete.size(); ++i) {
        delete to_delete[i];
        to_delete[i] = NULL;
    }

    while (!pq.empty()) {
        Board* board = pq.top();
        pq.pop();
        delete board;
        board = NULL;
    }
}
	virtual void workerfun() {
		unique_lock<mutex> lock(m);
		while(running){
			cv.wait(lock, [this]{return !workqueue.empty() || !delayworkqueue.empty() || !running;});

			if(!workqueue.empty()){
				shared_ptr<RunItem> runItem(workqueue.front());
				workqueue.pop_front();
				lock.unlock();
				if(!runItem->mCanceled) {
					(*runItem.get())();
				}
				lock.lock();
			}
			if(!delayworkqueue.empty()){
				shared_ptr<RunItem> runItem = delayworkqueue.top();
				const chrono::time_point<chrono::steady_clock> runAt = runItem->runAt();
				if(chrono::steady_clock::now() >= runAt){
					delayworkqueue.pop();
					lock.unlock();
					if(!runItem->mCanceled){
						(*runItem.get())();
					}
					lock.lock();

					if(runItem->mRepeat && !runItem->mCanceled){
						runItem->mCreateTime = chrono::steady_clock::now();
						delayworkqueue.push(runItem);
					}

				} else if(workqueue.empty()) {
					cv.wait_until(lock, runAt);
				}
			}
		}
	}
 void runTasks(){
     while(!scheduleList.empty()){
         auto t = scheduleList.top();
         scheduleList.pop();
         MillisecondsTime currentTime = std::chrono::duration_cast<MillisecondsTime>(std::chrono::system_clock::now().time_since_epoch());
         // pthread_t task_thread;
         // int pid = pthread_create(&task_thread, NULL, t.second->doTask(), (void *)i);
         // std::thread tt(&Scheduler::threadRunTask, t.second);
         if(currentTime >= t.first)
             t.second->doTask();
         else{
             MillisecondsTime waitTime = t.first - currentTime;
             std::this_thread::sleep_for(waitTime);
             std::cout << "wait time: " << waitTime.count() << std::endl;
             t.second->doTask();
         }
     }
 }
Example #24
0
void AddToHeaps(std::priority_queue<double, std::vector<double>, std::greater<double> >& m,
		std::priority_queue<double>& M, double x){

	// decide on initial heap to place element into
	if(m.empty() || x < m.top())
		M.push(x);
	else
		m.push(x);
	// make sure that heaps are balanced
	if(m.size() > M.size() + 1){
		M.push( m.top() );
		m.pop();	
	}
	else if(M.size() > m.size() + 1){
		m.push( M.top() );
		M.pop();
	}
}
Example #25
0
			CheckOverlapResult::shared_ptr_type get()
			{
				if ( heap.empty() )
					return CheckOverlapResult::shared_ptr_type();
			
				std::pair<uint64_t,CheckOverlapResult::shared_ptr_type> top = heap.top();
				heap.pop();
				
				CheckOverlapResult::shared_ptr_type newptr = in[top.first]->get();
				
				if ( newptr )
				{
					heap.push ( 
						std::pair<uint64_t,CheckOverlapResult::shared_ptr_type>(top.first,newptr) 
					);
				
				}
		
				return top.second;
			}
int FillGasSolverXXX::solve(int* gas, int gas_len, int* distance, int distance_len, std::priority_queue<int> gasStations, int fuelmeter, int position)
{
    // 1. 走れるだけ走る
    position += fuelmeter;
    fuelmeter = 0;
    // 2. ゴールに到着すれば終了する
    if(position >= this->goal_distance) return 0;
    // 3. 途中でガソリンスタンドを通過したら、ガソリン量をpriority_queueにpushする
    int i;
    for(i = 0; i < gas_len; ++i)
    {
        if(distance[i] > position) break;
        gasStations.push(gas[i]);
    }
    // 4. ガソリンが切れたら、queueからpopして、1へ
    if(gasStations.empty()) return 65535;
    fuelmeter += gasStations.top();
    gasStations.pop();
    return 1 + this->solve(gas + i, gas_len - i, distance + i, distance_len - i, gasStations, fuelmeter, position);
}
Block MergeSortingBlocksBlockInputStream::mergeImpl(std::priority_queue<TSortCursor> & queue)
{
    size_t num_columns = blocks[0].columns();

    MutableColumns merged_columns = blocks[0].cloneEmptyColumns();
    /// TODO: reserve (in each column)

    /// Take rows from queue in right order and push to 'merged'.
    size_t merged_rows = 0;
    while (!queue.empty())
    {
        TSortCursor current = queue.top();
        queue.pop();

        for (size_t i = 0; i < num_columns; ++i)
            merged_columns[i]->insertFrom(*current->all_columns[i], current->pos);

        if (!current->isLast())
        {
            current->next();
            queue.push(current);
        }

        ++total_merged_rows;
        if (limit && total_merged_rows == limit)
        {
            auto res = blocks[0].cloneWithColumns(std::move(merged_columns));
            blocks.clear();
            return res;
        }

        ++merged_rows;
        if (merged_rows == max_merged_block_size)
            return blocks[0].cloneWithColumns(std::move(merged_columns));
    }

    if (merged_rows == 0)
        return {};

    return blocks[0].cloneWithColumns(std::move(merged_columns));
}
Example #28
0
void AI::publishThreeComponentRHL(std::priority_queue < std::pair<double, cv::Point2d>, 
    std::vector<std::pair<double, cv::Point2d> >, 
    AI::CompareComponentsWithDeviation> largestThreeComponentQueue) {
    
    //create message
    robia::points_tuple message;
    
    if (largestThreeComponentQueue.size() != 3) {
      // Left Hand, Head, Right hand
      message.Rx = -1;
      message.Ry = -1;
      message.Hx = -1;
      message.Hy = -1;
      message.Lx = -1;
      message.Ly = -1;
    } else {    
      std::vector<cv::Point2d> largestThreeComponentVector;

      while(!largestThreeComponentQueue.empty()) {
        largestThreeComponentVector.push_back(largestThreeComponentQueue.top().second);
        largestThreeComponentQueue.pop();
      }

      std::sort(largestThreeComponentVector.begin(), largestThreeComponentVector.end(), comparePointsWithRespectToX);

      // Left Hand, Head, Right hand
      message.Rx = largestThreeComponentVector[0].x/LengthOfCamera;
      message.Ry = largestThreeComponentVector[0].y/HeightOfCamera;
      message.Hx = largestThreeComponentVector[1].x/LengthOfCamera;
      message.Hy = largestThreeComponentVector[1].y/HeightOfCamera;
      message.Lx = largestThreeComponentVector[2].x/LengthOfCamera;
      message.Ly = largestThreeComponentVector[2].y/HeightOfCamera;
    }

    // Publish three points to ROSTopic 
    pubThreePointsPositions.publish(message);

  }
Example #29
0
int main(void)
{
    scanf("%d", &asteroids);
    for(int a = 0; a < asteroids; ++ a)
    {
        scanf("%d %d", &time, &shot);
        shield += time - prev;

        hit.push(shot);
        while(!hit.empty() && shield < shot)
        {
            shield += hit.top();
            hit.pop();
            ++ result;
        }

        shield -= shot;
        prev = time;
    }

    printf("%d\n", result);
    return 0;
}
void MergingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
{
	size_t merged_rows = 0;

	/** Увеличить счётчики строк.
	  * Вернуть true, если пора закончить формировать текущий блок данных.
	  */
	auto count_row_and_check_limit = [&, this]()
	{
		++total_merged_rows;
		if (limit && total_merged_rows == limit)
		{
	//		std::cerr << "Limit reached\n";
			cancel();
			finished = true;
			return true;
		}

		++merged_rows;
		if (merged_rows == max_block_size)
		{
	//		std::cerr << "max_block_size reached\n";
			return true;
		}

		return false;
	};

	/// Вынимаем строки в нужном порядке и кладём в merged_block, пока строк не больше max_block_size
	while (!queue.empty())
	{
		TSortCursor current = queue.top();
		queue.pop();

		while (true)
		{
			/** А вдруг для текущего курсора блок целиком меньше или равен, чем остальные?
			  * Или в очереди остался только один источник данных? Тогда можно целиком взять блок текущего курсора.
			  */
			if (current.impl->isFirst() && (queue.empty() || current.totallyLessOrEquals(queue.top())))
			{
	//			std::cerr << "current block is totally less or equals\n";

				/// Если в текущем блоке уже есть данные, то сначала вернём его. Мы попадём сюда снова при следующем вызове функции merge.
				if (merged_rows != 0)
				{
	//				std::cerr << "merged rows is non-zero\n";
					queue.push(current);
					return;
				}

				size_t source_num = 0;
				size_t size = cursors.size();
				for (; source_num < size; ++source_num)
					if (&cursors[source_num] == current.impl)
						break;

				if (source_num == size)
					throw Exception("Logical error in MergingSortedBlockInputStream", ErrorCodes::LOGICAL_ERROR);

				for (size_t i = 0; i < num_columns; ++i)
					merged_block.unsafeGetByPosition(i).column = source_blocks[source_num]->unsafeGetByPosition(i).column;

	//			std::cerr << "copied columns\n";

				size_t merged_rows = merged_block.rows();

				if (limit && total_merged_rows + merged_rows > limit)
				{
					merged_rows = limit - total_merged_rows;
					for (size_t i = 0; i < num_columns; ++i)
					{
						auto & column = merged_block.unsafeGetByPosition(i).column;
						column = column->cut(0, merged_rows);
					}

					cancel();
					finished = true;
				}

	//			std::cerr << "fetching next block\n";

				total_merged_rows += merged_rows;
				fetchNextBlock(current, queue);
				return;
			}

	//		std::cerr << "total_merged_rows: " << total_merged_rows << ", merged_rows: " << merged_rows << "\n";
	//		std::cerr << "Inserting row\n";
			for (size_t i = 0; i < num_columns; ++i)
				merged_columns[i]->insertFrom(*current->all_columns[i], current->pos);

			if (!current->isLast())
			{
	//			std::cerr << "moving to next row\n";
				current->next();

				if (queue.empty() || !(current.greater(queue.top())))
				{
					if (count_row_and_check_limit())
					{
	//					std::cerr << "pushing back to queue\n";
						queue.push(current);
						return;
					}

					/// Не кладём курсор обратно в очередь, а продолжаем работать с текущим курсором.
	//				std::cerr << "current is still on top, using current row\n";
					continue;
				}
				else
				{
	//				std::cerr << "next row is not least, pushing back to queue\n";
					queue.push(current);
				}
			}
			else
			{
				/// Достаём из соответствующего источника следующий блок, если есть.
	//			std::cerr << "It was last row, fetching next block\n";
				fetchNextBlock(current, queue);
			}

			break;
		}

		if (count_row_and_check_limit())
			return;
	}

	cancel();
	finished = true;
}