Skip to content

Commit bcceb1f

Browse files
committed
planner_multi: add update functionality
Problem: when updating the Fluxion resource graph planners, resources, counts, and their orders can be changed by mutation of the resource graph topology and attributes. Add `update` functionality to `planner_multi` and the C interface to add new resources and planners, reorder, modify, and permute existing resources, and delete removed resources.
1 parent f9e78b3 commit bcceb1f

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed

resource/planner/c++/planner_multi.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,48 @@ planner_multi::~planner_multi ()
182182
erase ();
183183
}
184184

185+
void planner_multi::add_planner (int64_t base_time, uint64_t duration,
186+
const uint64_t resource_total,
187+
const char *resource_type, size_t i)
188+
{
189+
std::string type;
190+
planner_t *p = nullptr;
191+
192+
try {
193+
type = std::string (resource_type);
194+
p = new planner_t (base_time, duration,
195+
resource_total,
196+
resource_type);
197+
} catch (std::bad_alloc &e) {
198+
errno = ENOMEM;
199+
throw std::bad_alloc ();
200+
}
201+
m_iter.counts[type] = 0;
202+
if (i > m_types_totals_planners.size ())
203+
m_types_totals_planners.push_back ({type, resource_total, p});
204+
else {
205+
auto it = m_types_totals_planners.begin () + i;
206+
m_types_totals_planners.insert (
207+
it, planner_multi_meta{type, resource_total, p});
208+
}
209+
210+
}
211+
212+
void planner_multi::delete_planners (const std::unordered_set<std::string> &rtypes)
213+
{
214+
auto &by_res = m_types_totals_planners.get<res_type> ();
215+
for (auto iter = by_res.begin (); iter != by_res.end ();) {
216+
if (rtypes.find (iter->resource_type) == rtypes.end ()) {
217+
// need to remove from request_multi
218+
m_iter.counts.erase (iter->resource_type);
219+
// Trigger planner destructor
220+
delete iter->planner;
221+
iter = by_res.erase (iter);
222+
} else
223+
++iter;
224+
}
225+
}
226+
185227
planner_t *planner_multi::get_planner_at (size_t i) const
186228
{
187229
return m_types_totals_planners.at (i).planner;
@@ -193,6 +235,32 @@ planner_t *planner_multi::get_planner_at (const char *type) const
193235
return by_res.find (std::string (type))->planner;
194236
}
195237

