node.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #pragma once
  2. #include <yql/essentials/public/udf/udf_value_builder.h>
  3. #include <yql/essentials/public/udf/udf_value.h>
  4. namespace NYql::NDom {
  5. using namespace NUdf;
  6. constexpr char NodeResourceName[] = "Yson2.Node";
  7. using TPair = std::pair<TUnboxedValue, TUnboxedValue>;
  8. enum class ENodeType : ui8 {
  9. String = 0,
  10. Bool = 1,
  11. Int64 = 2,
  12. Uint64 = 3,
  13. Double = 4,
  14. Entity = 5,
  15. List = 6,
  16. Dict = 7,
  17. Attr = 8,
  18. };
  19. constexpr ui8 NodeTypeShift = 4;
  20. constexpr ui8 NodeTypeMask = 0xf0;
  21. template<ENodeType type>
  22. constexpr inline TUnboxedValuePod SetNodeType(TUnboxedValuePod node) {
  23. const auto buffer = reinterpret_cast<ui8*>(&node);
  24. buffer[TUnboxedValuePod::InternalBufferSize] = ui8(type) << NodeTypeShift;
  25. return node;
  26. }
  27. template<ENodeType type>
  28. constexpr inline bool IsNodeType(const TUnboxedValuePod node) {
  29. const auto buffer = reinterpret_cast<const ui8*>(&node);
  30. const auto currentMask = buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask;
  31. constexpr ui8 expectedMask = static_cast<ui8>(type) << NodeTypeShift;
  32. return currentMask == expectedMask;
  33. }
  34. inline ENodeType GetNodeType(const TUnboxedValuePod& node) {
  35. const auto* buffer = reinterpret_cast<const char*>(&node);
  36. const ui8 flag = (buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask) >> NodeTypeShift;
  37. return static_cast<ENodeType>(flag);
  38. }
  39. inline bool IsNodeType(const TUnboxedValuePod& node, ENodeType type) {
  40. const auto* buffer = reinterpret_cast<const char*>(&node);
  41. const ui8 currentMask = buffer[TUnboxedValuePod::InternalBufferSize] & NodeTypeMask;
  42. const ui8 expectedMask = static_cast<ui8>(type) << NodeTypeShift;
  43. return currentMask == expectedMask;
  44. }
  45. class TMapNode : public TManagedBoxedValue {
  46. public:
  47. template <bool NoSwap>
  48. class TIterator: public TManagedBoxedValue {
  49. public:
  50. TIterator(const TMapNode* parent);
  51. private:
  52. bool Skip() final;
  53. bool Next(TUnboxedValue& key) final;
  54. bool NextPair(TUnboxedValue& key, TUnboxedValue& payload) final;
  55. const TRefCountedPtr<TMapNode> Parent;
  56. ui32 Index;
  57. };
  58. TMapNode(const TPair* items, ui32 count);
  59. TMapNode(TMapNode&& src);
  60. ~TMapNode();
  61. TUnboxedValue Lookup(const TStringRef& key) const;
  62. private:
  63. ui64 GetDictLength() const final;
  64. TUnboxedValue GetDictIterator() const final;
  65. TUnboxedValue GetKeysIterator() const final;
  66. TUnboxedValue GetPayloadsIterator() const final;
  67. bool Contains(const TUnboxedValuePod& key) const final;
  68. TUnboxedValue Lookup(const TUnboxedValuePod& key) const final;
  69. bool HasDictItems() const final;
  70. bool IsSortedDict() const final;
  71. TStringRef GetResourceTag() const final;
  72. void* GetResource() final;
  73. ui32 Count_;
  74. ui32 UniqueCount_;
  75. TPair * Items_;
  76. };
  77. class TAttrNode : public TMapNode {
  78. public:
  79. TAttrNode(const TUnboxedValue& map, NUdf::TUnboxedValue&& value);
  80. TAttrNode(NUdf::TUnboxedValue&& value, const TPair* items, ui32 count);
  81. NUdf::TUnboxedValue GetVariantItem() const final;
  82. private:
  83. const NUdf::TUnboxedValue Value_;
  84. };
  85. inline TUnboxedValuePod MakeAttr(TUnboxedValue&& value, TPair* items, ui32 count) {
  86. if (count == 0) {
  87. return value.Release();
  88. }
  89. return SetNodeType<ENodeType::Attr>(TUnboxedValuePod(new TAttrNode(std::move(value), items, count)));
  90. }
  91. inline TUnboxedValuePod MakeString(const TStringBuf value, const IValueBuilder* valueBuilder) {
  92. return valueBuilder->NewString(value).Release();
  93. }
  94. inline TUnboxedValuePod MakeBool(bool value) {
  95. return SetNodeType<ENodeType::Bool>(TUnboxedValuePod(value));
  96. }
  97. inline TUnboxedValuePod MakeInt64(i64 value) {
  98. return SetNodeType<ENodeType::Int64>(TUnboxedValuePod(value));
  99. }
  100. inline TUnboxedValuePod MakeUint64(ui64 value) {
  101. return SetNodeType<ENodeType::Uint64>(TUnboxedValuePod(value));
  102. }
  103. inline TUnboxedValuePod MakeDouble(double value) {
  104. return SetNodeType<ENodeType::Double>(TUnboxedValuePod(value));
  105. }
  106. inline TUnboxedValuePod MakeEntity() {
  107. return SetNodeType<ENodeType::Entity>(TUnboxedValuePod::Zero());
  108. }
  109. inline TUnboxedValuePod MakeList(TUnboxedValue* items, ui32 count, const IValueBuilder* valueBuilder) {
  110. return SetNodeType<ENodeType::List>(count > 0U ? valueBuilder->NewList(items, count).Release() : TUnboxedValuePod::Zero());
  111. }
  112. inline TUnboxedValuePod MakeDict(const TPair* items, ui32 count) {
  113. return SetNodeType<ENodeType::Dict>(count > 0U ? TUnboxedValuePod(new TMapNode(items, count)) : TUnboxedValuePod::Zero());
  114. }
  115. struct TDebugPrinter {
  116. TDebugPrinter(const TUnboxedValuePod& node);
  117. class IOutputStream& Out(class IOutputStream &o) const;
  118. const TUnboxedValuePod& Node;
  119. };
  120. }
  121. template<>
  122. inline void Out<NYql::NDom::TDebugPrinter>(class IOutputStream &o, const NYql::NDom::TDebugPrinter& p) {
  123. p.Out(o);
  124. }