示例#1
0
BidirectionalIterator
test_some(BidirectionalIterator first, BidirectionalIterator last)
{
  BidirectionalIterator current = first;
  BidirectionalIterator start_of_completed = last;
  while (current != start_of_completed) {
    // Check if we have found a completed request.
    if (optional<status> result = current->test()) {
      using std::iter_swap;

      // We're expanding the set of completed requests
      --start_of_completed;

      // Swap the request we just completed with the last request that
      // has not yet been tested.
      iter_swap(current, start_of_completed);

      continue;
    }

    // Move to the next request.
    ++current;
  }

  return start_of_completed;
}
示例#2
0
std::pair<OutputIterator, BidirectionalIterator>
test_some(BidirectionalIterator first, BidirectionalIterator last,
          OutputIterator out)
{
  BidirectionalIterator current = first;
  BidirectionalIterator start_of_completed = last;
  while (current != start_of_completed) {
    // Check if we have found a completed request.
    if (optional<status> result = current->test()) {
      using std::iter_swap;

      // Emit the resulting status object
      *out++ = *result;

      // We're expanding the set of completed requests
      --start_of_completed;

      // Swap the request we just completed with the last request that
      // has not yet been tested.
      iter_swap(current, start_of_completed);

      continue;
    }

    // Move to the next request.
    ++current;
  }

  // Finish up by fixing the order of the completed set to match the
  // order in which we emitted status objects, then return.
  std::reverse(start_of_completed, last);
  return std::make_pair(out, start_of_completed);
}
示例#3
0
//shuffles the deck by switching cards at each position
void MasterPile::shuffle(){
  vector<Card>::iterator it = pile.begin();
  srand(time(NULL));
  while(it != pile.end()){
    int randomValue = rand() % this->getSize();
    iter_swap(it, pile.begin() + randomValue);
    it++;
  }
}
示例#4
0
template<class It> It uniquify(It begin, It const end)
{
    std::vector<It> v;
    v.reserve(static_cast<size_t>(std::distance(begin, end)));
    for (It i = begin; i != end; ++i)
    { v.push_back(i); }
    std::sort(v.begin(), v.end(), target_less());
    v.erase(std::unique(v.begin(), v.end(), target_equal()), v.end());
    std::sort(v.begin(), v.end());
    size_t j = 0;
    for (It i = begin; i != end && j != v.size(); ++i)
    {
        if (i == v[j])
        {
            using std::iter_swap; iter_swap(i, begin);
            ++j;
            ++begin;
        }
    }
    return begin;
}
示例#5
0
	void file_storage::optimize(int pad_file_limit)
	{
		// the main purpuse of padding is to optimize disk
		// I/O. This is a conservative memory page size assumption
		int alignment = 8*1024;

		// it doesn't make any sense to pad files that
		// are smaller than one piece
		if (pad_file_limit >= 0 && pad_file_limit < alignment)
			pad_file_limit = alignment;

		// put the largest file at the front, to make sure
		// it's aligned
		std::vector<file_entry>::iterator i = std::max_element(m_files.begin(), m_files.end()
			, boost::bind(&file_entry::size, _1) < boost::bind(&file_entry::size, _2));

		using std::iter_swap;
		iter_swap(i, m_files.begin());

		size_type off = 0;
		int padding_file = 0;
		for (std::vector<file_entry>::iterator i = m_files.begin();
			i != m_files.end(); ++i)
		{
			if (pad_file_limit >= 0
				&& (off & (alignment-1)) != 0
				&& i->size > pad_file_limit
				&& i->pad_file == false)
			{
				// if we have pad files enabled, and this file is
				// not piece-aligned and the file size exceeds the
				// limit, and it's not a padding file itself.
				// so add a padding file in front of it
				int pad_size = alignment - (off & (alignment-1));
				
				// find the largest file that fits in pad_size
				std::vector<file_entry>::iterator best_match = m_files.end();
				for (std::vector<file_entry>::iterator j = i+1; j < m_files.end(); ++j)
				{
					if (j->size > pad_size) continue;
					if (best_match == m_files.end() || j->size > best_match->size)
						best_match = j;
				}

				if (best_match != m_files.end())
				{
					// we found one
					// We cannot have found i, because i->size > pad_file_limit
					// which is forced to be no less than alignment. We only
					// look for files <= pad_size, which never is greater than
					// alignment
					TORRENT_ASSERT(best_match != i);
					file_entry e = *best_match;
					m_files.erase(best_match);
					i = m_files.insert(i, e);
					i->offset = off;
					off += i->size;
					continue;
				}

				// we could not find a file that fits in pad_size
				// add a padding file
				// note that i will be set to point to the
				// new pad file. Once we're done adding it, we need
				// to increment i to point to the current file again
				file_entry e;
				i = m_files.insert(i, e);
				i->size = pad_size;
				i->offset = off;
				i->file_base = 0;
				char name[10];
				std::sprintf(name, "%d", padding_file);
				i->path = *(i+1)->path.begin();
				i->path /= "_____padding_file_";
				i->path /= name;
				i->pad_file = true;
				off += pad_size;
				++padding_file;
				// skip the pad file we just added and point
				// at the current file again
				++i;
			}
			i->offset = off;
			off += i->size;
		}
		m_total_size = off;
	}
