From e698c5bf5a024cfaf32eb518a1b75b07ecdfa26a Mon Sep 17 00:00:00 2001 From: David Glasser Date: Wed, 11 Feb 2015 17:46:56 -0800 Subject: [PATCH] crossbar: check common reasons to not match first Also, put off the use of EJSON.equals until necessary. Inspired by @hypno2000. See #3697. --- History.md | 3 +++ packages/ddp/crossbar.js | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/History.md b/History.md index ec59fef451..0228cece71 100644 --- a/History.md +++ b/History.md @@ -76,6 +76,9 @@ (`application-configuration`, `ctl`, `ctl-helper`, `follower-livedata`, `dev-bundle-fetcher`, and `star-translate`). +* Optimize common cases faced by the "crossbar" data structure (used by oplog + tailing and DDP method write tracking). #3697 + * Upgraded dependencies: - node: 0.10.36 (from 0.10.33) diff --git a/packages/ddp/crossbar.js b/packages/ddp/crossbar.js index 4c49fd259e..d78719d32f 100644 --- a/packages/ddp/crossbar.js +++ b/packages/ddp/crossbar.js @@ -87,6 +87,26 @@ _.extend(DDPServer._Crossbar.prototype, { // (a targeted write to a collection does not match a targeted query // targeted at a different document) _matches: function (notification, trigger) { + // Most notifications that use the crossbar have a string `collection` and + // maybe an `id` that is a string or ObjectID. So let's fast-track "nope, + // different collection" and "nope, different ID". This makes a noticeable + // performance difference; see https://github.com/meteor/meteor/pull/3697 + if (typeof(notification.collection) === 'string' && + typeof(trigger.collection) === 'string' && + notification.collection !== trigger.collection) { + return false; + } + if (typeof(notification.id) === 'string' && + typeof(trigger.id) === 'string' && + notification.id !== trigger.id) { + return false; + } + if (notification.id instanceof LocalCollection._ObjectID && + trigger.id instanceof LocalCollection._ObjectID && + ! notification.id.equals(trigger.id)) { + return false; + } + return _.all(trigger, function (triggerValue, key) { return !_.has(notification, key) || EJSON.equals(triggerValue, notification[key]);