Skip to content

Commit

Permalink
concurrent_set: get a batch, all at once.
Browse files Browse the repository at this point in the history
  • Loading branch information
linas committed May 10, 2024
1 parent 2c485cc commit 1674500
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions opencog/util/concurrent_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,47 @@ class concurrent_set
return true;
}

/// Same as above, but tries to get at most `nelt` of them. If there
/// are fewer, then fewer are returned. The goal here is to reduce the
/// number of locks taken.
std::vector<Element> try_get(size_t nelt, bool reverse = false)
{
std::vector<Element> elvec;

std::lock_guard<std::mutex> lock(the_mutex);
if (is_canceled) throw Canceled();
if (the_set.empty())
return elvec;

if (the_set.size() < nelt) nelt = the_set.size();

if (reverse)
{
for (size_t j=0; j<nelt; j++)
{
// Frick-n-frack, cannot cast reverse iterators to
// forward iterators. Also, there is no erase() that
// accepts a reverse iterator. This means that
// fetches from the end actually run slower. Dang.
typename std::set<Element>::const_reverse_iterator it = the_set.crbegin();
Element value = *it;
the_set.erase(value);
elvec.emplace_back(value);
}
}
else
{
for (size_t j=0; j<nelt; j++)
{
typename std::set <Element>::const_iterator it = the_set.cbegin();
Element value = *it;
the_set.erase(it);
elvec.emplace_back(value);
}
}
return elvec;
}

/// Get an item from the set. Block if the set is empty.
/// The element is removed from the set, before this returns.
void get(Element& value)
Expand Down

0 comments on commit 1674500

Please sign in to comment.