示例#6
0
BidirectionalIterator
wait_some(BidirectionalIterator first, BidirectionalIterator last)
{
  using std::advance;

  if (first == last)
    return first;

  typedef typename std::iterator_traits<BidirectionalIterator>::difference_type
    difference_type;

  bool all_trivial_requests = true;
  difference_type n = 0;
  BidirectionalIterator current = first;
  BidirectionalIterator start_of_completed = last;
  while (true) {
    // Check if we have found a completed request.
    if (optional<status> result = current->test()) {
      using std::iter_swap;

      // We're expanding the set of completed requests
      --start_of_completed;

      // If we have hit the end of the list of pending requests, we're
      // done.
      if (current == start_of_completed)
        return start_of_completed;

      // Swap the request we just completed with the last request that
      // has not yet been tested.
      iter_swap(current, start_of_completed);

      continue;
    }

    // Check if this request (and all others before it) are "trivial"
    // requests, e.g., they can be represented with a single
    // MPI_Request.
    all_trivial_requests =
      all_trivial_requests
      && !current->m_handler
      && current->m_requests[1] == MPI_REQUEST_NULL;

    // Move to the next request.
    ++n;
    if (++current == start_of_completed) {
        // If we have satisfied some requests, we're done.
      if (start_of_completed != last)
        return start_of_completed;

      // We have reached the end of the list. If all requests thus far
      // have been trivial, we can call MPI_Waitsome directly, because
      // it may be more efficient than our busy-wait semantics.
      if (all_trivial_requests) {
        std::vector<MPI_Request> requests;
        std::vector<int> indices(n);
        requests.reserve(n);
        for (current = first; current != last; ++current)
          requests.push_back(current->m_requests[0]);

        // Let MPI wait until some of these operations complete.
        int num_completed;
        BOOST_MPI_CHECK_RESULT(MPI_Waitsome,
                               (n, &requests[0], &num_completed, &indices[0],
                                MPI_STATUSES_IGNORE));

        // Translate the index-based result of MPI_Waitsome into a
        // partitioning on the requests.
        int current_offset = 0;
        current = first;
        for (int index = 0; index < num_completed; ++index) {
          using std::iter_swap;

          // Move "current" to the request object at this index
          advance(current, indices[index] - current_offset);
          current_offset = indices[index];

          // Finish up the request and swap it into the "completed
          // requests" partition.
          current->m_requests[0] = requests[indices[index]];
          --start_of_completed;
          iter_swap(current, start_of_completed);
        }

        // We have satisfied some requests, so we are done.
        return start_of_completed;
      }

      // There are some nontrivial requests, so we must continue our
      // busy waiting loop.
      n = 0;
      current = first;
    }
  }

  // We cannot ever get here
  BOOST_ASSERT(false);
}