Goddess of Justice DB, the database used for storage on IzaroDFS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.4 KiB

пре 5 година
  1. #include <chrono>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <string.h>
  6. #include <sstream>
  7. #include <string>
  8. #include <endian.hpp>
  9. #include <network.hpp>
  10. #include <array>
  11. #include <thread>
  12. #include <algorithm>
  13. using namespace std::chrono_literals;
  14. int main(int, char** argv){
  15. int64_t offset=0;
  16. std::array<int64_t, 4096> offsets;
  17. std::array<int64_t, 4096> offsets_smooth;
  18. std::array<int64_t, 4096> offset_variations;
  19. size_t pos = 0;
  20. int64_t max_offset_variation;
  21. int64_t max_oscillation = 0;
  22. int64_t min_ever = std::numeric_limits<int64_t>::max();
  23. int64_t max_ever = 0;
  24. std::stringstream ip_stream{argv[1]};
  25. std::array<uint8_t, 4> ip;
  26. std::string token;
  27. std::getline(ip_stream, token, '.');
  28. ip[0] = std::stoi(token);
  29. std::getline(ip_stream, token, '.');
  30. ip[1] = std::stoi(token);
  31. std::getline(ip_stream, token, '.');
  32. ip[2] = std::stoi(token);
  33. std::getline(ip_stream, token, '.');
  34. ip[3] = std::stoi(token);
  35. uint16_t port = std::stoi(argv[2]);
  36. auto soc = socket(AF_INET, SOCK_DGRAM, 0);
  37. struct sockaddr_in server;
  38. server.sin_family = AF_INET;
  39. server.sin_addr.s_addr = *(in_addr_t*)ip.data();
  40. server.sin_port = htons(port);
  41. struct timeval tv;
  42. tv.tv_sec = 5;
  43. tv.tv_usec = 0;
  44. setsockopt(soc, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
  45. std::cerr << "Connecting..." <<std::endl;
  46. connect(soc, (struct sockaddr*)&server, sizeof(server));
  47. req_rep buffer;
  48. uint64_t cnt = 0;
  49. uint64_t old_time = 0;
  50. while(true)
  51. {
  52. uint64_t tmp;
  53. buffer.id = 16;
  54. buffer.client_ts = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
  55. send(soc, (void*)&buffer, (socklen_t)sizeof(req_rep), 0);
  56. recv(soc, (void*)&buffer, (socklen_t)sizeof(req_rep), 0);
  57. if(buffer.server_ts != old_time)
  58. {
  59. tmp = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - buffer.client_ts;
  60. int64_t n_offset = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count() - buffer.server_ts;
  61. n_offset /= 2;
  62. offset_variations[pos] = ((long long)(offset-n_offset));
  63. if(cnt != 0)
  64. {
  65. offsets[pos] = n_offset;
  66. } else {
  67. offsets.fill(n_offset);
  68. offsets_smooth.fill(n_offset);
  69. }
  70. max_offset_variation = std::max(*std::max_element(offset_variations.begin(), offset_variations.end()), std::abs((int64_t)*std::min_element(offset_variations.begin(), offset_variations.end())));
  71. offset = (
  72. 7 * (std::accumulate(offsets_smooth.begin(), offsets_smooth.end(), 0)/offsets_smooth.size())
  73. + std::accumulate(offsets.begin(), offsets.end(), 0)/offsets.size()
  74. ) / 8;
  75. offsets_smooth[pos] = offset;
  76. pos=(pos+1)%offset_variations.size();
  77. if(cnt > offsets.size()*2)
  78. {
  79. for(auto i : offsets_smooth)
  80. for(auto j : offsets_smooth)
  81. {
  82. max_oscillation = std::max(
  83. std::abs(i-j),
  84. max_oscillation
  85. );
  86. }
  87. min_ever = std::min(min_ever, offset);
  88. max_ever = std::max(max_ever, offset);
  89. }
  90. else if (cnt < offsets.size()) {
  91. offsets_smooth[pos] = n_offset;
  92. }
  93. old_time = buffer.server_ts;
  94. std::cout << cnt << "\t"<< min_ever << "\t" << offset << "\t" << max_ever << "\t" << max_oscillation << "\t" << offset-n_offset << "\t" << max_offset_variation <<std::endl;
  95. }
  96. cnt++;
  97. //std::this_thread::sleep_for(6ms);
  98. }
  99. }