This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

refactor to use a linked list node an array for internal storage

  • Loading branch information...
1 parent 73e026a commit 260791ceb7e5ffaeb4fc4dad19cb148fa2387ba3 @aaronpowell committed Jul 24, 2011
Showing with 179 additions and 51 deletions.
  1. +1 −0 Cakefile
  2. +96 −29 lib/postman.js
  3. +1 −1 lib/postman.min.js
  4. +79 −20 src/postman.coffee
  5. +2 −1 test/tests.js
View
@@ -71,4 +71,5 @@ task 'watch', 'Watch prod source files and build changes', ->
console.log 'build complete'
invoke 'tests'
catch e
+ console.log 'Oh snap, someething went wrong!'
console.log e
View
@@ -1,5 +1,54 @@
(function() {
- var cache, createCache, deliver, dropByDate, dropByFunction, dropMessages, isArray, isDate, isFunction, postie, receive, retract;
+ var LinkedList, cache, createCache, deliver, dropByDate, dropByFunction, dropMessages, isArray, isDate, isFunction, postie, receive, retract;
+ LinkedList = (function() {
+ function LinkedList() {
+ var first, last;
+ first = null;
+ last = null;
+ this.first = function() {
+ return first;
+ };
+ this.last = function() {
+ return last;
+ };
+ this.length = 0;
+ this.append = function(data) {
+ var node;
+ if (!data) {
+ return;
+ }
+ node = {
+ data: data,
+ next: null,
+ prev: null
+ };
+ if (!first) {
+ first = node;
+ last = node;
+ } else {
+ last.next = node;
+ node.prev = last;
+ last = node;
+ }
+ return this.length++;
+ };
+ this.remove = function(node) {
+ if (!node) {
+ return;
+ }
+ if (!node.prev) {
+ first = node.next;
+ if (first) {
+ first.prev = null;
+ }
+ } else {
+ node.prev.next = node.next;
+ }
+ return this.length--;
+ };
+ }
+ return LinkedList;
+ })();
cache = {};
postie;
isArray = function(obj) {
@@ -13,12 +62,12 @@
};
createCache = function(name) {
return cache[name] = {
- subs: [],
- history: []
+ subs: new LinkedList,
+ history: new LinkedList
};
};
deliver = function(name, args) {
- var fn, _i, _len, _ref;
+ var fn;
if (!cache[name]) {
createCache(name);
}
@@ -29,46 +78,49 @@
args = [args];
}
args = {
- created: new Date(),
- lastPublished: new Date(),
+ created: new Date,
+ lastPublished: new Date,
args: args
};
- cache[name].history.push(args);
- _ref = cache[name].subs;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- fn = _ref[_i];
- fn.apply(this, args.args);
+ cache[name].history.append(args);
+ fn = cache[name].subs.first();
+ while (fn) {
+ fn.data.apply(this, args.args);
+ fn = fn.next;
}
return postie;
};
receive = function(name, fn, ignoreHistory) {
- var arg, _i, _len, _ref;
+ var arg;
if (!cache[name]) {
createCache(name);
}
- cache[name].subs.push(fn);
+ cache[name].subs.append(fn);
if (!ignoreHistory) {
- _ref = cache[name].history;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- arg = _ref[_i];
- fn.apply(this, arg.args);
- arg.lastPublished = new Date();
+ arg = cache[name].history.first();
+ while (arg) {
+ fn.apply(this, arg.data.args);
+ arg.data.lastPublished = new Date;
+ arg = arg.next;
}
+ return postie;
}
- return postie;
};
retract = function(name, fn) {
- var index, subs;
+ var sub, subs;
if (!cache[name]) {
createCache(name);
}
if (!fn) {
- cache[name].subs = [];
+ cache[name].subs = new LinkedList;
} else {
subs = cache[name].subs;
- index = subs.indexOf(fn);
- if (index > -1) {
- subs.splice(0, index).concat(subs.splice(index, subs.length));
+ sub = subs.first();
+ while (sub) {
+ if (sub.data === fn) {
+ subs.remove(sub);
+ }
+ sub = sub.next;
}
}
return postie;
@@ -85,23 +137,38 @@
cache[name].history = dropByDate(criteria, cache[name].history);
}
} else {
- cache[name].history = [];
+ cache[name].history = new LinkedList;
}
return postie.deliver('dropMessage.' + name);
};
dropByFunction = function(fn, msgs) {
- return msgs.filter(fn);
+ var msg;
+ msg = msgs.first();
+ while (msg) {
+ if (fn.apply(msg.data)) {
+ msgs.remove(msg);
+ }
+ msg = msg.next;
+ }
+ return msgs;
};
dropByDate = function(date, msgs) {
- return msgs.filter(function(x) {
- return x.created < date;
- });
+ var msg;
+ msg = msgs.first();
+ while (msg) {
+ if (msg.data.created < date) {
+ msgs.remove(msg);
+ }
+ msg = msg.next;
+ }
+ return msgs;
};
postie = {
deliver: deliver,
receive: receive,
dropMessages: dropMessages,
retract: retract
};
+ this.LinkedList = LinkedList;
this.postman = postie;
}).call(this);
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,3 +1,43 @@
+class LinkedList
+ constructor: () ->
+ first = null
+ last = null
+
+ @first = () ->
+ first
+ @last = () ->
+ last
+ @length = 0
+
+ @append = (data) ->
+ return if !data
+
+ node =
+ data: data
+ next: null
+ prev: null
+
+ if !first
+ first = node
+ last = node
+ else
+ last.next = node
+ node.prev = last
+ last = node
+
+ @length++
+
+ @remove = (node) ->
+ return if !node
+
+ if !node.prev
+ first = node.next
+ if first
+ first.prev = null
+ else
+ node.prev.next = node.next
+ @length--
+
cache = {}
postie
isArray = (obj) ->
@@ -9,62 +49,81 @@ isDate = (obj) ->
createCache = (name) ->
cache[name] =
- subs: []
- history: []
+ subs: new LinkedList
+ history: new LinkedList
deliver = (name, args) ->
createCache name if ! cache[name]
args = [] if !args
args = [args] if !isArray args
args =
- created: new Date()
- lastPublished: new Date()
+ created: new Date
+ lastPublished: new Date
args: args
- cache[name].history.push args
- fn.apply this, args.args for fn in cache[name].subs
+ cache[name].history.append args
+ fn = cache[name].subs.first()
+
+ while fn
+ fn.data.apply this, args.args
+ fn = fn.next
+
postie
receive = (name, fn, ignoreHistory) ->
createCache name if ! cache[name]
- cache[name].subs.push fn
+ cache[name].subs.append fn
if !ignoreHistory
- for arg in cache[name].history
- fn.apply this, arg.args
- arg.lastPublished = new Date()
- postie
+ arg = cache[name].history.first()
+ while arg
+ fn.apply this, arg.data.args
+ arg.data.lastPublished = new Date
+ arg = arg.next
+ postie
retract = (name, fn) ->
createCache name if !cache[name]
if !fn
- cache[name].subs = []
+ cache[name].subs = new LinkedList
else
subs = cache[name].subs
- index = subs.indexOf fn
- if index > -1
- subs.splice(0, index).concat subs.splice index, subs.length
+ sub = subs.first()
+ while sub
+ if sub.data == fn
+ subs.remove sub
+ sub = sub.next
postie
-
+
dropMessages = (name, criteria) ->
createCache name if ! cache[name]
if criteria
cache[name].history = dropByFunction criteria, cache[name].history if isFunction criteria
cache[name].history = dropByDate criteria, cache[name].history if isDate criteria
else
- cache[name].history = []
+ cache[name].history = new LinkedList
postie.deliver 'dropMessage.' + name
dropByFunction = (fn, msgs) ->
- msgs.filter fn
+ msg = msgs.first()
+ while msg
+ if fn.apply msg.data
+ msgs.remove msg
+ msg = msg.next
+ msgs
dropByDate = (date, msgs) ->
- msgs.filter (x) ->
- x.created < date
+ msg = msgs.first()
+ while msg
+ if msg.data.created < date
+ msgs.remove msg
+ msg = msg.next
+ msgs
postie =
deliver: deliver
receive: receive
dropMessages: dropMessages
retract: retract
+this.LinkedList = LinkedList
this.postman = postie
View
@@ -54,9 +54,10 @@ test('can retract a callback and not receive messages', function() {
});
test('messages dropped by date', function() {
+ var d = new Date();
postman.deliver('test9', false);
- postman.dropMessages('test9', new Date());
+ postman.dropMessages('test9', new Date(d.getFullYear() + 1, d.getMonth(), d.getDay(), d.getHours(), d.getMinutes(), d.getSeconds()));
postman.deliver('test9', true);

0 comments on commit 260791c

Please sign in to comment.