Skip to content

Commit

Permalink
opt: TreeNode was scheduling flushes for new known-empty nodes.
Browse files Browse the repository at this point in the history
That's unnecessary, just mark it as initialized and save the flush.
  • Loading branch information
jamestalmage committed Feb 16, 2015
1 parent 1c33187 commit a163c5e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
31 changes: 20 additions & 11 deletions src/TreeNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,28 @@ function TreeNode(key, parent){
this._value = null;
this._pendingValue = null;
this._changed = false;
this._changeRegistered = false;
this._flushScheduled = false;
this._key = key;
this.initialized = false;
this._initializeNextFlush = false;
}

TreeNode.prototype.flushChanges = function(){
var changedChildren = this._childrenToFlush;
this._changeRegistered = false;
this._flushScheduled = false;
var initializing = this._initializeNextFlush;
if(initializing) {
this._initializeNextFlush = false;
this.initialized = true;
}
if(changedChildren.length){
var childrenToFlush = this._childrenToFlush;
if(childrenToFlush.length){
this._childrenToFlush = [];
changedChildren.forEach(function(child){
childrenToFlush.forEach(function(child){
child.flushChanges();
});
}
if(this._changed || initializing){
var changed = this._changed;
if(changed || initializing){
this._changed = false;
this._value = this._pendingValue;
var oldSnap = this._valueSnap;
Expand Down Expand Up @@ -119,8 +120,8 @@ TreeNode.prototype._setValue = function(value){
};

TreeNode.prototype._scheduleFlush = function(){
if(!this._changeRegistered){
this._changeRegistered = true;
if(!this._flushScheduled){
this._flushScheduled = true;
var parent = this._parent;
if(parent){
parent._scheduleChildFlush(this);
Expand Down Expand Up @@ -164,6 +165,7 @@ TreeNode.prototype._buildValueSnap = function(){
}
//TODO: Sort Children According To OrderByXXX
//TODO: Create Meaningful Refs
//TODO: Include priority
return new ObjectSnapshot(new FakeRef('https://blah.com/' + this.key()), children, null);
}
else {
Expand All @@ -190,7 +192,6 @@ TreeNode.prototype.child = function(path,create){
TreeNode.prototype._emitChildEvent = function (eventType, snap){
this._events.emit(eventType,snap);
this._changed = true;
this._scheduleFlush();
};

TreeNode.prototype._emitEventOnParent = function(eventType, snap){
Expand All @@ -207,11 +208,19 @@ TreeNode.prototype._getOrCreateChild = function(key){
if(!child){
child = children[key] = new TreeNode(key,this);
if(this.initialized){
child.setValue(null);
child.flushChanges();
child._initEmpty();
}
}
return child;
};

/**
* Called if we know this child to currently be empty.
* @private
*/
TreeNode.prototype._initEmpty = function(){
this.initialized = true;
this._valueSnap = this._buildValueSnap();
};

module.exports = TreeNode;
7 changes: 7 additions & 0 deletions test/TreeNode-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,13 @@ describe('TreeNode',function(){
expect(spy2).to.have.been.calledOnce.and.calledWith(snapVal('a',null,'a'));
});

it('creating new empty nodes does not schedule a flush', function(){
setAndFlush({a:'a'});
node.child('b',true).on('value',spy1);
expect(spy1).to.have.been.calledOnce.and.calledWith(snapVal(null));
expect(node._flushScheduled).to.equal(false);
});

it('are called when the child gets a value on initial flush', function(){
node.child('a',true).on('value',spy1);
node.child('b',true).on('value',spy2);
Expand Down

0 comments on commit a163c5e

Please sign in to comment.