From 8036341cf132091721dff095a2e29c40ebe08c96 Mon Sep 17 00:00:00 2001 From: Matthew Forrester Date: Sat, 19 Oct 2013 17:17:07 +0100 Subject: [PATCH] Use a tiny function to tack tiny UUID's to end of LocalStorage keys instead of a seperate indexer --- src/adapters/dom.js | 252 ++++++++++++++++++++++++++++++-------------- 1 file changed, 172 insertions(+), 80 deletions(-) diff --git a/src/adapters/dom.js b/src/adapters/dom.js index 553b1630..3034398b 100644 --- a/src/adapters/dom.js +++ b/src/adapters/dom.js @@ -11,44 +11,97 @@ // Lawnchair.adapter('dom', (function() { var storage = window.localStorage - // the indexer is an encapsulation of the helpers needed to keep an ordered index of the keys - var indexer = function(name) { - return { - // the key - key: name + '._index_', - // returns the index - all: function() { - var a = storage.getItem(JSON.stringify(this.key)) - if (a) { - a = JSON.parse(a) - } - if (a === null) storage.setItem(JSON.stringify(this.key), JSON.stringify([])) // lazy init - return JSON.parse(storage.getItem(JSON.stringify(this.key))) - }, - // adds a key to the index - add: function (key) { - var a = this.all() - a.push(key) - storage.setItem(JSON.stringify(this.key), JSON.stringify(a)) - }, - // deletes a key from the index - del: function (key) { - var a = this.all(), r = [] - // FIXME this is crazy inefficient but I'm in a strata meeting and half concentrating - for (var i = 0, l = a.length; i < l; i++) { - if (a[i] != key) r.push(a[i]) - } - storage.setItem(JSON.stringify(this.key), JSON.stringify(r)) - }, - // returns index for a key - find: function (key) { - var a = this.all() - for (var i = 0, l = a.length; i < l; i++) { - if (key === a[i]) return i + + // Generates (quite) small incremental UUID's which are tacked onto the end + // of LocalStorage keys to remove the requirement for a seperate indexer. + // + // NOTE: Taken from https://github.com/forbesmyester/SyncIt, Could be used + // for Lawnchair.uuid() + var getTLIdEncoderDecoder = function(epoch,uniqueLength) { + + var lastDate = null; + var index = -1; + if (uniqueLength === undefined) { + uniqueLength = 1; + } + + if (typeof epoch != 'number') { + throw "Only takes timestamps"; + } + + var genUid = function(now) { + + if (now === undefined) { + now = new Date().getTime(); + } + if (typeof now == 'object') { + throw "Only takes timestamps"; + } + + if ((lastDate === null) || (now !== lastDate)) { + index = -1; + } + + var superUnique = (++index).toString(32); + if (superUnique.length < uniqueLength) { + superUnique = '0' + superUnique; + } + var timeEncoded = (now - epoch).toString(32); + + if (superUnique.length > uniqueLength) { + throw "getUidGenerator.genUid cannot generate TLId until next millisecond!"; + } + + lastDate = now; + if (timeEncoded.substr(0,1) <= '9') { + return "X"+timeEncoded+superUnique; + } + return timeEncoded+superUnique; + }; + + var uidToTimestamp = function(tlid) { + if (tlid.substr(0,1) == 'X') { + tlid = tlid.substr(1); + } + tlid = tlid.substr(0, tlid.length - uniqueLength); + return parseInt(tlid,32) + epoch; + }; + + var sort = function(tlidA, tlidB) { + if (tlidA.substr(0,1) == 'X') { + tlidA = tlidA.substr(1); + } + if (tlidB.substr(0,1) == 'X') { + tlidB = tlidB.substr(1); + } + tlidA = tlidA.replace(/.*\./,''); + tlidB = tlidB.replace(/.*\./,''); + if (tlidA.length != tlidB.length) { + return (tlidA.length < tlidB.length) ? -1 : 1; + } + return (tlidA < tlidB) ? -1 : 1; + }; + + return {encode: genUid, decode: uidToTimestamp, sort: sort}; + }; + + var keyCollector = function(inst, searchKey) { + var keys = []; + var key; + var subKey; + for (var i = 0, l = storage.length; i