Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'in' Filters with too many elements fail with "Uncaught RangeError" #7

Closed
wants to merge 5 commits into from

Conversation

peckjon
Copy link
Contributor

@peckjon peckjon commented Jan 12, 2016

Fixes mapbox/mapbox-gl-js#1782

If too many elements (varies by environment, but appx 1-2k) are used for an 'in' filter, it will fail with "Uncaught RangeError: Maximum call stack size exceeded". This is because the logical comparison of many infix comarisons (eg "(p['foo']==='bar') || (p['foo']==='cat') || ...") becomes too long for the v8natives to handle.

Note: this fix does not handle large lists of VectorTileFeatureTypes.

@jfirebaugh
Copy link
Contributor

How about something like:

'[' + Array.prototype.slice.call(arguments, 2).map(function(value) {
  return '(' + operators['=='](_, key, value) + ')';
}).join(',') + '].indexOf(true) >= 0'

That would avoid the large disjunction for all cases. What it sacrifices in order to get that is short-circuit evaluation.

Fixes mapbox/mapbox-gl-js#1782

If too many elements (varies by environment, but appx 1-2k) are used for an 'in' filter, it will fail with "Uncaught RangeError: Maximum call stack size exceeded". This is because the logical comparison of many infix comarisons (eg "(p['foo']==='bar') || (p['foo']==='cat') || ...") becomes too long for the v8natives to handle.
@peckjon
Copy link
Contributor Author

peckjon commented Jan 13, 2016

@jfirebaugh Love it! Passes my local tests (about 2k elements). Committed for Pull.

@jfirebaugh
Copy link
Contributor

👍 Can you add a test that triggers the RangeError prior to this change?

@jfirebaugh
Copy link
Contributor

Thinking about this more, we should preserve short-circuit evaluation too.

'(function(){' + Array.prototype.slice.call(arguments, 2).map(function(value) {
  return 'if (' + operators['=='](_, key, value) + ') return true;';
}).join('') + 'return false;})()';

@peckjon
Copy link
Contributor Author

peckjon commented Jan 13, 2016

Sorry can you elaborate on the range error issue?

On Jan 12, 2016, at 17:30, John Firebaugh notifications@github.com wrote:

Can you add a test that triggers the RangeError prior to this change?


Reply to this email directly or view it on GitHub.

@jfirebaugh
Copy link
Contributor

Please add a test for this change, so we can ensure it doesn't regress with future changes.

@peckjon
Copy link
Contributor Author

peckjon commented Jan 13, 2016

Oh, sure. I should be able to get to both of these later tonight.

On Jan 12, 2016, at 17:46, John Firebaugh notifications@github.com wrote:

Please add a test for this change, so we can ensure it doesn't regress with future changes.


Reply to this email directly or view it on GitHub.

@peckjon
Copy link
Contributor Author

peckjon commented Jan 13, 2016

@jfirebaugh ready to go

@jfirebaugh
Copy link
Contributor

Thanks! Committed as 6254b4c. I'll make a release and update the dependency in mapbox-gl-js shortly.

@jfirebaugh jfirebaugh closed this Jan 13, 2016
@peckjon
Copy link
Contributor Author

peckjon commented Jan 13, 2016

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When using a Filter with lots of elements, get "Uncaught RangeError: Maximum call stack size exceeded"
2 participants