'use strict'; var Gun = require('../../gun'); var cache = {}; var timeout = null; /** * Remove all entries in the cache older than 5 minutes. * Reschedules itself to run again when the oldest item * might be too old. * @return {undefined} */ function gc () { var now = Date.now(); var oldest = now; var maxAge = 5 * 60 * 1000; Gun.obj.map(cache, function (time, id) { oldest = Math.min(now, time); if ((now - time) < maxAge) { return; } delete cache[id]; }); var done = Gun.obj.empty(cache); // Disengage GC. if (done) { timeout = null; return; } // Just how old? var elapsed = now - oldest; // How long before it's too old? var nextGC = maxAge - elapsed; // Schedule the next GC event. timeout = setTimeout(gc, nextGC); } /** * Checks a memory-efficient cache to see if a string has been seen before. * @param {String} id - A string to keep track of. * @return {Boolean} - Whether it's been seen recently. */ function duplicate (id) { // Have we seen this ID recently? var existing = cache.hasOwnProperty(id); // Add it to the cache. duplicate.track(id); return existing; } /** * Starts tracking an ID as a possible future duplicate. * @param {String} id - The ID to track. * @return {String} - The same ID. */ duplicate.track = function (id) { cache[id] = Date.now(); // Engage GC. if (!timeout) { gc(); } return id; }; /** * Generate a new ID and start tracking it. * @param {Number} [chars] - The number of characters to use. * @return {String} - The newly created ID. */ duplicate.track.newID = function (chars) { var id = Gun.text.random(chars); return duplicate.track(id); }; module.exports = duplicate;