238+
void planner_multi::update_planner_index (const char *type, size_t i)
239+
{
240+
std::string rtype = std::string (type);
241+
auto by_res = m_types_totals_planners.get<res_type> ().find (rtype);
242+
auto new_idx = m_types_totals_planners.begin () + i;
243+
auto curr_idx = m_types_totals_planners.get<idx> ().iterator_to (*by_res);
244+
// noop if new_idx == curr_idx
245+
m_types_totals_planners.relocate (new_idx, curr_idx);
246+
}
247+
248+
int planner_multi::update_planner_total (uint64_t total, size_t i)
249+
{
250+
m_types_totals_planners.at (i).resource_total = total;
251+
return m_types_totals_planners.at (i).planner->plan->update_total (total);
252+
}
253+
254+
bool planner_multi::planner_at (const char *type) const
255+
{
256+
auto &by_res = m_types_totals_planners.get<res_type> ();
257+
auto result = by_res.find (std::string (type));
258+
if (result == by_res.end ())
259+
return false;
260+
else
261+
return true;
262+
}
263+
196264
size_t planner_multi::get_planners_size () const
197265
{
198266
return m_types_totals_planners.size ();

resource/planner/c++/planner_multi.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "planner.hpp"
1515
#include <unordered_map>
16+
#include <unordered_set>
1617
#include <boost/multi_index_container.hpp>
1718
#include <boost/multi_index/member.hpp>
1819
#include <boost/multi_index/random_access_index.hpp>
@@ -65,6 +66,9 @@ class planner_multi {
6566
// Public getters and setters
6667
planner_t *get_planner_at (size_t i) const;
6768
planner_t *get_planner_at (const char *type) const;
69+
void update_planner_index (const char *type, size_t i);
70+
int update_planner_total (uint64_t total, size_t i);
71+
bool planner_at (const char *type) const;
6872
size_t get_planners_size () const;
6973
int64_t get_resource_total_at (size_t i) const;
7074
int64_t get_resource_total_at (const char *type) const;
@@ -81,6 +85,12 @@ class planner_multi {
8185
uint64_t get_span_counter ();
8286
void set_span_counter (uint64_t sc);
8387
void incr_span_counter ();
88+
void add_planner (int64_t base_time, uint64_t duration,
89+
const uint64_t resource_total,
90+
const char *resource_type, size_t i);
91+
// Assuming small number of resources,
92+
// could try set, too
93+
void delete_planners (const std::unordered_set<std::string> &rtypes);
8494

8595
private:
8696
multi_container m_types_totals_planners;

resource/planner/c/planner_multi.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,28 @@ size_t planner_multi_span_size (planner_multi_t *ctx);
292292
*/
293293
bool planner_multis_equal (planner_multi_t *lhs, planner_multi_t *rhs);
294294

295+
/*! Update the counts and resource types to support elasticity.
296+
*
297+
* \param ctx opaque multi-planner context returned
298+
* from planner_multi_new.
299+
* \param resource_totals
300+
* 64-bit unsigned integer array of size len where each
301+
* element contains the total count of available resources
302+
* of a single resource type.
303+
* \param resource_types
304+
* string array of size len where each element contains
305+
* the resource type corresponding to each corresponding
306+
* element in the resource_totals array.
307+
* \param len length of resource_counts and resource_types arrays.
308+
* \return 0 on success; -1 on an error with errno set as follows:
309+
* EINVAL: invalid argument.
310+
*/
311+
int planner_multi_update (planner_multi_t *ctx,
312+
const uint64_t *resource_totals,
313+
const char **resource_types,
314+
size_t len);
315+
316+
295317
#ifdef __cplusplus
296318
}
297319
#endif

resource/planner/c/planner_multi_c_interface.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <limits>
1515
#include <vector>
1616
#include <map>
17+
#include <unordered_set>
1718

1819
#include "planner_multi.h"
1920
#include "resource/planner/c++/planner_multi.hpp"
@@ -466,6 +467,63 @@ extern "C" bool planner_multis_equal (planner_multi_t *lhs,
466467
return (*(lhs->plan_multi) == *(rhs->plan_multi));
467468
}
468469

470+
extern "C" int planner_multi_update (planner_multi_t *ctx,
471+
const uint64_t *resource_totals,
472+
const char **resource_types,
473+
size_t len)
474+
{
475+
int rc = -1;
476+
size_t i = 0;
477+
// Assuming small number of resource types,
478+
// could try set, too
479+
std::unordered_set<std::string> rtypes;
480+
int64_t base_time = 0;
481+
int64_t duration = 0;
482+
483+
if (!ctx || !resource_totals || !resource_types) {
484+
errno = EINVAL;
485+
goto done;
486+
}
487+
base_time = planner_base_time (
488+
ctx->plan_multi->get_planner_at (static_cast<size_t> (0)));
489+
duration = planner_duration (
490+
ctx->plan_multi->get_planner_at (static_cast<size_t> (0)));
491+
if (duration < 0) {
492+
errno = EINVAL;
493+
goto done;
494+
}
495+
496+
for (i = 0; i < len; ++i) {
497+
if (resource_totals[i] >
498+
static_cast<uint64_t> (std::numeric_limits<int64_t>::max ())) {
499+
errno = ERANGE;
500+
goto done;
501+
}
502+
rtypes.insert (resource_types[i]);
503+
if (!ctx->plan_multi->planner_at (resource_types[i])) {
504+
// Assume base_time same as parent
505+
ctx->plan_multi->add_planner (base_time, static_cast<uint64_t> (duration),
506+
resource_totals[i], resource_types[i], i);
507+
} else {
508+
// Index could have changed
509+
ctx->plan_multi->update_planner_index (resource_types[i], i);
510+
if ( (rc = ctx->plan_multi->update_planner_total (resource_totals[i],
511+
i)) != 0) {
512+
errno = EINVAL;
513+
goto done;
514+
}
515+
}
516+
}
517+
// remove values not in new types
518+
if (rtypes.size () > 0)
519+
ctx->plan_multi->delete_planners (rtypes);
520+
521+
rc = 0;
522+
523+
done:
524+
return rc;
525+
}
526+
469527
/*
470528
* vi: ts=4 sw=4 expandtab
471529
*/

0 commit comments

Comments
 (0)