Skip to content

Commit 829bc1f

Browse files
committed
Backport mozilla#308 onto 0.6.1
1 parent ac518d2 commit 829bc1f

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

lib/util.js

+57-3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,43 @@ function urlGenerate(aParsedUrl) {
6666
}
6767
exports.urlGenerate = urlGenerate;
6868

69+
var MAX_CACHED_INPUTS = 32;
70+
71+
/**
72+
* Takes some function `f(input) -> result` and returns a memoized version of
73+
* `f`.
74+
*
75+
* We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
76+
* memoization is a dumb-simple, linear least-recently-used cache.
77+
*/
78+
function lruMemoize(f) {
79+
var cache = [];
80+
81+
return function(input) {
82+
for (var i = 0; i < cache.length; i++) {
83+
if (cache[i].input === input) {
84+
var temp = cache[0];
85+
cache[0] = cache[i];
86+
cache[i] = temp;
87+
return cache[0].result;
88+
}
89+
}
90+
91+
var result = f(input);
92+
93+
cache.unshift({
94+
input,
95+
result,
96+
});
97+
98+
if (cache.length > MAX_CACHED_INPUTS) {
99+
cache.pop();
100+
}
101+
102+
return result;
103+
};
104+
}
105+
69106
/**
70107
* Normalizes a path, or the path portion of a URL:
71108
*
@@ -77,7 +114,7 @@ exports.urlGenerate = urlGenerate;
77114
*
78115
* @param aPath The path or url to normalize.
79116
*/
80-
function normalize(aPath) {
117+
var normalize = lruMemoize(function normalize(aPath) {
81118
var path = aPath;
82119
var url = urlParse(aPath);
83120
if (url) {
@@ -87,8 +124,25 @@ function normalize(aPath) {
87124
path = url.path;
88125
}
89126
var isAbsolute = exports.isAbsolute(path);
127+
// Split the path into parts between `/` characters. This is much faster than
128+
// using `.split(/\/+/g)`.
129+
var parts = [];
130+
var start = 0;
131+
var i = 0;
132+
while (true) {
133+
start = i;
134+
i = path.indexOf("/", start);
135+
if (i === -1) {
136+
parts.push(path.slice(start));
137+
break;
138+
} else {
139+
parts.push(path.slice(start, i));
140+
while (i < path.length && path[i] === "/") {
141+
i++;
142+
}
143+
}
144+
}
90145

91-
var parts = path.split(/\/+/);
92146
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
93147
part = parts[i];
94148
if (part === '.') {
@@ -119,7 +173,7 @@ function normalize(aPath) {
119173
return urlGenerate(url);
120174
}
121175
return path;
122-
}
176+
});
123177
exports.normalize = normalize;
124178

125179
/**

0 commit comments

Comments
 (0)