#include <stdint.h>
|
|
#ifdef COMPILE_TIME
|
|
#include "9float.hpp"
|
|
using scatter_key_t = ninefloat::Q<uint64_t,64>;
|
|
static const scatter_key_t scatter_key_increment = ninefloat::Q<uint64_t,64>::min_increment();
|
|
#else
|
|
using scatter_key_t = uint64_t;
|
|
static const scatter_key_t scatter_key_increment = 1;
|
|
#endif
|
|
|
|
#include <vector>
|
|
|
|
namespace StorageTree{
|
|
|
|
namespace _impl{
|
|
|
|
template<class childs>
|
|
struct subdivision
|
|
{
|
|
uint64_t weight;
|
|
std::vector<childs> content;
|
|
scatter_key_t begin;
|
|
scatter_key_t end;
|
|
static const bool divisible = true;
|
|
};
|
|
|
|
struct daemon_impl{
|
|
uint64_t weight;
|
|
scatter_key_t begin;
|
|
scatter_key_t end;
|
|
static const bool divisible = false;
|
|
};
|
|
|
|
template<class T>
|
|
constexpr T max(T any = 0)
|
|
{
|
|
if(any>any+scatter_key_increment)
|
|
return any
|
|
return max(any+scatter_key_increment);
|
|
}
|
|
}
|
|
|
|
|
|
using daemon = _impl::daemon_impl;
|
|
using server = _impl::subdivision<daemon>;
|
|
using subrack = _impl::subdivision<server>;
|
|
using rack = _impl::subdivision<subrack>;
|
|
using room = _impl::subdivision<rack>;
|
|
using datacenter = _impl::subdivision<room>;
|
|
using root = _impl::subdivision<datacenter>;
|
|
|
|
template<class T, std::enable_if_t<T::divisible>>
|
|
void update_weights(T& root, uint64_t sub_ratio=1, scatter_key_t begin=0, scatter_key_t end=_impl::max<scatter_key_t>())
|
|
{
|
|
scatter_key_t address_space = end-begin;
|
|
scatter_key_t base = begin
|
|
for(int idx=0:idx<root.content.size();idx++)
|
|
{
|
|
auto& elem = root.content[idx];
|
|
if(idx!=root.content.size()-1)
|
|
{
|
|
update_weights(elem, root.content.size()*sub_ratio, base, base+address_space/root.content.size());
|
|
base = base+address_space/root.content.size()+scatter_key_increment;
|
|
}
|
|
else
|
|
update_weights(elem, root.content.size()*sub_ratio, base, end);
|
|
|
|
}
|
|
}
|
|
|
|
template<class T, std::enable_if_t<!T::divisible>>
|
|
void update_weights(T& root, scatter_key_t begin, scatter_key_t end)
|
|
{
|
|
this->begin = begin;
|
|
this->end = end;
|
|
}
|
|
}
|