Skip to content

Commit

Permalink
perf: avoid unnecessary string replace when checking if arrays match …
Browse files Browse the repository at this point in the history
…pathsToValidate re: #13159
  • Loading branch information
vkarpov15 committed Mar 13, 2023
1 parent 7761bff commit dcf7209
Showing 1 changed file with 24 additions and 31 deletions.
55 changes: 24 additions & 31 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,7 @@ function _evaluateRequiredFunctions(doc) {
* ignore
*/

function _getPathsToValidate(doc) {
function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
const skipSchemaValidators = {};

_evaluateRequiredFunctions(doc);
Expand Down Expand Up @@ -2628,6 +2628,22 @@ function _getPathsToValidate(doc) {
}
}

for (const path of paths) {
// Single nested paths (paths embedded under single nested subdocs) will
// be validated on their own when we call `validate()` on the subdoc itself.
// Re: gh-8468
if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
paths.delete(path);
continue;
}
}

if (Array.isArray(pathsToValidate)) {
paths = _handlePathsToValidate(paths, pathsToValidate);
} else if (Array.isArray(pathsToSkip)) {
paths = _handlePathsToSkip(paths, pathsToSkip);
}

// from here on we're not removing items from paths

// gh-661: if a whole array is modified, make sure to run validation on all
Expand Down Expand Up @@ -2687,13 +2703,6 @@ function _getPathsToValidate(doc) {
}

for (const path of paths) {
// Single nested paths (paths embedded under single nested subdocs) will
// be validated on their own when we call `validate()` on the subdoc itself.
// Re: gh-8468
if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
paths.delete(path);
continue;
}
const _pathType = doc.$__schema.path(path);
if (!_pathType || !_pathType.$isSchemaMap) {
continue;
Expand Down Expand Up @@ -2776,19 +2785,14 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
};

// only validate required fields when necessary
const pathDetails = _getPathsToValidate(this);
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
let paths = shouldValidateModifiedOnly ?
pathDetails[0].filter((path) => this.$isModified(path)) :
pathDetails[0];
const skipSchemaValidators = pathDetails[1];
if (typeof pathsToValidate === 'string') {
pathsToValidate = pathsToValidate.split(' ');
}
if (Array.isArray(pathsToValidate)) {
paths = _handlePathsToValidate(paths, pathsToValidate);
} else if (pathsToSkip) {
paths = _handlePathsToSkip(paths, pathsToSkip);
}

if (paths.length === 0) {
return immediate(function() {
Expand Down Expand Up @@ -2907,18 +2911,12 @@ function _handlePathsToValidate(paths, pathsToValidate) {
}
}

const ret = [];
const ret = new Set();
for (const path of paths) {
if (_pathsToValidate.has(path)) {
ret.push(path);
ret.add(path);
} else if (parentPaths.has(path)) {
ret.push(parentPaths.get(path));
} else {
// Special case given that we add array indexes to paths
const pathWithoutNumber = path.replace(/\.\d+$/, '');
if (pathWithoutNumber !== path && _pathsToValidate.has(pathWithoutNumber)) {
ret.push(path);
}
ret.add(parentPaths.get(path));
}
}
return ret;
Expand All @@ -2930,8 +2928,8 @@ function _handlePathsToValidate(paths, pathsToValidate) {

function _handlePathsToSkip(paths, pathsToSkip) {
pathsToSkip = new Set(pathsToSkip);
paths = paths.filter(p => !pathsToSkip.has(p));
return paths;
paths = Array.from(paths).filter(p => !pathsToSkip.has(p));
return new Set(paths);
}

/**
Expand Down Expand Up @@ -2987,17 +2985,12 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
}

// only validate required fields when necessary
const pathDetails = _getPathsToValidate(this);
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
let paths = shouldValidateModifiedOnly ?
pathDetails[0].filter((path) => this.$isModified(path)) :
pathDetails[0];
const skipSchemaValidators = pathDetails[1];

if (Array.isArray(pathsToValidate)) {
paths = _handlePathsToValidate(paths, pathsToValidate);
} else if (Array.isArray(pathsToSkip)) {
paths = _handlePathsToSkip(paths, pathsToSkip);
}
const validating = {};

for (let i = 0, len = paths.length; i < len; ++i) {
Expand Down

0 comments on commit dcf7209

Please sign in to comment.