Skip to content

Commit

Permalink
planner_multi: add update functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
milroy committed Jan 13, 2024
1 parent 2b886d1 commit 04ddf71
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
65 changes: 65 additions & 0 deletions resource/planner/c++/planner_multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,51 @@ planner_multi::~planner_multi ()
erase ();
}

void planner_multi::add_planner (int64_t base_time, uint64_t duration,
const uint64_t resource_total,
const char *resource_type, size_t i)
{
char *type = nullptr;
planner_t *p = nullptr;

if ( (type = strdup (resource_type)) == nullptr) {
errno = ENOMEM;
throw std::runtime_error ("ERROR in strdup\n");
}
m_iter.counts[type] = 0;
try {
p = new planner_t (base_time, duration,
resource_total,
resource_type);
} catch (std::bad_alloc &e) {
errno = ENOMEM;
}
if (p == nullptr)
throw std::runtime_error ("ERROR adding planner_multi\n");

if (i > m_types_totals_planners.size ())
m_types_totals_planners.push_back ({type, resource_total, p});
else {
auto it = m_types_totals_planners.begin () + i;
m_types_totals_planners.insert (
it, planner_multi_meta{type, resource_total, p});
}

}

void planner_multi::delete_planners (const std::unordered_set<std::string> &rtypes)
{
auto &by_res = m_types_totals_planners.get<res_type> ();
for (auto iter = by_res.begin (); iter != by_res.end ();) {
if (rtypes.find (iter->resource_type) == rtypes.end ()) {
iter = by_res.erase (iter);
// need to remove from request_multi
m_iter.counts.erase (iter->resource_type);
} else
++iter;
}
}

planner_t *planner_multi::get_planner_at (size_t i)
{
return m_types_totals_planners.at (i).planner;
Expand All @@ -194,6 +239,26 @@ planner_t *planner_multi::get_planner_at (const char *type)
return by_res.find (strdup (type))->planner;
}

void planner_multi::update_planner_index (const char *type, size_t i)
{
std::string rtype = strdup (type);
auto by_res = m_types_totals_planners.get<res_type> ().find (rtype);
auto new_idx = m_types_totals_planners.begin () + i;
auto curr_idx = m_types_totals_planners.get<idx> ().iterator_to (*by_res);
// noop if new_idx == curr_idx
m_types_totals_planners.relocate (new_idx, curr_idx);
}

bool planner_multi::planner_at (const char *type)
{
auto &by_res = m_types_totals_planners.get<res_type> ();
auto result = by_res.find (std::string (type));
if (result == by_res.end ())
return false;
else
return true;
}

size_t planner_multi::get_planners_size ()
{
return m_types_totals_planners.size ();
Expand Down
9 changes: 9 additions & 0 deletions resource/planner/c++/planner_multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define PLANNER_MULTI_HPP

#include "planner.hpp"
#include <unordered_set>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/random_access_index.hpp>
Expand Down Expand Up @@ -64,6 +65,8 @@ class planner_multi {
// Public getters and setters
planner_t *get_planner_at (size_t i);
planner_t *get_planner_at (const char *type);
void update_planner_index (const char *type, size_t i);
bool planner_at (const char *type);
size_t get_planners_size ();
uint64_t get_resource_total_at (size_t i);
const char *get_resource_type_at (size_t i);
Expand All @@ -79,6 +82,12 @@ class planner_multi {
uint64_t get_span_counter ();
void set_span_counter (uint64_t sc);
void incr_span_counter ();
void add_planner (int64_t base_time, uint64_t duration,
const uint64_t resource_total,
const char *resource_type, size_t i);
// Assuming small number of resources,
// could try set, too
void delete_planners (const std::unordered_set<std::string> &rtypes);

private:
multi_container m_types_totals_planners;
Expand Down
19 changes: 19 additions & 0 deletions resource/planner/c/planner_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,25 @@ size_t planner_multi_span_size (planner_multi_t *ctx);
*/
bool planner_multis_equal (planner_multi_t *lhs, planner_multi_t *rhs);

/*! Update the counts and resource types to support elasticity.
*
* \param resource_totals
* 64-bit unsigned integer array of size len where each
* element contains the total count of available resources
* of a single resource type.
* \param resource_types
* string array of size len where each element contains
* the resource type corresponding to each corresponding
* element in the resource_totals array.
* \return 0 on success; -1 on an error with errno set as follows:
* EINVAL: invalid argument.
*/
int planner_multi_update (planner_multi_t *ctx,
const uint64_t *resource_totals,
const char **resource_types,
size_t len);


#ifdef __cplusplus
}
#endif
Expand Down
58 changes: 58 additions & 0 deletions resource/planner/c/planner_multi_c_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <limits>
#include <vector>
#include <map>
#include <unordered_set>

#include "planner_multi.h"
#include "resource/planner/c++/planner_multi.hpp"
Expand Down Expand Up @@ -471,6 +472,63 @@ extern "C" bool planner_multis_equal (planner_multi_t *lhs,
return (*(lhs->plan_multi) == *(rhs->plan_multi));
}

extern "C" int planner_multi_update (planner_multi_t *ctx,
const uint64_t *resource_totals,
const char **resource_types,
size_t len)
{
int rc = -1;
size_t ntypes, ntotals, i = 0;
// Assuming small number of resources,
// could try set, too
std::unordered_set<std::string> rtypes;
int64_t base_time = 0;
int64_t duration = 0;

if (!ctx || !resource_totals || !resource_types) {
errno = EINVAL;
goto done;
}
base_time = planner_base_time (
ctx->plan_multi->get_planner_at (static_cast<size_t> (0)));
duration = planner_duration (
ctx->plan_multi->get_planner_at (static_cast<size_t> (0)));
if (duration < 0) {
errno = EINVAL;
goto done;
}

for (i = 0; i < len; ++i) {
if (resource_totals[i] >
static_cast<uint64_t> (std::numeric_limits<int64_t>::max ())) {
errno = ERANGE;
goto done;
}
rtypes.insert (resource_types[i]);
if (!ctx->plan_multi->planner_at (resource_types[i])) {
// Assume base_time same as parent
ctx->plan_multi->add_planner (base_time, static_cast<uint64_t> (duration),
resource_totals[i], resource_types[i], i);
} else {
// Index could have changed
ctx->plan_multi->update_planner_index (resource_types[i], i);
if ( (rc = planner_update (ctx->plan_multi->get_planner_at (i),
resource_totals[i])) != 0) {
errno = EINVAL;
goto done;
}
}
}
// remove values not in new types
if (rtypes.size () > 0)
ctx->plan_multi->delete_planners (rtypes);

rc = 0;

done:
return rc;
}

/*
* vi: ts=4 sw=4 expandtab
*/

0 comments on commit 04ddf71

Please sign in to comment.