Skip to content

Commit

Permalink
new version hash listeners tree which is faster in most case
Browse files Browse the repository at this point in the history
  • Loading branch information
malash committed May 5, 2017
1 parent 25569e3 commit 5db88aa
Showing 1 changed file with 28 additions and 27 deletions.
55 changes: 28 additions & 27 deletions benchmark/hash-listener-tree.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
/* eslint-disable */
import { stringifyPath } from '../src/utils';
function pathify(p) {
if (Array.isArray(p)) p = stringifyPath(p);
return '$$_' + p; // prepend special symbols to avoid name conflict with protos
}
function keyify(path, listener) {
return path + '//' + listener;
}
let count = 1;
class ListenTree {
constructor() {
this._listeners = [];
this._count = 1;
this._listeners = Object.create(null);
this._listened = {};
}

on(p, listener) {
const path = pathify(p);
const path = `!_${ p.join('#')}`;
if (!listener.$id) {
listener.$id = this._count++;
listener.$id = count++;
}
const key = keyify(path, listener.$id);
const key = path + '//' + listener.$id;
if (this._listened[key]) return;
if (!this._listeners[path]) this._listeners[path] = [];
this._listeners[path].push(listener);
this._listened[key] = true;
}

off(p, listener) {
const path = pathify(p);
const path = `!_${ p.join('#')}`;
const listeners = this._listeners[path];
if (!listeners || !listeners.length) return;
listeners.splice(listeners.indexOf(listener), 1);
this._listened[keyify(path, listener)] = false;
if (!listeners) return;
var i = 0;
while (listeners[i] && listener != listeners[i]) i++;
while (listeners[i] = listeners[i + 1]) i++;
listeners.length = i;
this._listened[path + '//' + listener.$id] = false;
}

emit(p) {
const path = pathify(p);
const listeners = {};
Object.keys(this._listeners).forEach(p2 => {
if (path !== '' && p2 !== ''
&& p2.indexOf(path) !== 0 && path.indexOf(p2) !== 0) return;
(this._listeners[p2] || []).forEach(listener => {
listeners[listener.$id] = listener;
});
});
Object.keys(listeners).forEach(k => listeners[k]());
const path = `!_${ p.join('#')}`;
const listeners = this._listeners;
const len1 = path.length;
const called = {};
for (let p2 in listeners) {
const len2 = p2.length;
if (len2 >= len1 && p2.slice(0, len1) !== path) continue;
if (len2 < len1 && path.slice(0, len2) !== p2) continue;
const subListeners = listeners[p2];
var i = 0, listener;
while (listener = subListeners[i++]) {
if (called[listener.$id]) continue;
called[listener.$id] = true;
listener();
}
}
}
}

Expand Down

0 comments on commit 5db88aa

Please sign in to comment.