From 1d78da1bec30d4e821a9c36e91c1469759b8742f Mon Sep 17 00:00:00 2001 From: Joongi Kim Date: Fri, 4 Mar 2016 00:43:49 +0900 Subject: [PATCH] Add accumulated index calculator with tests. * This will replace batch_ids/item_ids arrays for offloading, greatly saving the memory footprint. * Adds a standardized return (error) codes for NBA internal APIs. --- include/nba/core/accumidx.hh | 39 ++++++++++++++++++++++++++++++++ include/nba/core/errors.hh | 16 ++++++++++++++ tests/test_accumidx.cc | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 include/nba/core/accumidx.hh create mode 100644 include/nba/core/errors.hh create mode 100644 tests/test_accumidx.cc diff --git a/include/nba/core/accumidx.hh b/include/nba/core/accumidx.hh new file mode 100644 index 0000000..a90d57b --- /dev/null +++ b/include/nba/core/accumidx.hh @@ -0,0 +1,39 @@ +#ifndef __NBA_CORE_ACCUMIDX_HH__ +#define __NBA_CORE_ACCUMIDX_HH__ + +#include +#include + +namespace nba { + +template +static inline nba::error_t get_accum_idx(const T *group_counts, + const T num_groups, + const T global_idx, + T &group_idx, + T &item_idx) +{ + static_assert(std::is_integral::value, "Integer type required."); + T sum = 0; + T i; + bool found = false; + for (i = 0; i < num_groups; i++) { + if (global_idx >= sum && global_idx < sum + group_counts[i]) { + item_idx = global_idx - sum; + found = true; + break; + } + sum += group_counts[i]; + } + if (found) + group_idx = i; + else + return NBA_NOT_FOUND; + return NBA_SUCCESS; +} + +} // endns(nba) + +#endif + +// vim: ts=8 sts=4 sw=4 et diff --git a/include/nba/core/errors.hh b/include/nba/core/errors.hh new file mode 100644 index 0000000..e2bcaf0 --- /dev/null +++ b/include/nba/core/errors.hh @@ -0,0 +1,16 @@ +#ifndef __NBA_CORE_ERRORS_HH__ +#define __NBA_CORE_ERRORS_HH__ + +namespace nba { + +typedef enum : int { + NBA_SUCCESS = 0, + NBA_FAILURE = 1, + NBA_NOT_FOUND = 2, +} error_t; + +} // endns(nba) + +#endif + +// vim: ts=8 sts=4 sw=4 et diff --git a/tests/test_accumidx.cc b/tests/test_accumidx.cc new file mode 100644 index 0000000..c6a12a4 --- /dev/null +++ b/tests/test_accumidx.cc @@ -0,0 +1,43 @@ +#include +#include +#include + +using namespace std; +using namespace nba; + +TEST(AccumIdxTest, Count) { + const unsigned num_groups = 4; + const unsigned groups[num_groups] = { 35, 1, 0, 21 }; + unsigned group_idx = 0, item_idx = 0; + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 0u, group_idx, item_idx)); + EXPECT_EQ(0, group_idx); + EXPECT_EQ(0, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 1u, group_idx, item_idx)); + EXPECT_EQ(0, group_idx); + EXPECT_EQ(1, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 17u, group_idx, item_idx)); + EXPECT_EQ(0, group_idx); + EXPECT_EQ(17, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 34u, group_idx, item_idx)); + EXPECT_EQ(0, group_idx); + EXPECT_EQ(34, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 35u, group_idx, item_idx)); + EXPECT_EQ(1, group_idx); + EXPECT_EQ(0, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 36u, group_idx, item_idx)); + EXPECT_EQ(3, group_idx); + EXPECT_EQ(0, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 37u, group_idx, item_idx)); + EXPECT_EQ(3, group_idx); + EXPECT_EQ(1, item_idx); + EXPECT_EQ(NBA_SUCCESS, get_accum_idx(groups, num_groups, 56u, group_idx, item_idx)); + EXPECT_EQ(3, group_idx); + EXPECT_EQ(20, item_idx); + group_idx = 7; + item_idx = 7; + EXPECT_EQ(NBA_NOT_FOUND, get_accum_idx(groups, num_groups, 57u, group_idx, item_idx)); + EXPECT_EQ(7, group_idx); + EXPECT_EQ(7, item_idx); +} + +// vim: ts=8 sts=4 sw=4 et