A library to scatter things accross a cluster depending on weights
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

114 行
2.9 KiB

  1. #pragma once
  2. #include <stdint.h>
  3. #include "9float.hpp"
  4. using scatter_key_t = ninefloat::Q<__int128,64>;
  5. static const scatter_key_t scatter_key_increment = ninefloat::Q<__int128,64>::min_increment();
  6. #include <vector>
  7. #include <numeric>
  8. #include <type_traits>
  9. #include <iostream>
  10. namespace StorageTree {
  11. namespace _impl {
  12. template<class childs>
  13. struct subdivision {
  14. uint64_t weight;
  15. std::vector<childs> content;
  16. scatter_key_t begin;
  17. scatter_key_t end;
  18. static constexpr bool divisible = true;
  19. };
  20. struct daemon_impl {
  21. uint64_t weight;
  22. scatter_key_t begin;
  23. scatter_key_t end;
  24. static constexpr bool divisible = false;
  25. };
  26. template<class T>
  27. constexpr T max(T any = 0)
  28. {
  29. if(any>any+scatter_key_increment) {
  30. return any;
  31. }
  32. return max(any+scatter_key_increment);
  33. }
  34. }
  35. using daemon = _impl::daemon_impl;
  36. using server = _impl::subdivision<daemon>;
  37. using subrack = _impl::subdivision<server>;
  38. using rack = _impl::subdivision<subrack>;
  39. using room = _impl::subdivision<rack>;
  40. using datacenter = _impl::subdivision<room>;
  41. using root = _impl::subdivision<datacenter>;
  42. template<class T>
  43. uint64_t total_weight(T& root)
  44. {
  45. uint64_t ret=0;
  46. for(auto& val : root.content) {
  47. ret+=total_weight(val);
  48. }
  49. return ret;
  50. }
  51. template<>
  52. uint64_t total_weight<daemon>(daemon& root)
  53. {
  54. return root.weight;
  55. }
  56. template<class T>
  57. scatter_key_t update_weights(T& root, uint64_t total, double sub_ratio=1, scatter_key_t begin=0, double ratio=0.5)
  58. {
  59. auto b = begin;
  60. for(auto& elem : root.content) {
  61. std::cout<<"UP"<<std::endl;
  62. b = update_weights(
  63. elem,
  64. total,
  65. sub_ratio*root.content.size(),
  66. b,
  67. ratio
  68. )+scatter_key_increment;
  69. }
  70. return begin;
  71. }
  72. template<>
  73. scatter_key_t update_weights<daemon>(daemon& root, uint64_t total, double sub_ratio, scatter_key_t begin, double ratio)
  74. {
  75. root.begin = begin;
  76. root.end = begin+scatter_key_t(0.5)*((scatter_key_t(1/sub_ratio)*scatter_key_t(ratio)+scatter_key_t((double)root.weight/(double)total)*scatter_key_t(1-ratio)));
  77. std::cout<<"Starts: "<<(uint64_t)root.begin.data()<<" Ends: "<<(uint64_t)root.end.data()<<std::endl;
  78. return root.end;
  79. }
  80. template<class T, typename... Args>
  81. void add_rule(T& root, uint64_t weight, size_t idx, std::tuple<Args...> Var)
  82. {
  83. if(idx<root.content.size())
  84. add_rule(root.content.at(idx),weight,Var...);
  85. else if(idx==root.content.size())
  86. {
  87. root.content.emplace_back();
  88. add_rule(root.content.at(idx),weight,Var...);
  89. }
  90. else
  91. throw std::runtime_error("libscatter: Bad rule, are you sure the order is right?");
  92. }
  93. template<>
  94. void add_rule<daemon,size_t>(daemon& root, uint64_t weight,std::tuple<>)
  95. {
  96. root.weight=weight;
  97. }
  98. }