Browse Source

Common TChangeRecord in ydb/core/change_exchange (#737)

Ilnaz Nizametdinov 1 year ago
parent
commit
25431f4941

+ 90 - 0
ydb/core/change_exchange/change_record.cpp

@@ -0,0 +1,90 @@
+#include "change_record.h"
+
+#include <ydb/core/protos/change_exchange.pb.h>
+
+namespace NKikimr::NChangeExchange {
+
+void TChangeRecord::Serialize(NKikimrChangeExchange::TChangeRecord& record) const {
+    record.SetOrder(Order);
+    record.SetGroup(Group);
+    record.SetStep(Step);
+    record.SetTxId(TxId);
+
+    switch (Kind) {
+        case EKind::AsyncIndex: {
+            Y_ABORT_UNLESS(record.MutableAsyncIndex()->ParseFromArray(Body.data(), Body.size()));
+            break;
+        }
+        case EKind::CdcDataChange: {
+            Y_ABORT_UNLESS(record.MutableCdcDataChange()->ParseFromArray(Body.data(), Body.size()));
+            break;
+        }
+        case EKind::CdcHeartbeat: {
+            break;
+        }
+    }
+}
+
+static auto ParseBody(const TString& protoBody) {
+    NKikimrChangeExchange::TDataChange body;
+    Y_ABORT_UNLESS(body.ParseFromArray(protoBody.data(), protoBody.size()));
+    return body;
+}
+
+TConstArrayRef<TCell> TChangeRecord::GetKey() const {
+    if (Key) {
+        return *Key;
+    }
+
+    switch (Kind) {
+        case EKind::AsyncIndex:
+        case EKind::CdcDataChange: {
+            const auto parsed = ParseBody(Body);
+
+            TSerializedCellVec key;
+            Y_ABORT_UNLESS(TSerializedCellVec::TryParse(parsed.GetKey().GetData(), key));
+
+            Key.ConstructInPlace(key.GetCells());
+            break;
+        }
+
+        case EKind::CdcHeartbeat: {
+            Y_ABORT("Not supported");
+        }
+    }
+
+    Y_ABORT_UNLESS(Key);
+    return *Key;
+}
+
+i64 TChangeRecord::GetSeqNo() const {
+    Y_ABORT_UNLESS(Order <= Max<i64>());
+    return static_cast<i64>(Order);
+}
+
+TInstant TChangeRecord::GetApproximateCreationDateTime() const {
+    return GetGroup()
+        ? TInstant::MicroSeconds(GetGroup())
+        : TInstant::MilliSeconds(GetStep());
+}
+
+TString TChangeRecord::ToString() const {
+    TString result;
+    TStringOutput out(result);
+    Out(out);
+    return result;
+}
+
+void TChangeRecord::Out(IOutputStream& out) const {
+    out << "{"
+        << " Order: " << Order
+        << " Group: " << Group
+        << " Step: " << Step
+        << " TxId: " << TxId
+        << " Kind: " << Kind
+        << " Source: " << Source
+        << " Body: " << Body.size() << "b"
+    << " }";
+}
+
+}

+ 127 - 0
ydb/core/change_exchange/change_record.h

@@ -0,0 +1,127 @@
+#pragma once
+
+#include <ydb/core/scheme/scheme_tablecell.h>
+
+#include <util/generic/maybe.h>
+#include <util/generic/string.h>
+
+namespace NKikimrChangeExchange {
+    class TChangeRecord;
+}
+
+namespace NKikimr::NChangeExchange {
+
+template <typename T, typename TDerived> class TChangeRecordBuilder;
+
+class TChangeRecord {
+    template <typename T, typename TDerived> friend class TChangeRecordBuilder;
+
+public:
+    enum class ESource: ui8 {
+        Unspecified = 0,
+        InitialScan = 1,
+    };
+
+    enum class EKind: ui8 {
+        AsyncIndex,
+        CdcDataChange,
+        CdcHeartbeat,
+    };
+
+public:
+    ui64 GetOrder() const { return Order; }
+    ui64 GetGroup() const { return Group; }
+    ui64 GetStep() const { return Step; }
+    ui64 GetTxId() const { return TxId; }
+    EKind GetKind() const { return Kind; }
+    const TString& GetBody() const { return Body; }
+    ESource GetSource() const { return Source; }
+
+    void Serialize(NKikimrChangeExchange::TChangeRecord& record) const;
+
+    TConstArrayRef<TCell> GetKey() const;
+    i64 GetSeqNo() const;
+    TInstant GetApproximateCreationDateTime() const;
+
+    TString ToString() const;
+    void Out(IOutputStream& out) const;
+
+protected:
+    ui64 Order = Max<ui64>();
+    ui64 Group = 0;
+    ui64 Step = 0;
+    ui64 TxId = 0;
+    EKind Kind;
+    TString Body;
+    ESource Source = ESource::Unspecified;
+
+    mutable TMaybe<TOwnedCellVec> Key;
+    mutable TMaybe<TString> PartitionKey;
+
+}; // TChangeRecord
+
+template <typename T, typename TDerived>
+class TChangeRecordBuilder {
+protected:
+    using TSelf = TDerived;
+    using EKind = TChangeRecord::EKind;
+    using ESource = TChangeRecord::ESource;
+
+public:
+    explicit TChangeRecordBuilder(EKind kind) {
+        Record.Kind = kind;
+    }
+
+    explicit TChangeRecordBuilder(T&& record) {
+        Record = std::move(record);
+    }
+
+    TSelf& WithOrder(ui64 order) {
+        Record.Order = order;
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithGroup(ui64 group) {
+        Record.Group = group;
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithStep(ui64 step) {
+        Record.Step = step;
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithTxId(ui64 txId) {
+        Record.TxId = txId;
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithBody(const TString& body) {
+        Record.Body = body;
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithBody(TString&& body) {
+        Record.Body = std::move(body);
+        return static_cast<TSelf&>(*this);
+    }
+
+    TSelf& WithSource(ESource source) {
+        Record.Source = source;
+        return static_cast<TSelf&>(*this);
+    }
+
+    T&& Build() {
+        return std::move(Record);
+    }
+
+protected:
+    T Record;
+
+}; // TChangeRecordBuilder
+
+}
+
+Y_DECLARE_OUT_SPEC(inline, NKikimr::NChangeExchange::TChangeRecord, out, value) {
+    return value.Out(out);
+}

+ 16 - 0
ydb/core/change_exchange/ya.make

@@ -0,0 +1,16 @@
+LIBRARY()
+
+SRCS(
+    change_record.cpp
+)
+
+GENERATE_ENUM_SERIALIZATION(change_record.h)
+
+PEERDIR(
+    ydb/core/protos
+    ydb/core/scheme
+)
+
+YQL_LAST_ABI_VERSION()
+
+END()

+ 1 - 68
ydb/core/tx/datashard/change_record.cpp

@@ -5,69 +5,9 @@
 namespace NKikimr::NDataShard {
 
 void TChangeRecord::Serialize(NKikimrChangeExchange::TChangeRecord& record) const {
-    record.SetOrder(Order);
-    record.SetGroup(Group);
-    record.SetStep(Step);
-    record.SetTxId(TxId);
+    NChangeExchange::TChangeRecord::Serialize(record);
     record.SetPathOwnerId(PathId.OwnerId);
     record.SetLocalPathId(PathId.LocalPathId);
-
-    switch (Kind) {
-        case EKind::AsyncIndex: {
-            Y_ABORT_UNLESS(record.MutableAsyncIndex()->ParseFromArray(Body.data(), Body.size()));
-            break;
-        }
-        case EKind::CdcDataChange: {
-            Y_ABORT_UNLESS(record.MutableCdcDataChange()->ParseFromArray(Body.data(), Body.size()));
-            break;
-        }
-        case EKind::CdcHeartbeat: {
-            break;
-        }
-    }
-}
-
-static auto ParseBody(const TString& protoBody) {
-    NKikimrChangeExchange::TDataChange body;
-    Y_ABORT_UNLESS(body.ParseFromArray(protoBody.data(), protoBody.size()));
-    return body;
-}
-
-TConstArrayRef<TCell> TChangeRecord::GetKey() const {
-    if (Key) {
-        return *Key;
-    }
-
-    switch (Kind) {
-        case EKind::AsyncIndex:
-        case EKind::CdcDataChange: {
-            const auto parsed = ParseBody(Body);
-
-            TSerializedCellVec key;
-            Y_ABORT_UNLESS(TSerializedCellVec::TryParse(parsed.GetKey().GetData(), key));
-
-            Key.ConstructInPlace(key.GetCells());
-            break;
-        }
-
-        case EKind::CdcHeartbeat: {
-            Y_ABORT("Not supported");
-        }
-    }
-
-    Y_ABORT_UNLESS(Key);
-    return *Key;
-}
-
-i64 TChangeRecord::GetSeqNo() const {
-    Y_ABORT_UNLESS(Order <= Max<i64>());
-    return static_cast<i64>(Order);
-}
-
-TInstant TChangeRecord::GetApproximateCreationDateTime() const {
-    return GetGroup()
-        ? TInstant::MicroSeconds(GetGroup())
-        : TInstant::MilliSeconds(GetStep());
 }
 
 bool TChangeRecord::IsBroadcast() const {
@@ -79,13 +19,6 @@ bool TChangeRecord::IsBroadcast() const {
     }
 }
 
-TString TChangeRecord::ToString() const {
-    TString result;
-    TStringOutput out(result);
-    Out(out);
-    return result;
-}
-
 void TChangeRecord::Out(IOutputStream& out) const {
     out << "{"
         << " Order: " << Order

+ 16 - 108
ydb/core/tx/datashard/change_record.h

@@ -2,46 +2,20 @@
 
 #include "datashard_user_table.h"
 
+#include <ydb/core/change_exchange/change_record.h>
 #include <ydb/core/scheme/scheme_pathid.h>
-#include <ydb/core/scheme/scheme_tablecell.h>
-
-#include <util/generic/maybe.h>
-#include <util/generic/string.h>
-
-namespace NKikimrChangeExchange {
-    class TChangeRecord;
-}
 
 namespace NKikimr::NDataShard {
 
 class TChangeRecordBuilder;
 
-class TChangeRecord {
+class TChangeRecord: public NChangeExchange::TChangeRecord {
     friend class TChangeRecordBuilder;
 
 public:
-    enum class ESource: ui8 {
-        Unspecified = 0,
-        InitialScan = 1,
-    };
-
-    enum class EKind: ui8 {
-        AsyncIndex,
-        CdcDataChange,
-        CdcHeartbeat,
-    };
-
-public:
-    ui64 GetOrder() const { return Order; }
-    ui64 GetGroup() const { return Group; }
-    ui64 GetStep() const { return Step; }
-    ui64 GetTxId() const { return TxId; }
     ui64 GetLockId() const { return LockId; }
     ui64 GetLockOffset() const { return LockOffset; }
     const TPathId& GetPathId() const { return PathId; }
-    EKind GetKind() const { return Kind; }
-    const TString& GetBody() const { return Body; }
-    ESource GetSource() const { return Source; }
 
     const TPathId& GetTableId() const { return TableId; }
     ui64 GetSchemaVersion() const { return SchemaVersion; }
@@ -49,122 +23,56 @@ public:
 
     void Serialize(NKikimrChangeExchange::TChangeRecord& record) const;
 
-    TConstArrayRef<TCell> GetKey() const;
-    i64 GetSeqNo() const;
     TString GetPartitionKey() const;
-    TInstant GetApproximateCreationDateTime() const;
     bool IsBroadcast() const;
 
-    TString ToString() const;
     void Out(IOutputStream& out) const;
 
 private:
-    ui64 Order = Max<ui64>();
-    ui64 Group = 0;
-    ui64 Step = 0;
-    ui64 TxId = 0;
     ui64 LockId = 0;
     ui64 LockOffset = 0;
     TPathId PathId;
-    EKind Kind;
-    TString Body;
-    ESource Source = ESource::Unspecified;
 
     ui64 SchemaVersion;
     TPathId TableId;
     TUserTable::TCPtr Schema;
 
-    mutable TMaybe<TOwnedCellVec> Key;
-    mutable TMaybe<TString> PartitionKey;
-
 }; // TChangeRecord
 
-class TChangeRecordBuilder {
-    using EKind = TChangeRecord::EKind;
-    using ESource = TChangeRecord::ESource;
-
+class TChangeRecordBuilder: public NChangeExchange::TChangeRecordBuilder<TChangeRecord, TChangeRecordBuilder> {
 public:
-    explicit TChangeRecordBuilder(EKind kind) {
-        Record.Kind = kind;
-    }
-
-    explicit TChangeRecordBuilder(TChangeRecord&& record)
-        : Record(std::move(record))
-    {
-    }
+    using NChangeExchange::TChangeRecordBuilder<TChangeRecord, TChangeRecordBuilder>::TChangeRecordBuilder;
 
-    TChangeRecordBuilder& WithLockId(ui64 lockId) {
+    TSelf& WithLockId(ui64 lockId) {
         Record.LockId = lockId;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecordBuilder& WithLockOffset(ui64 lockOffset) {
+    TSelf& WithLockOffset(ui64 lockOffset) {
         Record.LockOffset = lockOffset;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithOrder(ui64 order) {
-        Record.Order = order;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithGroup(ui64 group) {
-        Record.Group = group;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecordBuilder& WithStep(ui64 step) {
-        Record.Step = step;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithTxId(ui64 txId) {
-        Record.TxId = txId;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithPathId(const TPathId& pathId) {
+    TSelf& WithPathId(const TPathId& pathId) {
         Record.PathId = pathId;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecordBuilder& WithTableId(const TPathId& tableId) {
+    TSelf& WithTableId(const TPathId& tableId) {
         Record.TableId = tableId;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecordBuilder& WithSchemaVersion(ui64 version) {
+    TSelf& WithSchemaVersion(ui64 version) {
         Record.SchemaVersion = version;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecordBuilder& WithSchema(TUserTable::TCPtr schema) {
+    TSelf& WithSchema(TUserTable::TCPtr schema) {
         Record.Schema = schema;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithBody(const TString& body) {
-        Record.Body = body;
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithBody(TString&& body) {
-        Record.Body = std::move(body);
-        return *this;
-    }
-
-    TChangeRecordBuilder& WithSource(ESource source) {
-        Record.Source = source;
-        return *this;
+        return static_cast<TSelf&>(*this);
     }
 
-    TChangeRecord&& Build() {
-        return std::move(Record);
-    }
-
-private:
-    TChangeRecord Record;
-
 }; // TChangeRecordBuilder
 
 }

+ 1 - 0
ydb/core/tx/datashard/ya.make

@@ -235,6 +235,7 @@ PEERDIR(
     library/cpp/string_utils/quote
     ydb/core/actorlib_impl
     ydb/core/base
+    ydb/core/change_exchange
     ydb/core/engine
     ydb/core/engine/minikql
     ydb/core/formats

+ 1 - 0
ydb/core/ya.make

@@ -4,6 +4,7 @@ RECURSE(
     blobstorage
     blob_depot
     blockstore
+    change_exchange
     client
     cms
     control