From 4bd6aca0c02ca62d82f119acd4e1e941cccc350f Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Wed, 3 Mar 2010 02:36:40 -0800 Subject: [PATCH] Cache URLs for performance improvement. Reviewed by me. --- Objective-J/CFURL.js | 87 ++++++++++++++++++++++++++++++++++++++- Objective-J/Executable.js | 8 +++- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/Objective-J/CFURL.js b/Objective-J/CFURL.js index 50c2af6fd..bc38a9654 100644 --- a/Objective-J/CFURL.js +++ b/Objective-J/CFURL.js @@ -1,7 +1,24 @@ // Based on the regex in RFC2396 Appendix B. var URI_RE = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; -GLOBAL(CFURL) = function(/*CFURL|String*/ aURL, /*CFURL*/ aBaseURL) +var CFURLsForCachedUIDs, + CFURLCachingEnableCount = 0; + +function enableCFURLCaching() +{ + ++CFURLCachingEnableCount; + CFURLsForCachedUIDs = { }; +} + +function disableCFURLCaching() +{ + CFURLCachingEnableCount = MAX(CFURLCachingEnableCount - 1, 0); + + if (!CFURLCachingEnableCount === 0) + delete CFURLsForCachedUIDs; +} + +GLOBAL(CFURL) = function CFURL(/*CFURL|String*/ aURL, /*CFURL*/ aBaseURL) { if (aURL instanceof CFURL) if (!aBaseURL) @@ -16,6 +33,17 @@ GLOBAL(CFURL) = function(/*CFURL|String*/ aURL, /*CFURL*/ aBaseURL) return new CFURL(aURL.string(), aBaseURL); } + // Use the cache if it's enabled. + if (CFURLsForCachedUIDs) + { + var cacheUID = aURL + " " + (aBaseURL && aBaseURL.UID() || ""); + + if (hasOwnProperty.call(CFURLsForCachedUIDs, cacheUID)) + return CFURLsForCachedUIDs[cacheUID]; + + CFURLsForCachedUIDs[cacheUID] = this; + } + this._UID = objj_generateObjectUID(); this._string = aURL; @@ -33,6 +61,11 @@ GLOBAL(CFURL) = function(/*CFURL|String*/ aURL, /*CFURL*/ aBaseURL) var URLMap = { }; +CFURL.prototype.UID = function() +{ + return this._UID; +} + CFURL.prototype.mappedURL = function() { return URLMap[this.absoluteString()] || this; @@ -241,7 +274,57 @@ CFURL.prototype.staticResourceData = function() return data; } +/* +function parseURL(aURL) +{ + var parts = expression.exec(aURL.string()), + index = 0, + count = parts.length; + for (; index < count; ++index) + aURL[expressionKeys[index]] = parts[index] || ""; + + aURL._root = (aURL._root || aURL._authorityRoot) ? "/" : ""; + + var components = aPath.split("/"), + results = [], + index = 0, + count = components.length, + isRoot = aPath.charAt(0) === "/"; + + for (; index < count; ++index) + { + var component = components[index]; + + // These simply remain in the current directory. + if (component === "" || component === ".") + continue; + + if (component !== "..") + { + results.push(component); + continue; + } + + var resultsCount = results.length; + + // If we have a valid previous component, "climb" it. + if (resultsCount > 0 && results[resultsCount - 1] !== "..") + results.pop(); + + // If this isn't a root listing, and we are preceded by only ..'s, or + // nothing at all, then add it since it makes sense for relative paths. + else if (!isRoot && resultsCount === 0 || results[resultsCount - 1] === "..") + results.push(component); + } + + return (isRoot ? "/" : "") + results.join("/"); + + items.direcotries = that; + items.domains = items.domain.split("."); + }; +} +*/ // from Chiron's HTTP module: /**** keys @@ -327,7 +410,7 @@ var strictExpression = new RegExp( /* url */ mapping all `keys` to values. */ var Parser = function (expression) { - return function (url) { + return function p_p(url) { if (typeof url == "undefined") throw new Error("HttpError: URL is undefined"); if (typeof url != "string") return new Object(url); diff --git a/Objective-J/Executable.js b/Objective-J/Executable.js index 490951e85..bd0c1d468 100644 --- a/Objective-J/Executable.js +++ b/Objective-J/Executable.js @@ -20,12 +20,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + var ExecutableUnloadedFileDependencies = 0, ExecutableLoadingFileDependencies = 1, ExecutableLoadedFileDependencies = 2, AnonymousExecutableCount = 0; - function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL*/ aURL, /*Function*/ aFunction) { if (arguments.length === 0) @@ -366,6 +366,9 @@ Executable.fileImporterForURL = function(/*CFURL*/ aURL) { cachedImporter = function(/*CFURL*/ aURL, /*BOOL*/ isQuoted, /*Function*/ aCallback) { + // We make heavy use of URLs throughout this process, so cache them! + enableCFURLCaching(); + aURL = new CFURL(aURL, isQuoted ? referenceURL : NULL); var fileExecutableSearch = new FileExecutableSearch(aURL, isQuoted); @@ -377,6 +380,9 @@ Executable.fileImporterForURL = function(/*CFURL*/ aURL) { fileExecutable.execute(); + // No more need to cache these. + disableCFURLCaching(); + if (aCallback) aCallback(); }