Goddess of Justice DB, the database used for storage on IzaroDFS
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

112 linhas
3.4 KiB

  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. }