summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@gmail.com>2023-03-13 12:46:57 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2023-04-13 15:50:18 -0400
commit28bdca6e56619eee507461545103fbcce118e1ce (patch)
treebcff5b2602ea5e552494d8a9e405963524241d7b
parent7368332932c6781b27049563757a8f8601d80e13 (diff)
downloadcouchdb-28bdca6e56619eee507461545103fbcce118e1ce.tar.gz
Avoid re-compiling filter view functions
Filter view functions feature re-uses view map function for filtering _changes feeds. Instead of accumulating emitted KVs, it uses custom emit() function which just toggles a flag. However, in order to use this optimisation, the function is compiled first with the regular emit function, then the function source is queried with a non-portable toSource() method, and re-compiled again with a new sandbox where emit is overridden. Instead of reparsing and re-compiling it, pass the sandbox to the compile function and compile filter views with that correct sandbox to start with. Moreover, this helps remove another non-portable function call.
-rw-r--r--share/server/filter.js5
-rw-r--r--share/server/loop.js5
-rw-r--r--share/server/util.js4
3 files changed, 6 insertions, 8 deletions
diff --git a/share/server/filter.js b/share/server/filter.js
index 84f5cfc09..e3a62ab26 100644
--- a/share/server/filter.js
+++ b/share/server/filter.js
@@ -28,11 +28,6 @@ var Filter = (function() {
respond([true, results]);
},
filter_view : function(fun, ddoc, args) {
- // recompile
- var sandbox = create_filter_sandbox();
- var source = fun.toSource();
- fun = evalcx(source, sandbox);
-
var results = [];
var docs = args[0];
for (var i=0; i < docs.length; i++) {
diff --git a/share/server/loop.js b/share/server/loop.js
index 91dd1d6b0..70a143a45 100644
--- a/share/server/loop.js
+++ b/share/server/loop.js
@@ -87,7 +87,10 @@ var DDoc = (function() {
" on design doc " + ddocId]);
}
if (typeof fun != "function") {
- fun = Couch.compileFunction(fun, ddoc, funPath.join('.'));
+ // For filter_view we want the emit() function to be overridden
+ // and just toggle a flag instead of accumulating rows
+ var sandbox = (cmd === "views") ? create_filter_sandbox() : create_sandbox();
+ fun = Couch.compileFunction(fun, ddoc, funPath.join('.'), sandbox);
// cache the compiled fun on the ddoc
point[funPath[i]] = fun;
};
diff --git a/share/server/util.js b/share/server/util.js
index aba56eaf2..c207d0ab9 100644
--- a/share/server/util.js
+++ b/share/server/util.js
@@ -58,11 +58,11 @@ var resolveModule = function(names, mod, root) {
var Couch = {
// moving this away from global so we can move to json2.js later
- compileFunction : function(source, ddoc, name) {
+ compileFunction : function(source, ddoc, name, sandbox) {
if (!source) throw(["error","not_found","missing function"]);
var functionObject = null;
- var sandbox = create_sandbox();
+ var sandbox = sandbox || create_sandbox();
var require = function(name, module) {
module = module || {};