interconnect.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "interconnect.h"
  2. #include <util/digest/murmur.h>
  3. #include <google/protobuf/text_format.h>
  4. namespace NActors {
  5. TNodeLocation::TNodeLocation(const NActorsInterconnect::TNodeLocation& location) {
  6. const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
  7. const NActorsInterconnect::TNodeLocation *locp = &location;
  8. NActorsInterconnect::TNodeLocation temp; // for legacy location case
  9. // WalleConfig compatibility section
  10. if (locp->HasBody()) {
  11. if (locp == &location) {
  12. temp.CopyFrom(*locp);
  13. locp = &temp;
  14. }
  15. temp.SetUnit(::ToString(temp.GetBody()));
  16. temp.ClearBody();
  17. }
  18. // legacy value processing
  19. if (locp->HasDataCenterNum() || locp->HasRoomNum() || locp->HasRackNum() || locp->HasBodyNum()) {
  20. if (locp == &location) {
  21. temp.CopyFrom(*locp);
  22. locp = &temp;
  23. }
  24. LegacyValue = TLegacyValue{temp.GetDataCenterNum(), temp.GetRoomNum(), temp.GetRackNum(), temp.GetBodyNum()};
  25. temp.ClearDataCenterNum();
  26. temp.ClearRoomNum();
  27. temp.ClearRackNum();
  28. temp.ClearBodyNum();
  29. const NProtoBuf::Reflection *reflection = temp.GetReflection();
  30. bool fieldsFromNewFormat = false;
  31. for (int i = 0, count = descriptor->field_count(); !fieldsFromNewFormat && i < count; ++i) {
  32. fieldsFromNewFormat |= reflection->HasField(temp, descriptor->field(i));
  33. }
  34. if (!fieldsFromNewFormat) {
  35. const auto& v = LegacyValue->DataCenter;
  36. const char *p = reinterpret_cast<const char*>(&v);
  37. temp.SetDataCenter(TString(p, strnlen(p, sizeof(ui32))));
  38. temp.SetModule(::ToString(LegacyValue->Room));
  39. temp.SetRack(::ToString(LegacyValue->Rack));
  40. temp.SetUnit(::ToString(LegacyValue->Body));
  41. }
  42. }
  43. auto makeString = [&] {
  44. NProtoBuf::TextFormat::Printer p;
  45. p.SetSingleLineMode(true);
  46. TString s;
  47. p.PrintToString(*locp, &s);
  48. return s;
  49. };
  50. // modern format parsing
  51. const NProtoBuf::Reflection *reflection = locp->GetReflection();
  52. for (int i = 0, count = descriptor->field_count(); i < count; ++i) {
  53. const NProtoBuf::FieldDescriptor *field = descriptor->field(i);
  54. if (reflection->HasField(*locp, field)) {
  55. Y_VERIFY(field->type() == NProtoBuf::FieldDescriptor::TYPE_STRING, "Location# %s", makeString().data());
  56. Items.emplace_back(TKeys::E(field->number()), reflection->GetString(*locp, field));
  57. }
  58. }
  59. const NProtoBuf::UnknownFieldSet& unknown = locp->unknown_fields();
  60. for (int i = 0, count = unknown.field_count(); i < count; ++i) {
  61. const NProtoBuf::UnknownField& field = unknown.field(i);
  62. Y_VERIFY(field.type() == NProtoBuf::UnknownField::TYPE_LENGTH_DELIMITED, "Location# %s", makeString().data());
  63. Items.emplace_back(TKeys::E(field.number()), field.length_delimited());
  64. }
  65. std::sort(Items.begin(), Items.end());
  66. }
  67. TNodeLocation::TNodeLocation(TFromSerialized, const TString& s)
  68. : TNodeLocation(ParseLocation(s))
  69. {}
  70. NActorsInterconnect::TNodeLocation TNodeLocation::ParseLocation(const TString& s) {
  71. NActorsInterconnect::TNodeLocation res;
  72. const bool success = res.ParseFromString(s);
  73. Y_VERIFY(success);
  74. return res;
  75. }
  76. TString TNodeLocation::ToStringUpTo(TKeys::E upToKey) const {
  77. const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
  78. TStringBuilder res;
  79. for (const auto& [key, value] : Items) {
  80. if (upToKey < key) {
  81. break;
  82. }
  83. TString name;
  84. if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
  85. name = field->options().GetExtension(NActorsInterconnect::PrintName);
  86. } else {
  87. name = ::ToString(int(key));
  88. }
  89. if (key != upToKey) {
  90. res << name << "=" << value << "/";
  91. } else {
  92. res << value;
  93. }
  94. }
  95. return res;
  96. }
  97. void TNodeLocation::Serialize(NActorsInterconnect::TNodeLocation *pb) const {
  98. const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
  99. const NProtoBuf::Reflection *reflection = pb->GetReflection();
  100. NProtoBuf::UnknownFieldSet *unknown = pb->mutable_unknown_fields();
  101. for (const auto& [key, value] : Items) {
  102. if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
  103. reflection->SetString(pb, field, value);
  104. } else {
  105. unknown->AddLengthDelimited(key)->assign(value);
  106. }
  107. }
  108. }
  109. TString TNodeLocation::GetSerializedLocation() const {
  110. NActorsInterconnect::TNodeLocation pb;
  111. Serialize(&pb);
  112. TString s;
  113. const bool success = pb.SerializeToString(&s);
  114. Y_VERIFY(success);
  115. return s;
  116. }
  117. TNodeLocation::TLegacyValue TNodeLocation::GetLegacyValue() const {
  118. if (LegacyValue) {
  119. return *LegacyValue;
  120. }
  121. ui32 dataCenterId = 0, moduleId = 0, rackId = 0, unitId = 0;
  122. for (const auto& [key, value] : Items) {
  123. switch (key) {
  124. case TKeys::DataCenter:
  125. memcpy(&dataCenterId, value.data(), Min<size_t>(sizeof(dataCenterId), value.length()));
  126. break;
  127. case TKeys::Module: {
  128. const bool success = TryFromString(value, moduleId);
  129. Y_VERIFY(success);
  130. break;
  131. }
  132. case TKeys::Rack:
  133. // hacky way to obtain numeric id by a rack name
  134. if (!TryFromString(value, rackId)) {
  135. rackId = MurmurHash<ui32>(value.data(), value.length());
  136. }
  137. break;
  138. case TKeys::Unit: {
  139. const bool success = TryFromString(value, unitId);
  140. Y_VERIFY(success);
  141. break;
  142. }
  143. default:
  144. Y_FAIL("unexpected legacy key# %d", key);
  145. }
  146. }
  147. return {dataCenterId, moduleId, rackId, unitId};
  148. }
  149. } // NActors