mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
- We don't want to do a bunch of parsing *per comparison* when sorting a list of package version strings. package-version-parser's `compare` (and server's `compare`, which it uses) both accept either a string or a parsed record. By parsing explicitly with memoization, we avoid a super-linear blow-up in the amount of parsing. This'll save someone half a second, at least. - Adjust profiling hooks and messages - Expose `Profile` to isopackets
137 lines
4.3 KiB
JavaScript
137 lines
4.3 KiB
JavaScript
var CS = ConstraintSolver;
|
|
var PV = PackageVersion;
|
|
|
|
var pvkey = function (pkg, version) {
|
|
return pkg + " " + version;
|
|
};
|
|
|
|
// Stores the Dependencies for each known PackageAndVersion.
|
|
CS.CatalogCache = function () {
|
|
// String(PackageAndVersion) -> String -> Dependency.
|
|
// For example, "foo 1.0.0" -> "bar" -> Dependency.fromString("?bar@1.0.2").
|
|
this._dependencies = {};
|
|
// A map derived from the keys of _dependencies, for ease of iteration.
|
|
// "foo" -> ["1.0.0", ...]
|
|
// Versions in the array are unique but not sorted, unless the `.sorted`
|
|
// property is set on the array. The array is never empty.
|
|
this._versions = {};
|
|
};
|
|
|
|
CS.CatalogCache.prototype.hasPackageVersion = function (pkg, version) {
|
|
return _.has(this._dependencies, pvkey(pkg, version));
|
|
};
|
|
|
|
CS.CatalogCache.prototype.addPackageVersion = function (p, v, deps) {
|
|
check(p, String);
|
|
check(v, String);
|
|
// `deps` must not have any duplicate values of `.packageConstraint.package`
|
|
check(deps, [CS.Dependency]);
|
|
|
|
var key = pvkey(p, v);
|
|
if (_.has(this._dependencies, key)) {
|
|
throw new Error("Already have an entry for " + key);
|
|
}
|
|
|
|
if (! _.has(this._versions, p)) {
|
|
this._versions[p] = [];
|
|
}
|
|
this._versions[p].push(v);
|
|
this._versions[p].sorted = false;
|
|
|
|
var depsByPackage = {};
|
|
this._dependencies[key] = depsByPackage;
|
|
_.each(deps, function (d) {
|
|
var p2 = d.packageConstraint.package;
|
|
if (_.has(depsByPackage, p2)) {
|
|
throw new Error("Can't have two dependencies on " + p2 +
|
|
" in " + key);
|
|
}
|
|
depsByPackage[p2] = d;
|
|
});
|
|
};
|
|
|
|
// Returns the dependencies of a (package, version), stored in a map.
|
|
// The values are Dependency objects; the key for `d` is
|
|
// `d.packageConstraint.package`. (Don't mutate the map.)
|
|
CS.CatalogCache.prototype.getDependencyMap = function (p, v) {
|
|
var key = pvkey(p, v);
|
|
if (! _.has(this._dependencies, key)) {
|
|
throw new Error("No entry for " + key);
|
|
}
|
|
return this._dependencies[key];
|
|
};
|
|
|
|
// Returns an array of version strings, sorted, possibly empty.
|
|
// (Don't mutate the result.)
|
|
CS.CatalogCache.prototype.getPackageVersions = function (pkg) {
|
|
var result = (_.has(this._versions, pkg) ?
|
|
this._versions[pkg] : []);
|
|
if ((!result.length) || result.sorted) {
|
|
return result;
|
|
} else {
|
|
// sort in place, and record so that we don't sort redundantly
|
|
// (we'll sort again if more versions are pushed onto the array)
|
|
var pvParse = _.memoize(PV.parse);
|
|
result.sort(function (a, b) {
|
|
return PV.compare(pvParse(a), pvParse(b));
|
|
});
|
|
result.sorted = true;
|
|
return result;
|
|
}
|
|
};
|
|
|
|
CS.CatalogCache.prototype.hasPackage = function (pkg) {
|
|
return _.has(this._versions, pkg);
|
|
};
|
|
|
|
CS.CatalogCache.prototype.toJSONable = function () {
|
|
var self = this;
|
|
var data = {};
|
|
_.each(self._dependencies, function (depsByPackage, key) {
|
|
// depsByPackage is a map of String -> Dependency.
|
|
// Map over the values to get an array of String.
|
|
data[key] = _.map(depsByPackage, function (dep) {
|
|
return dep.toString();
|
|
});
|
|
});
|
|
return { data: data };
|
|
};
|
|
|
|
CS.CatalogCache.fromJSONable = function (obj) {
|
|
check(obj, { data: Object });
|
|
|
|
var cache = new CS.CatalogCache();
|
|
_.each(obj.data, function (depsArray, pv) {
|
|
check(depsArray, [String]);
|
|
pv = CS.PackageAndVersion.fromString(pv);
|
|
cache.addPackageVersion(
|
|
pv.package, pv.version,
|
|
_.map(depsArray, function (str) {
|
|
return CS.Dependency.fromString(str);
|
|
}));
|
|
});
|
|
return cache;
|
|
};
|
|
|
|
// Calls `iter` on each PackageAndVersion, with the second argument being
|
|
// a map from package name to Dependency. If `iter` returns true,
|
|
// iteration is stopped. There's no particular order to the iteration.
|
|
CS.CatalogCache.prototype.eachPackageVersion = function (iter) {
|
|
var self = this;
|
|
_.find(self._dependencies, function (value, key) {
|
|
var stop = iter(CS.PackageAndVersion.fromString(key), value);
|
|
return stop;
|
|
});
|
|
};
|
|
|
|
// Calls `iter` on each package name, with the second argument being
|
|
// a list of versions present for that package (unique and sorted).
|
|
// If `iter` returns true, iteration is stopped.
|
|
ConstraintSolver.CatalogCache.prototype.eachPackage = function (iter) {
|
|
var self = this;
|
|
_.find(_.keys(self._versions), function (key) {
|
|
var stop = iter(key, self.getPackageVersions(key));
|
|
return stop;
|
|
});
|
|
};
|