aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-04-20 13:49:33 +0300
committerarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-04-20 13:49:33 +0300
commitd85809f7b86d53a83de4744b395e61df085e727f (patch)
tree32093c9bdbaa6c4ab42f34f38cfb6f401ec46d4d
parentf8b13db877cf0234f2bdf7092164f57eebc52aa1 (diff)
downloadydb-d85809f7b86d53a83de4744b395e61df085e727f.tar.gz
intermediate changes
ref:95923961b070d9d9b37fcb1d21bffeae90f3d022
-rw-r--r--build/rules/autocheck.blacklist1
-rw-r--r--library/cpp/scheme/scheme.cpp57
-rw-r--r--library/cpp/scheme/scheme.h26
-rw-r--r--library/cpp/scheme/tests/ut/scheme_merge_ut.cpp63
4 files changed, 123 insertions, 24 deletions
diff --git a/build/rules/autocheck.blacklist b/build/rules/autocheck.blacklist
index 245860e713..83fedcaa5c 100644
--- a/build/rules/autocheck.blacklist
+++ b/build/rules/autocheck.blacklist
@@ -1342,3 +1342,4 @@ classifieds/php-catalog-cron
adv/pcode/mobileadssdk/tests/mock-data
weather/frontend
distribution_interface/chrome-nano
+distribution_interface/slices-new
diff --git a/library/cpp/scheme/scheme.cpp b/library/cpp/scheme/scheme.cpp
index 3efd116d4f..e6b59e8346 100644
--- a/library/cpp/scheme/scheme.cpp
+++ b/library/cpp/scheme/scheme.cpp
@@ -28,39 +28,39 @@ namespace NSc {
return bufs;
}
- TValue& TValue::MergeUpdate(const TValue& delta) {
- return DoMerge(delta, false);
+ TValue& TValue::MergeUpdate(const TValue& delta, TMaybe<TMergeOptions> mergeOptions) {
+ return DoMerge(delta, false, mergeOptions);
}
- TValue& TValue::ReverseMerge(const TValue& delta) {
- return DoMerge(delta, true);
+ TValue& TValue::ReverseMerge(const TValue& delta, TMaybe<TMergeOptions> mergeOptions) {
+ return DoMerge(delta, true, mergeOptions);
}
- TValue& TValue::MergeUpdateJson(TStringBuf data) {
- return MergeUpdate(FromJson(data));
+ TValue& TValue::MergeUpdateJson(TStringBuf data, TMaybe<TMergeOptions> mergeOptions) {
+ return MergeUpdate(FromJson(data), mergeOptions);
}
- TValue& TValue::ReverseMergeJson(TStringBuf data) {
- return ReverseMerge(FromJson(data));
+ TValue& TValue::ReverseMergeJson(TStringBuf data, TMaybe<TMergeOptions> mergeOptions) {
+ return ReverseMerge(FromJson(data), mergeOptions);
}
- bool TValue::MergeUpdateJson(TValue& v, TStringBuf data) {
+ bool TValue::MergeUpdateJson(TValue& v, TStringBuf data, TMaybe<TMergeOptions> mergeOptions) {
NSc::TValue m;
if (!FromJson(m, data)) {
return false;
}
- v.MergeUpdate(m);
+ v.MergeUpdate(m, mergeOptions);
return true;
}
- bool TValue::ReverseMergeJson(TValue& v, TStringBuf data) {
+ bool TValue::ReverseMergeJson(TValue& v, TStringBuf data, TMaybe<TMergeOptions> mergeOptions) {
NSc::TValue m;
if (!FromJson(m, data)) {
return false;
}
- v.ReverseMerge(m);
+ v.ReverseMerge(m, mergeOptions);
return true;
}
@@ -290,22 +290,24 @@ namespace NSc {
return true;
}
- TValue& TValue::DoMerge(const TValue& delta, bool lowPriorityDelta) {
+ TValue& TValue::DoMerge(const TValue& delta, bool lowPriorityDelta, TMaybe<TMergeOptions> mergeOptions) {
if (Same(*this, delta)) {
return *this;
}
using namespace NImpl;
- return DoMergeImpl(delta, lowPriorityDelta, GetTlsInstance<TSelfLoopContext>(), GetTlsInstance<TSelfOverrideContext>());
+ return DoMergeImpl(delta, lowPriorityDelta, mergeOptions, GetTlsInstance<TSelfLoopContext>(), GetTlsInstance<TSelfOverrideContext>());
}
- TValue& TValue::DoMergeImpl(const TValue& delta, bool lowPriorityDelta,
+ TValue& TValue::DoMergeImpl(const TValue& delta, bool lowPriorityDelta, TMaybe<TMergeOptions> mergeOptions,
NImpl::TSelfLoopContext& otherLoopCtx,
NImpl::TSelfOverrideContext& selfOverrideGuard) {
if (Same(*this, delta)) {
return *this;
}
+ bool allowMergeArray = mergeOptions.Defined() && mergeOptions->ArrayMergeMode == TMergeOptions::EArrayMergeMode::Merge;
+
if (delta.IsDict() && (!lowPriorityDelta || IsDict() || IsNull())) {
TScCore& core = CoreMutable();
const TScCore& deltaCore = delta.Core();
@@ -323,7 +325,30 @@ namespace NSc {
const TDict& ddelta = deltaCore.Dict;
for (const auto& dit : ddelta) {
- core.GetOrAdd(dit.first).DoMergeImpl(dit.second, lowPriorityDelta, otherLoopCtx, selfOverrideGuard);
+ core.GetOrAdd(dit.first).DoMergeImpl(dit.second, lowPriorityDelta, mergeOptions, otherLoopCtx, selfOverrideGuard);
+ }
+ } else if (delta.IsArray() && allowMergeArray && (!lowPriorityDelta || IsArray() || IsNull())) {
+ TScCore& core = CoreMutable();
+ const TScCore& deltaCore = delta.Core();
+
+ NImpl::TSelfLoopContext::TGuard loopCheck(otherLoopCtx, deltaCore);
+
+ if (!loopCheck.Ok) {
+ return *this; // a loop encountered (and asserted), skip the back reference
+ }
+
+ if (!lowPriorityDelta || IsNull()) {
+ SetArray();
+ }
+
+ Y_ASSERT(IsArray());
+
+ const TArray& adelta = deltaCore.Array;
+ if (adelta.size() > core.Array.size()) {
+ core.Array.resize(adelta.size());
+ }
+ for (size_t i = 0; i < adelta.size(); ++i) {
+ core.Array[i].DoMergeImpl(adelta[i], lowPriorityDelta, mergeOptions, otherLoopCtx, selfOverrideGuard);
}
} else if (!delta.IsNull() && (!lowPriorityDelta || IsNull())) {
DoCopyFromImpl(delta, otherLoopCtx, selfOverrideGuard);
diff --git a/library/cpp/scheme/scheme.h b/library/cpp/scheme/scheme.h
index cc0699c67a..b4cb98c967 100644
--- a/library/cpp/scheme/scheme.h
+++ b/library/cpp/scheme/scheme.h
@@ -4,6 +4,8 @@
#include "fwd.h"
+#include <util/generic/maybe.h>
+
#include <iterator>
#include <utility>
@@ -12,6 +14,14 @@ namespace NSc {
#pragma warning(disable : 4521 4522)
#endif
+ struct TMergeOptions {
+ enum class EArrayMergeMode {
+ Replace,
+ Merge
+ };
+ EArrayMergeMode ArrayMergeMode = EArrayMergeMode::Replace;
+ };
+
// todo: try to remove some rarely used methods
class TValue {
public:
@@ -341,14 +351,14 @@ namespace NSc {
* - Do nothing.
*/
- TValue& MergeUpdateJson(TStringBuf json); // returns self
- TValue& ReverseMergeJson(TStringBuf json); // returns self
+ TValue& MergeUpdateJson(TStringBuf json, TMaybe<TMergeOptions> mergeOptions = {}); // returns self
+ TValue& ReverseMergeJson(TStringBuf json, TMaybe<TMergeOptions> mergeOptions = {}); // returns self
- static bool MergeUpdateJson(TValue&, TStringBuf json); // returns true unless failed to parse the json
- static bool ReverseMergeJson(TValue&, TStringBuf json); // returns true unless failed to parse the json
+ static bool MergeUpdateJson(TValue&, TStringBuf json, TMaybe<TMergeOptions> mergeOptions = {}); // returns true unless failed to parse the json
+ static bool ReverseMergeJson(TValue&, TStringBuf json, TMaybe<TMergeOptions> mergeOptions = {}); // returns true unless failed to parse the json
- TValue& MergeUpdate(const TValue& delta); // return self
- TValue& ReverseMerge(const TValue& delta); // return self
+ TValue& MergeUpdate(const TValue& delta, TMaybe<TMergeOptions> mergeOptions = {}); // return self
+ TValue& ReverseMerge(const TValue& delta, TMaybe<TMergeOptions> mergeOptions = {}); // return self
public: // Path methods /////////////////////////////////////////////////////////
// TODO: add throwing variants
@@ -405,8 +415,8 @@ namespace NSc {
bool IsSameOrAncestorOf(const TValue& other) const;
private:
- TValue& DoMerge(const TValue& delta, bool olddelta);
- TValue& DoMergeImpl(const TValue& delta, bool olddelta, NImpl::TSelfLoopContext&, NImpl::TSelfOverrideContext&);
+ TValue& DoMerge(const TValue& delta, bool olddelta, TMaybe<TMergeOptions> mergeOptions);
+ TValue& DoMergeImpl(const TValue& delta, bool olddelta, TMaybe<TMergeOptions> mergeOptions, NImpl::TSelfLoopContext&, NImpl::TSelfOverrideContext&);
TValue& DoCopyFromImpl(const TValue& other, NImpl::TSelfLoopContext&, NImpl::TSelfOverrideContext&);
NJson::TJsonValue ToJsonValueImpl(NImpl::TSelfLoopContext&) const;
diff --git a/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp b/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp
index 2a06cf110d..38c5283383 100644
--- a/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp
+++ b/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp
@@ -169,4 +169,67 @@ Y_UNIT_TEST_SUITE(TSchemeMergeTest) {
UNIT_ASSERT_JSON_EQ_JSON(a, "[1,2,3]");
UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[1,2,3]}");
}
+
+ Y_UNIT_TEST(TestMerge8) {
+ NSc::TValue v;
+ v["a"] = NSc::TValue::FromJson("[0.125,0.12,0.1,0.08,0.06]");
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[0.125,0.12,0.1,0.08,0.06]}");
+
+ NSc::TMergeOptions options = {.ArrayMergeMode = NSc::TMergeOptions::EArrayMergeMode::Merge};
+ NSc::TValue a = v.TrySelectOrAdd("a")->MergeUpdateJson("[1,2,3]", options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(a, "[1,2,3,0.08,0.06]");
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[1,2,3,0.08,0.06]}");
+ }
+
+ Y_UNIT_TEST(TestMerge9) {
+ NSc::TValue v;
+ v["a"] = NSc::TValue::FromJson("[{a:1},{b:2,d:2}]");
+
+ NSc::TValue update;
+ update["a"] = NSc::TValue::FromJson("[{},{a:1,d:1},{b:2}]");
+
+ NSc::TMergeOptions options = {.ArrayMergeMode = NSc::TMergeOptions::EArrayMergeMode::Merge};
+ v.MergeUpdate(update, options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[{a:1},{a:1,b:2,d:1},{b:2}]}");
+
+ //no uncontrolled grow
+ v.MergeUpdate(update, options);
+ v.MergeUpdate(update, options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[{a:1},{a:1,b:2,d:1},{b:2}]}");
+ }
+
+ Y_UNIT_TEST(TestMerge10) {
+ NSc::TValue v;
+ v["a"] = NSc::TValue::FromJson("[0.125,0.12,0.1,0.08,0.06]");
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[0.125,0.12,0.1,0.08,0.06]}");
+
+ NSc::TMergeOptions options = {.ArrayMergeMode = NSc::TMergeOptions::EArrayMergeMode::Merge};
+ NSc::TValue delta = NSc::TValue::FromJson("{a:[1,2,3,4,5,6]}");
+ v.ReverseMerge(delta, options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[0.125,0.12,0.1,0.08,0.06,6]}");
+ }
+
+ Y_UNIT_TEST(TestMerge11) {
+ NSc::TValue v;
+ v["a"] = NSc::TValue::FromJson("[{a:1},{b:2,d:2}]");
+
+ NSc::TValue update;
+ update["a"] = NSc::TValue::FromJson("[{},{a:1,d:1},{b:2}]");
+
+ NSc::TMergeOptions options = {.ArrayMergeMode = NSc::TMergeOptions::EArrayMergeMode::Merge};
+ v.ReverseMerge(update, options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[{a:1},{a:1,b:2,d:2},{b:2}]}");
+
+ //no uncontrolled grow
+ v.ReverseMerge(update, options);
+ v.ReverseMerge(update, options);
+
+ UNIT_ASSERT_JSON_EQ_JSON(v, "{a:[{a:1},{a:1,b:2,d:2},{b:2}]}");
+ }
+
};