Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Selection to its own header. #306

Merged
merged 2 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ set(SONATA_SRC
src/nodes.cpp
src/population.cpp
src/report_reader.cpp
src/selection.cpp
src/utils.cpp
${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp
)
Expand Down
72 changes: 1 addition & 71 deletions include/bbp/sonata/population.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,81 +19,11 @@
#include <utility> // std::move
#include <vector>

#include <bbp/sonata/selection.h>

namespace bbp {
namespace sonata {

//--------------------------------------------------------------------------------------------------

class SONATA_API Selection
{
public:
using Value = uint64_t;
using Values = std::vector<Value>;
using Range = std::pair<Value, Value>;
using Ranges = std::vector<Range>;

Selection(Ranges ranges);

template <typename Iterator>
static Selection fromValues(Iterator first, Iterator last);
static Selection fromValues(const Values& values);

/**
* Get a list of ranges constituting Selection
*/
const Ranges& ranges() const;

/**
* Array of IDs constituting Selection
*/
Values flatten() const;

/**
* Total number of elements constituting Selection
*/
size_t flatSize() const;

bool empty() const;

private:
Ranges ranges_;
};

bool SONATA_API operator==(const Selection&, const Selection&);
bool SONATA_API operator!=(const Selection&, const Selection&);

Selection SONATA_API operator&(const Selection&, const Selection&);
Selection SONATA_API operator|(const Selection&, const Selection&);

template <typename Iterator>
Selection Selection::fromValues(Iterator first, Iterator last) {
Selection::Ranges ranges;

Selection::Range range{0, 0};
while (first != last) {
const auto v = *first;
if (v == range.second) {
++range.second;
} else {
if (range.first < range.second) {
ranges.push_back(range);
}
range.first = v;
range.second = v + 1;
}
++first;
}

if (range.first < range.second) {
ranges.push_back(range);
}

return Selection(std::move(ranges));
}

//--------------------------------------------------------------------------------------------------

class SONATA_API Population
{
public:
Expand Down
80 changes: 80 additions & 0 deletions include/bbp/sonata/selection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#pragma once

#include "common.h"

#include <cstdint>
#include <utility> // std::move
#include <vector>

namespace bbp {
namespace sonata {

class SONATA_API Selection
{
public:
using Value = uint64_t;
using Values = std::vector<Value>;
using Range = std::pair<Value, Value>;
using Ranges = std::vector<Range>;

Selection(Ranges ranges);

template <typename Iterator>
static Selection fromValues(Iterator first, Iterator last);
static Selection fromValues(const Values& values);

/**
* Get a list of ranges constituting Selection
*/
const Ranges& ranges() const;

/**
* Array of IDs constituting Selection
*/
Values flatten() const;

/**
* Total number of elements constituting Selection
*/
size_t flatSize() const;

bool empty() const;

private:
Ranges ranges_;
};

bool SONATA_API operator==(const Selection&, const Selection&);
bool SONATA_API operator!=(const Selection&, const Selection&);

Selection SONATA_API operator&(const Selection&, const Selection&);
Selection SONATA_API operator|(const Selection&, const Selection&);

template <typename Iterator>
Selection Selection::fromValues(Iterator first, Iterator last) {
Selection::Ranges ranges;

Selection::Range range{0, 0};
while (first != last) {
const auto v = *first;
if (v == range.second) {
++range.second;
} else {
if (range.first < range.second) {
ranges.push_back(range);
}
range.first = v;
range.second = v + 1;
}
++first;
}

if (range.first < range.second) {
ranges.push_back(range);
}

return Selection(std::move(ranges));
}

} // namespace sonata
} // namespace bbp
114 changes: 0 additions & 114 deletions src/population.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,120 +22,6 @@
namespace bbp {
namespace sonata {

namespace detail {
using Range = Selection::Range;
using Ranges = Selection::Ranges;

void _checkRanges(const Ranges& ranges) {
for (const auto& range : ranges) {
if (range.first >= range.second) {
throw SonataError(fmt::format("Invalid range: {}-{}", range.first, range.second));
}
}
}

Ranges _sortAndMerge(const Ranges& ranges) {
return bulk_read::sortAndMerge(ranges);
}

Selection intersection_(const Ranges& lhs, const Ranges& rhs) {
if (lhs.empty() || rhs.empty()) {
return Selection({});
}
Ranges r0 = detail::_sortAndMerge(lhs);
Ranges r1 = detail::_sortAndMerge(rhs);

auto it0 = r0.cbegin();
auto it1 = r1.cbegin();

Ranges ret;
while (it0 != r0.cend() && it1 != r1.cend()) {
auto start = std::max(it0->first, it1->first);
auto end = std::min(it0->second, it1->second);
if (start < end) {
ret.emplace_back(start, end);
}

if (it0->second < it1->second) {
++it0;
} else {
++it1;
}
}

return Selection(std::move(ret));
}

Selection union_(const Ranges& lhs, const Ranges& rhs) {
Ranges ret;
std::copy(lhs.begin(), lhs.end(), std::back_inserter(ret));
std::copy(rhs.begin(), rhs.end(), std::back_inserter(ret));
ret = detail::_sortAndMerge(ret);
return Selection(std::move(ret));
}
} // namespace detail


Selection::Selection(Selection::Ranges ranges)
: ranges_(std::move(ranges)) {
detail::_checkRanges(ranges_);
}


Selection Selection::fromValues(const Selection::Values& values) {
return fromValues(values.begin(), values.end());
}


const Selection::Ranges& Selection::ranges() const {
return ranges_;
}


Selection::Values Selection::flatten() const {
Selection::Values result;
result.reserve(flatSize());
for (const auto& range : ranges_) {
for (auto v = range.first; v < range.second; ++v) {
result.emplace_back(v);
}
}
return result;
}


size_t Selection::flatSize() const {
return bulk_read::detail::flatSize(ranges_);
}


bool Selection::empty() const {
return ranges().empty();
}

//--------------------------------------------------------------------------------------------------


bool operator==(const Selection& lhs, const Selection& rhs) {
return lhs.ranges() == rhs.ranges();
}


bool operator!=(const Selection& lhs, const Selection& rhs) {
return !(lhs == rhs);
}


Selection operator&(const Selection& lhs, const Selection& rhs) {
return detail::intersection_(lhs.ranges(), rhs.ranges());
}


Selection operator|(const Selection& lhs, const Selection& rhs) {
return detail::union_(lhs.ranges(), rhs.ranges());
}


namespace {

std::string _getDataType(const HighFive::DataSet& dset, const std::string& name) {
Expand Down
5 changes: 4 additions & 1 deletion src/read_bulk.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#pragma once

#include <bbp/sonata/population.h>
#include <algorithm>
#include <cstdint>
#include <fmt/format.h>

#include <bbp/sonata/population.h>

#define SONATA_PAGESIZE (4 * 1 << 20)

Expand Down
Loading
Loading