function listOnTimeout() { var msecs = this.msecs; var list = this; debug('timeout callback %d', msecs); var now = Date.now(); debug('now: %s', now); var first; while (first = L.peek(list)) { var diff = now - first._idleStart; if (diff < msecs) { list.start(msecs - diff, 0); debug('%d list wait because diff is %d', msecs, diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (!first._onTimeout) continue; // v0.4 compatibility: if the timer callback throws and the // domain or uncaughtException handler ignore the exception, // other timers that expire on this tick should still run. // // https://github.com/joyent/node/issues/2631 var domain = first.domain; if (domain && domain._disposed) continue; try { if (domain) domain.enter(); var threw = true; first._onTimeout(); if (domain) domain.exit(); threw = false; } finally { if (threw) { process.nextTick(function() { list.ontimeout(); }); } } } } debug('%d list empty', msecs); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; }
exports.active = function(item) { var msecs = item._idleTimeout; if (msecs >= 0) { var list = lists[msecs]; if (!list || L.isEmpty(list)) { insert(item, msecs); } else { item._idleStart = Date.now(); L.append(list, item); } } };
function reuse(item) { L.remove(item); var list = lists[item._idleTimeout]; // if empty - reuse the watcher if (list && L.isEmpty(list)) { debug('reuse hit'); list.stop(); delete lists[item._idleTimeout]; return list; } return null; }
var unenroll = exports.unenroll = function(item) { L.remove(item); var list = lists[item._idleTimeout]; // if empty then stop the watcher debug('unenroll'); if (list && L.isEmpty(list)) { debug('unenroll: list empty'); list.close(); delete lists[item._idleTimeout]; } // if active is called later, then we want to make sure not to insert again item._idleTimeout = -1; };
// the main function - creates lists on demand and the watchers associated // with them. function insert(item, msecs) { item._idleStart = new Date(); item._idleTimeout = msecs; if (msecs < 0) return; var list; if (lists[msecs]) { list = lists[msecs]; } else { list = new Timer(); list.start(msecs, 0); L.init(list); lists[msecs] = list; list.ontimeout = function() { debug('timeout callback ' + msecs); // TODO - don't stop and start the watcher all the time. // just set its repeat var now = new Date(); debug('now: ' + now); var first; while (first = L.peek(list)) { var diff = now - first._idleStart; if (diff + 1 < msecs) { list.start(diff, 0); debug(msecs + ' list wait because diff is ' + diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (first._onTimeout) first._onTimeout(); } } debug(msecs + ' list empty'); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; }; } L.append(list, item); assert(!L.isEmpty(list)); // list is not empty }
function processImmediate() { var immediate = L.shift(immediateQueue); if (L.isEmpty(immediateQueue)) { process._needImmediateCallback = false; } if (immediate._onImmediate) { if (immediate.domain) immediate.domain.enter(); immediate._onImmediate(); if (immediate.domain) immediate.domain.exit(); } }
function processImmediate() { var immediate; if (L.isEmpty(immediateQueue)) { immediateTimer.stop(); immediateQueue.started = false; } else { immediate = L.shift(immediateQueue); if (immediate.domain) immediate.domain.enter(); immediate._onTimeout(); if (immediate.domain) immediate.domain.exit(); } }
exports.active = function(item) { var msecs = item._idleTimeout; if (msecs >= 0) { var list = lists[msecs]; if (!list || L.isEmpty(list)) { insert(item, msecs); } else { item._idleStart = Timer.now(); L.append(list, item); } } // Whether or not a new TimerWrap needed to be created, this should run // for each item. This way each "item" (i.e. timer) can properly have // their own domain assigned. if (asyncFlags[kHasListener] > 0) runAsyncQueue(item); };
list.ontimeout = function() { debug('timeout callback ' + msecs); var now = Date.now(); debug('now: ' + (new Date(now))); var first; while (first = L.peek(list)) { var diff = now - first._idleStart; if (diff + 1 < msecs) { list.start(msecs - diff, 0); debug(msecs + ' list wait because diff is ' + diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (!first._onTimeout) continue; // v0.4 compatibility: if the timer callback throws and the user's // uncaughtException handler ignores the exception, other timers that // expire on this tick should still run. If #2582 goes through, this // hack should be removed. // // https://github.com/joyent/node/issues/2631 if (first.domain) { if (first.domain._disposed) continue; first.domain.enter(); } try { first._onTimeout(); } catch (e) { if (!process.listeners('uncaughtException').length) throw e; process.emit('uncaughtException', e); } if (first.domain) first.domain.exit(); } } debug(msecs + ' list empty'); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; };
exports.active = function(item) { var msecs = item._idleTimeout; if (msecs >= 0) { var list = lists[msecs]; if (!list || L.isEmpty(list)) { insert(item, msecs); } else { item._idleStart = Date.now(); item._monotonicStartTime = Timer.now(); L.append(list, item); } list = lists[msecs]; // Set _addedTimer so that listOnTimeout can refresh // its current time value to avoid wrong timing computation // in case timers callback block for a while. // See test/simple/test-timers-blocking-callback.js for more // details list._addedTimer = true; } };
exports.active = function(item) { const msecs = item._idleTimeout; if (msecs < 0 || msecs === undefined) return; item._idleStart = Timer.now(); var list; if (lists[msecs]) { list = lists[msecs]; } else { list = new Timer(); list.start(msecs, 0); L.init(list); lists[msecs] = list; list.msecs = msecs; list[kOnTimeout] = listOnTimeout; } L.append(list, item); assert(!L.isEmpty(list)); // list is not empty };
// the main function - creates lists on demand and the watchers associated // with them. function insert(item, msecs) { item._idleStart = Date.now(); item._idleTimeout = msecs; if (msecs < 0) return; var list; if (lists[msecs]) { list = lists[msecs]; } else { list = new Timer(); list.start(msecs, 0); L.init(list); lists[msecs] = list; list.msecs = msecs; list.ontimeout = listOnTimeout; } L.append(list, item); assert(!L.isEmpty(list)); // list is not empty }
(function () { var _linklist = require('_linklist'), linklist = require('./lib/linklist'); var ITERATIONS = 1000000, startTime, listObject, i, obj; startTime = Date.now(); console.log("START ORIGINAL TEST AT", startTime); listObject = {}; _linklist.init(listObject); for (i = 0; i < ITERATIONS; i++) { _linklist.append(listObject, { idx: i }); } while (!_linklist.isEmpty(listObject)) { obj = _linklist.shift(listObject); //console.log(obj); } console.log("PROCESS TIME IS %d milliseconds", Date.now() - startTime); console.log(""); startTime = Date.now(); console.log("START CHALLENGED TEST AT", startTime); listObject = {}; listObject.firstList = new linklist.LinkList(); for (i = 0; i < ITERATIONS; i++) { listObject.firstList.append({ idx: i }); } while (!listObject.firstList.isEmpty()) { obj = listObject.firstList.shift(); //console.log(obj); } // iterator test /*listObject.firstList.forEach(function (item) { listObject.firstList.remove(item); });*/ // map test /*console.log(listObject.firstList.map(function (item) { return item; }));*/ console.log("PROCESS TIME IS %d milliseconds", Date.now() - startTime); }());
const L = require('_linklist'); var list = { name: 'list' }; var A = { name: 'A' }; var B = { name: 'B' }; var C = { name: 'C' }; var D = { name: 'D' }; L.init(list); L.init(A); L.init(B); L.init(C); L.init(D); assert.ok(L.isEmpty(list)); assert.equal(null, L.peek(list)); L.append(list, A); // list -> A assert.equal(A, L.peek(list)); L.append(list, B); // list -> A -> B assert.equal(A, L.peek(list)); L.append(list, C); // list -> A -> B -> C assert.equal(A, L.peek(list)); L.append(list, D);
function listOnTimeout() { var msecs = this.msecs; var list = this; debug('timeout callback %d', msecs); var now = Timer.now(); debug('now: %s', now); var diff, first, hasQueue, threw; while (first = L.peek(list)) { diff = now - first._idleStart; if (diff < msecs) { list.start(msecs - diff, 0); debug('%d list wait because diff is %d', msecs, diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (!first._onTimeout) continue; // v0.4 compatibility: if the timer callback throws and the // domain or uncaughtException handler ignore the exception, // other timers that expire on this tick should still run. // // https://github.com/joyent/node/issues/2631 var domain = first.domain; if (domain && domain._disposed) continue; hasQueue = !!first._asyncQueue; try { if (hasQueue) loadAsyncQueue(first); if (domain) domain.enter(); threw = true; first._onTimeout(); if (domain) domain.exit(); if (hasQueue) unloadAsyncQueue(first); threw = false; } finally { if (threw) { // We need to continue processing after domain error handling // is complete, but not by using whatever domain was left over // when the timeout threw its exception. var oldDomain = process.domain; process.domain = null; process.nextTick(function() { list[kOnTimeout](); }); process.domain = oldDomain; } } } } debug('%d list empty', msecs); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; }
function listOnTimeout() { var msecs = this.msecs; var list = this; debug('timeout callback %d', msecs); var now = Timer.now(); debug('now: %d', now); var diff, first, threw; while (first = L.peek(list)) { // If the previous iteration caused a timer to be added, // update the value of "now" so that timing computations are // done correctly. See test/simple/test-timers-blocking-callback.js // for more information. if (now < first._idleStart) { now = Timer.now(); debug('now: %d', now); } diff = now - first._idleStart; if (diff < msecs) { list.start(msecs - diff, 0); debug('%d list wait because diff is %d', msecs, diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (!first._onTimeout) continue; // v0.4 compatibility: if the timer callback throws and the // domain or uncaughtException handler ignore the exception, // other timers that expire on this tick should still run. // // https://github.com/joyent/node/issues/2631 var domain = first.domain; if (domain && domain._disposed) continue; try { if (domain) domain.enter(); threw = true; first._onTimeout(); if (domain) domain.exit(); threw = false; } finally { if (threw) { // We need to continue processing after domain error handling // is complete, but not by using whatever domain was left over // when the timeout threw its exception. var oldDomain = process.domain; process.domain = null; process.nextTick(function() { list[kOnTimeout](); }); process.domain = oldDomain; } } } } debug('%d list empty', msecs); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; }
function unrefTimeout() { var now = Timer.now(); debug('unrefTimer fired'); var timeSinceLastActive; var nextTimeoutTime; var nextTimeoutDuration; var minNextTimeoutTime; var timersToTimeout = []; // The actual timer fired and has not yet been rearmed, // let's consider its next firing time is invalid for now. // It may be set to a relevant time in the future once // we scanned through the whole list of timeouts and if // we find a timeout that needs to expire. unrefTimer.when = -1; // Iterate over the list of timeouts, // call the onTimeout callback for those expired, // and rearm the actual timer if the next timeout to expire // will expire before the current actual timer. var cur = unrefList._idlePrev; while (cur != unrefList) { timeSinceLastActive = now - cur._idleStart; if (timeSinceLastActive < cur._idleTimeout) { // This timer hasn't expired yet, but check if its expiring time is // earlier than the actual timer's expiring time nextTimeoutDuration = cur._idleTimeout - timeSinceLastActive; nextTimeoutTime = now + nextTimeoutDuration; if (minNextTimeoutTime == null || (nextTimeoutTime < minNextTimeoutTime)) { // We found a timeout that will expire earlier, // store its next timeout time now so that we // can rearm the actual timer accordingly when // we scanned through the whole list. minNextTimeoutTime = nextTimeoutTime; } } else { // We found a timer that expired. Do not call its _onTimeout callback // right now, as it could mutate any item of the list (including itself). // Instead, add it to another list that will be processed once the list // of current timers has been fully traversed. timersToTimeout.push(cur); } cur = cur._idlePrev; } var nbTimersToTimeout = timersToTimeout.length; for (var timerIdx = 0; timerIdx < nbTimersToTimeout; ++timerIdx) _makeTimerTimeout(timersToTimeout[timerIdx]); // Rearm the actual timer with the timeout delay // of the earliest timeout found. if (minNextTimeoutTime != null) { unrefTimer.start(minNextTimeoutTime - now, 0); unrefTimer.when = minNextTimeoutTime; debug('unrefTimer rescheduled'); } else if (L.isEmpty(unrefList)) { debug('unrefList is empty'); } }
// the main function - creates lists on demand and the watchers associated // with them. function insert(item, msecs) { item._idleStart = new Date(); item._idleTimeout = msecs; if (msecs < 0) return; var list; if (lists[msecs]) { list = lists[msecs]; } else { list = new Timer(); list.start(msecs, 0); L.init(list); lists[msecs] = list; list.ontimeout = function() { debug('timeout callback ' + msecs); var now = new Date(); debug('now: ' + now); var first; while (first = L.peek(list)) { var diff = now - first._idleStart; if (diff + 1 < msecs) { list.start(msecs - diff, 0); debug(msecs + ' list wait because diff is ' + diff); return; } else { L.remove(first); assert(first !== L.peek(list)); if (!first._onTimeout) continue; // v0.4 compatibility: if the timer callback throws and the user's // uncaughtException handler ignores the exception, other timers that // expire on this tick should still run. If #2582 goes through, this // hack should be removed. // // https://github.com/joyent/node/issues/2631 try { first._onTimeout(); } catch (e) { if (!process.listeners('uncaughtException').length) throw e; process.emit('uncaughtException', e); } } } debug(msecs + ' list empty'); assert(L.isEmpty(list)); list.close(); delete lists[msecs]; }; } L.append(list, item); assert(!L.isEmpty(list)); // list is not empty }