123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #include "interconnect.h"
- #include <util/digest/murmur.h>
- #include <google/protobuf/text_format.h>
- namespace NActors {
- TNodeLocation::TNodeLocation(const NActorsInterconnect::TNodeLocation& location) {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
- const NActorsInterconnect::TNodeLocation *locp = &location;
- NActorsInterconnect::TNodeLocation temp; // for legacy location case
- // WalleConfig compatibility section
- if (locp->HasBody()) {
- if (locp == &location) {
- temp.CopyFrom(*locp);
- locp = &temp;
- }
- temp.SetUnit(::ToString(temp.GetBody()));
- temp.ClearBody();
- }
- // legacy value processing
- if (locp->HasDataCenterNum() || locp->HasRoomNum() || locp->HasRackNum() || locp->HasBodyNum()) {
- if (locp == &location) {
- temp.CopyFrom(*locp);
- locp = &temp;
- }
- LegacyValue = TLegacyValue{temp.GetDataCenterNum(), temp.GetRoomNum(), temp.GetRackNum(), temp.GetBodyNum()};
- temp.ClearDataCenterNum();
- temp.ClearRoomNum();
- temp.ClearRackNum();
- temp.ClearBodyNum();
- const NProtoBuf::Reflection *reflection = temp.GetReflection();
- bool fieldsFromNewFormat = false;
- for (int i = 0, count = descriptor->field_count(); !fieldsFromNewFormat && i < count; ++i) {
- fieldsFromNewFormat |= reflection->HasField(temp, descriptor->field(i));
- }
- if (!fieldsFromNewFormat) {
- const auto& v = LegacyValue->DataCenter;
- const char *p = reinterpret_cast<const char*>(&v);
- temp.SetDataCenter(TString(p, strnlen(p, sizeof(ui32))));
- temp.SetModule(::ToString(LegacyValue->Room));
- temp.SetRack(::ToString(LegacyValue->Rack));
- temp.SetUnit(::ToString(LegacyValue->Body));
- }
- }
- auto makeString = [&] {
- NProtoBuf::TextFormat::Printer p;
- p.SetSingleLineMode(true);
- TString s;
- p.PrintToString(*locp, &s);
- return s;
- };
- // modern format parsing
- const NProtoBuf::Reflection *reflection = locp->GetReflection();
- for (int i = 0, count = descriptor->field_count(); i < count; ++i) {
- const NProtoBuf::FieldDescriptor *field = descriptor->field(i);
- if (reflection->HasField(*locp, field)) {
- Y_VERIFY(field->type() == NProtoBuf::FieldDescriptor::TYPE_STRING, "Location# %s", makeString().data());
- Items.emplace_back(TKeys::E(field->number()), reflection->GetString(*locp, field));
- }
- }
- const NProtoBuf::UnknownFieldSet& unknown = locp->unknown_fields();
- for (int i = 0, count = unknown.field_count(); i < count; ++i) {
- const NProtoBuf::UnknownField& field = unknown.field(i);
- Y_VERIFY(field.type() == NProtoBuf::UnknownField::TYPE_LENGTH_DELIMITED, "Location# %s", makeString().data());
- Items.emplace_back(TKeys::E(field.number()), field.length_delimited());
- }
- std::sort(Items.begin(), Items.end());
- }
- TNodeLocation::TNodeLocation(TFromSerialized, const TString& s)
- : TNodeLocation(ParseLocation(s))
- {}
- NActorsInterconnect::TNodeLocation TNodeLocation::ParseLocation(const TString& s) {
- NActorsInterconnect::TNodeLocation res;
- const bool success = res.ParseFromString(s);
- Y_VERIFY(success);
- return res;
- }
- TString TNodeLocation::ToStringUpTo(TKeys::E upToKey) const {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
- TStringBuilder res;
- for (const auto& [key, value] : Items) {
- if (upToKey < key) {
- break;
- }
- TString name;
- if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
- name = field->options().GetExtension(NActorsInterconnect::PrintName);
- } else {
- name = ::ToString(int(key));
- }
- if (key != upToKey) {
- res << name << "=" << value << "/";
- } else {
- res << value;
- }
- }
- return res;
- }
- void TNodeLocation::Serialize(NActorsInterconnect::TNodeLocation *pb) const {
- const NProtoBuf::Descriptor *descriptor = NActorsInterconnect::TNodeLocation::descriptor();
- const NProtoBuf::Reflection *reflection = pb->GetReflection();
- NProtoBuf::UnknownFieldSet *unknown = pb->mutable_unknown_fields();
- for (const auto& [key, value] : Items) {
- if (const NProtoBuf::FieldDescriptor *field = descriptor->FindFieldByNumber(key)) {
- reflection->SetString(pb, field, value);
- } else {
- unknown->AddLengthDelimited(key)->assign(value);
- }
- }
- }
- TString TNodeLocation::GetSerializedLocation() const {
- NActorsInterconnect::TNodeLocation pb;
- Serialize(&pb);
- TString s;
- const bool success = pb.SerializeToString(&s);
- Y_VERIFY(success);
- return s;
- }
- TNodeLocation::TLegacyValue TNodeLocation::GetLegacyValue() const {
- if (LegacyValue) {
- return *LegacyValue;
- }
- ui32 dataCenterId = 0, moduleId = 0, rackId = 0, unitId = 0;
- for (const auto& [key, value] : Items) {
- switch (key) {
- case TKeys::DataCenter:
- memcpy(&dataCenterId, value.data(), Min<size_t>(sizeof(dataCenterId), value.length()));
- break;
- case TKeys::Module: {
- const bool success = TryFromString(value, moduleId);
- Y_VERIFY(success);
- break;
- }
- case TKeys::Rack:
- // hacky way to obtain numeric id by a rack name
- if (!TryFromString(value, rackId)) {
- rackId = MurmurHash<ui32>(value.data(), value.length());
- }
- break;
- case TKeys::Unit: {
- const bool success = TryFromString(value, unitId);
- Y_VERIFY(success);
- break;
- }
- default:
- Y_FAIL("unexpected legacy key# %d", key);
- }
- }
- return {dataCenterId, moduleId, rackId, unitId};
- }
- } // NActors
|