@@ -25,7 +25,7 @@ inline Node &addNode(NodesCache &outNodes, Node &parent) {
2525 UNRECOVERABLE_IF (outNodes.size () >= outNodes.capacity ()); // resize must not grow
2626 parent.firstChildId = static_cast <NodeId>(outNodes.size ());
2727 parent.lastChildId = static_cast <NodeId>(outNodes.size ());
28- outNodes.resize (outNodes. size () + 1 );
28+ outNodes.push_back ( Node () );
2929 auto &curr = *outNodes.rbegin ();
3030 curr.id = parent.lastChildId ;
3131 curr.parentId = parent.id ;
@@ -36,7 +36,7 @@ inline Node &addNode(NodesCache &outNodes, Node &parent) {
3636inline Node &addNode (NodesCache &outNodes, Node &prevSibling, Node &parent) {
3737 UNRECOVERABLE_IF (outNodes.size () >= outNodes.capacity ()); // resize must not grow
3838 prevSibling.nextSiblingId = static_cast <NodeId>(outNodes.size ());
39- outNodes.resize (outNodes. size () + 1 );
39+ outNodes.push_back ( Node () );
4040 auto &curr = *outNodes.rbegin ();
4141 curr.id = prevSibling.nextSiblingId ;
4242 curr.parentId = parent.id ;
@@ -308,7 +308,6 @@ bool tokenize(ConstStringRef text, LinesCache &outLines, TokensCache &outTokens,
308308}
309309
310310void finalizeNode (NodeId nodeId, const TokensCache &tokens, NodesCache &outNodes, std::string &outErrReason, std::string &outWarning) {
311- outNodes.reserve (outNodes.size () + 1 );
312311 auto &node = outNodes[nodeId];
313312 if (invalidTokenId != node.key ) {
314313 return ;
@@ -328,7 +327,7 @@ void finalizeNode(NodeId nodeId, const TokensCache &tokens, NodesCache &outNodes
328327 UNRECOVERABLE_IF (invalidNodeID == node.lastChildId )
329328 outNodes[node.lastChildId ].nextSiblingId = static_cast <NodeId>(outNodes.size ());
330329
331- outNodes.resize (outNodes. size () + 1 );
330+ outNodes.push_back ( Node () );
332331 auto &newNode = *outNodes.rbegin ();
333332 newNode.id = static_cast <NodeId>(outNodes.size () - 1 );
334333 newNode.parentId = nodeId;
@@ -349,40 +348,39 @@ bool isEmptyVector(const Token &token, size_t lineId, std::string &outError) {
349348}
350349
351350bool buildTree (const LinesCache &lines, const TokensCache &tokens, NodesCache &outNodes, std::string &outErrReason, std::string &outWarning) {
351+ const auto tokensCacheSize = tokens.size ();
352352 StackVec<NodeId, 64 > nesting;
353353 size_t lineId = 0U ;
354354 size_t lastUsedLine = 0u ;
355- outNodes.resize ( 1 );
355+ outNodes.push_back ( Node () );
356356 outNodes.rbegin ()->id = 0U ;
357357 outNodes.rbegin ()->firstChildId = 1U ;
358358 outNodes.rbegin ()->lastChildId = 1U ;
359359 nesting.resize (1 ); // root
360-
361360 while (lineId < lines.size ()) {
362361 if (isUnused (lines[lineId].lineType )) {
363362 ++lineId;
364363 continue ;
365364 }
366- reserveBasedOnEstimates (outNodes, static_cast <TokenId>(0 ), static_cast <TokenId>(tokens.size ()), lines[lineId].first );
367-
368365 auto currLineIndent = lines[lineId].indent ;
369366 if (currLineIndent == outNodes.rbegin ()->indent ) {
370367 if (lineId > 0u && false == isEmptyVector (tokens[lines[lastUsedLine].first ], lastUsedLine, outErrReason)) {
371368 return false ;
372369 }
373- outNodes. reserve (outNodes. size () + 1 );
370+ reserveBasedOnEstimates (outNodes, static_cast <TokenId>( 0u ), static_cast <TokenId>(tokensCacheSize), lines[lineId]. first );
374371 auto &prev = *outNodes.rbegin ();
375372 auto &parent = outNodes[*nesting.rbegin ()];
376373 auto &curr = addNode (outNodes, prev, parent);
377374 curr.indent = currLineIndent;
378375 } else if (currLineIndent > outNodes.rbegin ()->indent ) {
379- outNodes. reserve (outNodes. size () + 1 );
376+ reserveBasedOnEstimates (outNodes, static_cast <TokenId>( 0u ), static_cast <TokenId>(tokensCacheSize), lines[lineId]. first );
380377 auto &parent = *outNodes.rbegin ();
381378 auto &curr = addNode (outNodes, parent);
382379 curr.indent = currLineIndent;
383380 nesting.push_back (parent.id );
384381 } else {
385382 while (currLineIndent < outNodes[*nesting.rbegin ()].indent ) {
383+ reserveBasedOnEstimates (outNodes, static_cast <TokenId>(0u ), static_cast <TokenId>(tokensCacheSize), lines[lineId].first );
386384 finalizeNode (*nesting.rbegin (), tokens, outNodes, outErrReason, outWarning);
387385 UNRECOVERABLE_IF (nesting.empty ());
388386 nesting.pop_back ();
@@ -392,7 +390,7 @@ bool buildTree(const LinesCache &lines, const TokensCache &tokens, NodesCache &o
392390 outErrReason = constructYamlError (lineId, tokens[lines[lineId].first ].pos , tokens[lines[lineId].first ].pos + 1 , " Invalid indentation" );
393391 return false ;
394392 } else {
395- outNodes. reserve (outNodes. size () + 1 );
393+ reserveBasedOnEstimates (outNodes, static_cast <TokenId>( 0u ), static_cast <TokenId>(tokensCacheSize), lines[lineId]. first );
396394 auto &prev = outNodes[*nesting.rbegin ()];
397395 auto &parent = outNodes[prev.parentId ];
398396 auto &curr = addNode (outNodes, prev, parent);
@@ -410,21 +408,26 @@ bool buildTree(const LinesCache &lines, const TokensCache &tokens, NodesCache &o
410408 auto collectionEnd = lines[lineId].last - 1 ;
411409 UNRECOVERABLE_IF (tokens[collectionBeg].traits .type != Token::Type::CollectionBeg || tokens[collectionEnd].traits .type != Token::Type::CollectionEnd);
412410
413- auto &parentNode = *outNodes.rbegin ();
414- Node *lastAddedNode = nullptr ;
411+ auto parentNodeId = outNodes.size () - 1 ;
412+ auto previousSiblingId = std::numeric_limits<size_t >::max ();
413+
415414 for (auto currTokenId = collectionBeg + 1 ; currTokenId < collectionEnd; currTokenId += 2 ) {
416415 auto tokenType = tokens[currTokenId].traits .type ;
417416 UNRECOVERABLE_IF (tokenType != Token::Type::LiteralNumber && tokenType != Token::Type::LiteralString);
417+ reserveBasedOnEstimates (outNodes, static_cast <TokenId>(0u ), static_cast <TokenId>(tokensCacheSize), lines[lineId].first );
418418
419- if (lastAddedNode == nullptr ) {
420- lastAddedNode = &addNode (outNodes, parentNode);
419+ auto &parentNode = outNodes[parentNodeId];
420+ if (previousSiblingId == std::numeric_limits<size_t >::max ()) {
421+ addNode (outNodes, parentNode);
421422 } else {
422- lastAddedNode = &addNode (outNodes, *lastAddedNode, parentNode);
423+ auto &previousSibling = outNodes[previousSiblingId];
424+ addNode (outNodes, previousSibling, parentNode);
423425 }
424- lastAddedNode->indent = currLineIndent + 1 ;
425- lastAddedNode->value = currTokenId;
426+ previousSiblingId = outNodes.size () - 1 ;
427+ outNodes[previousSiblingId].indent = currLineIndent + 1 ;
428+ outNodes[previousSiblingId].value = currTokenId;
426429 }
427- nesting.push_back (parentNode. id );
430+ nesting.push_back (static_cast <NodeId>(parentNodeId) );
428431 } else if ((' #' != tokens[lines[lineId].first + 2 ]) && (' \n ' != tokens[lines[lineId].first + 2 ])) {
429432 outNodes.rbegin ()->value = lines[lineId].first + 2 ;
430433 }
0 commit comments