-
Notifications
You must be signed in to change notification settings - Fork 27.4k
WIP: Filter cache #8942
WIP: Filter cache #8942
Changes from all commits
a7965d7
9cf02ae
65caaaa
dd0b9e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -559,7 +559,11 @@ Parser.prototype = { | |
|
||
filter: function() { | ||
var token = this.expect(); | ||
var fn = this.$filter(token.text); | ||
var filterName = token.text; | ||
var expression = this.text; | ||
var filterCacheKeyInput = filterName + '_i_' + expression; | ||
var filterCacheKeyResult = filterName + '_r_' + expression; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the filter has no parameters, you put an array of the values and if does not, the raw value. I wonder if this can be an issue as var filterIndexAtExpression = this.index;
var filterCacheKeyInput = filterName + '_' + filterIndexAtExpression + '_i_' + expression;
var filterCacheKeyResult = filterName + '_' + filterIndexAtExpression + '_r_' + expression; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point :) |
||
var fn = this.$filter(filterName); | ||
var argsFn; | ||
var args; | ||
|
||
|
@@ -572,6 +576,9 @@ Parser.prototype = { | |
} | ||
|
||
return valueFn(function $parseFilter(self, locals, input) { | ||
var result; | ||
var filterCache = self.$$filterCache; | ||
|
||
if (args) { | ||
args[0] = input; | ||
|
||
|
@@ -580,10 +587,41 @@ Parser.prototype = { | |
args[i + 1] = argsFn[i](self, locals); | ||
} | ||
|
||
return fn.apply(undefined, args); | ||
var primitiveInputs = true; | ||
i = args.length; | ||
while (primitiveInputs && i--) { | ||
primitiveInputs = primitiveInputs && isPrimitive(args[i]); | ||
} | ||
|
||
if (primitiveInputs) { | ||
if (filterCacheKeyInput in filterCache && | ||
equals(filterCache[filterCacheKeyInput], args)) { | ||
result = filterCache[filterCacheKeyResult]; | ||
} else { | ||
result = fn.apply(undefined, args); | ||
filterCache[filterCacheKeyInput] = shallowCopy(args, []); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes the assumption that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah. I don't know if anyone uses $parse without scope, but we can guard against the filtercache not being present |
||
filterCache[filterCacheKeyResult] = result; | ||
} | ||
} else { | ||
result = fn.apply(undefined, args); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
if (isPrimitive(input)) { | ||
if (filterCache[filterCacheKeyInput] === input && (input === undefined || filterCacheKeyInput in filterCache)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am reading this wrong of if this is the first time the filter is executed and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. darn it Lucas, how do you always find these corner-cases. you rock! |
||
result = filterCache[filterCacheKeyResult]; | ||
} else { | ||
result = fn(input); | ||
filterCache[filterCacheKeyInput] = input; | ||
filterCache[filterCacheKeyResult] = result; | ||
} | ||
} else { | ||
result = fn(input); | ||
} | ||
|
||
return fn(input); | ||
return result; | ||
}); | ||
}, | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed
boolean
here