|
@ -0,0 +1,77 @@ |
|
|
|
|
|
#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; |
|
|
|
|
|
} |
|
|
|
|
|
} |