aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/scheme/scheme.cpp
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 /library/cpp/scheme/scheme.cpp
parentf8b13db877cf0234f2bdf7092164f57eebc52aa1 (diff)
downloadydb-d85809f7b86d53a83de4744b395e61df085e727f.tar.gz
intermediate changes
ref:95923961b070d9d9b37fcb1d21bffeae90f3d022
Diffstat (limited to 'library/cpp/scheme/scheme.cpp')
-rw-r--r--library/cpp/scheme/scheme.cpp57
1 files changed, 41 insertions, 16 deletions
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);