123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- #pragma once
- #include "defs.h"
- #include <util/stream/output.h> // for IOutputStream
- #include <util/generic/hash.h>
- namespace NActors {
- // used as global uniq address of actor
- // also could be used to transport service id (12 byte strings placed in hint-localid)
- // highest 1 bit of node - mark of service id
- // next 11 bits of node-id - pool id
- // next 20 bits - node id itself
- struct TActorId {
- static constexpr ui32 MaxServiceIDLength = 12;
- static constexpr ui32 MaxPoolID = 0x000007FF;
- static constexpr ui32 MaxNodeId = 0x000FFFFF;
- static constexpr ui32 PoolIndexShift = 20;
- static constexpr ui32 PoolIndexMask = MaxPoolID << PoolIndexShift;
- static constexpr ui32 ServiceMask = 0x80000000;
- static constexpr ui32 NodeIdMask = MaxNodeId;
- private:
- union {
- struct {
- ui64 LocalId;
- ui32 Hint;
- ui32 NodeId;
- } N;
- struct {
- ui64 X1;
- ui64 X2;
- } X;
- ui8 Buf[16];
- } Raw;
- public:
- TActorId() noexcept {
- Raw.X.X1 = 0;
- Raw.X.X2 = 0;
- }
- explicit TActorId(ui32 nodeId, ui32 poolId, ui64 localId, ui32 hint) noexcept {
- Y_VERIFY_DEBUG(poolId <= MaxPoolID);
- Raw.N.LocalId = localId;
- Raw.N.Hint = hint;
- Raw.N.NodeId = nodeId | (poolId << PoolIndexShift);
- }
- explicit TActorId(ui32 nodeId, const TStringBuf& x) noexcept {
- Y_ABORT_UNLESS(x.size() <= MaxServiceIDLength, "service id is too long");
- Raw.N.LocalId = 0;
- Raw.N.Hint = 0;
- Raw.N.NodeId = nodeId | ServiceMask;
- memcpy(Raw.Buf, x.data(), x.size());
- }
- explicit TActorId(ui64 x1, ui64 x2) noexcept {
- Raw.X.X1 = x1;
- Raw.X.X2 = x2;
- }
- explicit operator bool() const noexcept {
- return Raw.X.X1 != 0 || Raw.X.X2 != 0;
- }
- ui64 LocalId() const noexcept {
- return Raw.N.LocalId;
- }
- ui32 Hint() const noexcept {
- return Raw.N.Hint;
- }
- ui32 NodeId() const noexcept {
- return Raw.N.NodeId & NodeIdMask;
- }
- bool IsService() const noexcept {
- return (Raw.N.NodeId & ServiceMask);
- }
- TStringBuf ServiceId() const noexcept {
- Y_VERIFY_DEBUG(IsService());
- return TStringBuf((const char*)Raw.Buf, MaxServiceIDLength);
- }
- static ui32 PoolIndex(ui32 nodeid) noexcept {
- return ((nodeid & PoolIndexMask) >> PoolIndexShift);
- }
- ui32 PoolID() const noexcept {
- return PoolIndex(Raw.N.NodeId);
- }
- ui64 RawX1() const noexcept {
- return Raw.X.X1;
- }
- ui64 RawX2() const noexcept {
- return Raw.X.X2;
- }
- bool operator<(const TActorId& x) const noexcept {
- const ui64 s1 = Raw.X.X1;
- const ui64 s2 = Raw.X.X2;
- const ui64 x1 = x.Raw.X.X1;
- const ui64 x2 = x.Raw.X.X2;
- return (s1 != x1) ? (s1 < x1) : (s2 < x2);
- }
- bool operator!=(const TActorId& x) const noexcept {
- return Raw.X.X1 != x.Raw.X.X1 || Raw.X.X2 != x.Raw.X.X2;
- }
- bool operator==(const TActorId& x) const noexcept {
- return !(x != *this);
- }
- ui64 Hash() const noexcept {
- const ui32* x = (const ui32*)Raw.Buf;
- const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull;
- const ui64 x2 = x[1] * 0x179CA10C9242235Dull;
- const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull;
- const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull;
- const ui64 z1 = x1 + x2;
- const ui64 z2 = x3 + x4;
- const ui64 sum = 0x5851F42D4C957F2D + z1 + z2;
- return (sum >> 32) | (sum << 32);
- }
- ui32 Hash32() const noexcept {
- const ui32* x = (const ui32*)Raw.Buf;
- const ui64 x1 = x[0] * 0x001DFF3D8DC48F5Dull;
- const ui64 x2 = x[1] * 0x179CA10C9242235Dull;
- const ui64 x3 = x[2] * 0x0F530CAD458B0FB1ull;
- const ui64 x4 = x[3] * 0xB5026F5AA96619E9ull;
- const ui64 z1 = x1 + x2;
- const ui64 z2 = x3 + x4;
- const ui64 sum = 0x5851F42D4C957F2D + z1 + z2;
- return sum >> 32;
- }
- struct THash {
- ui64 operator()(const TActorId& actorId) const noexcept {
- return actorId.Hash();
- }
- };
- struct THash32 {
- ui64 operator()(const TActorId& actorId) const noexcept {
- return actorId.Hash();
- }
- };
- struct TOrderedCmp {
- bool operator()(const TActorId &left, const TActorId &right) const noexcept {
- Y_VERIFY_DEBUG(!left.IsService() && !right.IsService(), "ordered compare works for plain actorids only");
- const ui32 n1 = left.NodeId();
- const ui32 n2 = right.NodeId();
- return (n1 != n2) ? (n1 < n2) : left.LocalId() < right.LocalId();
- }
- };
- TString ToString() const;
- void Out(IOutputStream& o) const;
- bool Parse(const char* buf, ui32 sz);
- };
- static_assert(sizeof(TActorId) == 16, "expect sizeof(TActorId) == 16");
- static_assert(MaxPools < TActorId::MaxPoolID); // current implementation of united pool has limit MaxPools on pool id
- }
- template <>
- inline void Out<NActors::TActorId>(IOutputStream& o, const NActors::TActorId& x) {
- return x.Out(o);
- }
- template <>
- struct THash<NActors::TActorId> {
- inline ui64 operator()(const NActors::TActorId& x) const {
- return x.Hash();
- }
- };
- template<> struct std::hash<NActors::TActorId> : THash<NActors::TActorId> {};
|