10000 Fix creation of millions of VPackBuilders in edge import - part 1 - #194 · arangodb/arangodb@0669e51 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0669e51

Browse files
committed
Fix creation of millions of VPackBuilders in edge import - part 1 - #194
1 parent d402ea6 commit 0669e51

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

3rdParty/velocypack/include/velocypack/Collection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ class Collection {
199199
bool mergeValues, bool nullMeansRemove = false) {
200200
return merge(*left, *right, mergeValues, nullMeansRemove);
201201
}
202+
static Builder& merge(Builder& builder, Slice const& left, Slice const& right, bool mergeValues, bool nullMeansRemove = false);
202203

203204
static void visitRecursive(
204205
Slice const& slice, VisitationOrder order,

3rdParty/velocypack/src/Collection.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,71 @@ Builder Collection::merge(Slice const& left, Slice const& right,
403403
return b;
404404
}
405405

406+
Builder& Collection::merge(Builder& builder, Slice const& left, Slice const& right,
407+
bool mergeValues, bool nullMeansRemove) {
408+
if (!left.isObject() || !right.isObject()) {
409+
throw Exception(Exception::InvalidValueType, "Expecting type Object");
410+
}
411+
412+
builder.add(Value(ValueType::Object));
413+
414+
std::unordered_map<std::string, Slice> rightValues;
415+
{
416+
ObjectIterator it(right);
417+
while (it.valid()) {
418+
rightValues.emplace(it.key(true).copyString(), it.value());
419+
it.next();
420+
}
421+
}
422+
423+
{
424+
ObjectIterator it(left);
425+
426+
while (it.valid()) {
427+
auto key = it.key(true).copyString();
428+
auto found = rightValues.find(key);
429+
430+
if (found == rightValues.end()) {
431+
// use left value
432+
builder.add(key, it.value());
433+
} else if (mergeValues && it.value().isObject() &&
434+
(*found).second.isObject()) {
435+
// merge both values
436+
auto& value = (*found).second;
437+
if (!nullMeansRemove || (!value.isNone() && !value.isNull())) {
438+
Collection::merge(builder, it.value(), value, true, nullMeansRemove);
439+
}
440+
// clear the value in the map so its not added again
441+
(*found).second = Slice();
442+
} else {
443+
// use right value
444+
auto& value = (*found).second;
445+
if (!nullMeansRemove || (!value.isNone() && !value.isNull())) {
446+
builder.add(key, value);
447+
}
448+
// clear the value in the map so its not added again
449+
(*found).second = Slice();
450+
}
451+
it.next();
452+
}
453+
}
454+
455+
// add remaining values that were only in right
456+
for (auto& it : rightValues) {
457+
auto& s = it.second;
458+
if (s.isNone()) {
459+
continue;
460+
}
461+
if (nullMeansRemove && s.isNull()) {
462+
continue;
463+
}
464+
builder.add(std::move(it.first), s);
465+
}
466+
467+
builder.close();
468+
return builder;
469+
}
470+
406471
template <Collection::VisitationOrder order>
407472
static bool doVisit(
408473
Slice const& slice,

arangod/RestHandler/RestImportHandler.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ int RestImportHandler::handleSingleDocument(SingleCollectionTransaction& trx,
201201

202202

203203
// document ok, now import it
204-
VPackBuilder newBuilder;
204+
transaction::BuilderLeaser newBuilder(&trx);
205205

206206
// add prefixes to _from and _to
207207
if (!_fromPrefix.empty() || !_toPrefix.empty()) {
@@ -239,9 +239,8 @@ int RestImportHandler::handleSingleDocument(SingleCollectionTransaction& trx,
239239
tempBuilder->close();
240240

241241
if (tempBuilder->slice().length() > 0) {
242-
newBuilder =
243-
VPackCollection::merge(slice, tempBuilder->slice(), false, false);
244-
slice = newBuilder.slice();
242+
VPackCollection::merge(*(newBuilder.builder()), slice, tempBuilder->slice(), false, false);
243+
slice = newBuilder->slice();
245244
}
246245
}
247246

0 commit comments

Comments
 (0)
0