memoizerific
Advanced tools
Comparing version
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.memoizerific = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
if (typeof Map !== 'function' || (process && process.env && process.env.TEST_MAPORSIMILAR === 'true')) { | ||
module.exports = _dereq_('./similar'); | ||
module.exports = _dereq_('./similar'); | ||
} | ||
else { | ||
module.exports = Map; | ||
module.exports = Map; | ||
} | ||
},{"./similar":2}],2:[function(_dereq_,module,exports){ | ||
function Similar() { | ||
this.list = []; | ||
this.lastItem = undefined; | ||
this.size = 0; | ||
this.list = []; | ||
this.lastItem = undefined; | ||
this.size = 0; | ||
return this; | ||
return this; | ||
} | ||
Similar.prototype.get = function(key) { | ||
var index; | ||
var index; | ||
if (this.lastItem && this.lastItem.key === key) { | ||
return this.lastItem.val; | ||
} | ||
if (this.lastItem && this.isEqual(this.lastItem.key, key)) { | ||
return this.lastItem.val; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
return this.list[index].val; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
return this.list[index].val; | ||
} | ||
return undefined; | ||
return undefined; | ||
}; | ||
Similar.prototype.set = function(key, val) { | ||
var index; | ||
var index; | ||
if (this.lastItem && this.lastItem.key === key) { | ||
this.lastItem.val = val; | ||
return this; | ||
} | ||
if (this.lastItem && this.isEqual(this.lastItem.key, key)) { | ||
this.lastItem.val = val; | ||
return this; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
this.list[index].val = val; | ||
return this; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
this.list[index].val = val; | ||
return this; | ||
} | ||
this.lastItem = { key: key, val: val }; | ||
this.list.push(this.lastItem); | ||
this.size++; | ||
this.lastItem = { key: key, val: val }; | ||
this.list.push(this.lastItem); | ||
this.size++; | ||
return this; | ||
return this; | ||
}; | ||
Similar.prototype.delete = function(key) { | ||
var index; | ||
var index; | ||
if (this.lastItem && this.lastItem.key === key) { | ||
this.lastItem = undefined; | ||
} | ||
if (this.lastItem && this.isEqual(this.lastItem.key, key)) { | ||
this.lastItem = undefined; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.size--; | ||
return this.list.splice(index, 1)[0]; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.size--; | ||
return this.list.splice(index, 1)[0]; | ||
} | ||
return undefined; | ||
return undefined; | ||
}; | ||
@@ -74,34 +74,39 @@ | ||
Similar.prototype.has = function(key) { | ||
var index; | ||
var index; | ||
if (this.lastItem && this.lastItem.key === key) { | ||
return true; | ||
} | ||
if (this.lastItem && this.isEqual(this.lastItem.key, key)) { | ||
return true; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
return true; | ||
} | ||
index = this.indexOf(key); | ||
if (index >= 0) { | ||
this.lastItem = this.list[index]; | ||
return true; | ||
} | ||
return false; | ||
return false; | ||
}; | ||
Similar.prototype.forEach = function(callback, thisArg) { | ||
var i; | ||
for (i = 0; i < this.size; i++) { | ||
callback.call(thisArg || this, this.list[i].val, this.list[i].key, this); | ||
} | ||
var i; | ||
for (i = 0; i < this.size; i++) { | ||
callback.call(thisArg || this, this.list[i].val, this.list[i].key, this); | ||
} | ||
}; | ||
Similar.prototype.indexOf = function(key) { | ||
var i; | ||
for (i = 0; i < this.size; i++) { | ||
if (this.list[i].key === key) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
var i; | ||
for (i = 0; i < this.size; i++) { | ||
if (this.isEqual(this.list[i].key, key)) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
// check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) | ||
Similar.prototype.isEqual = function(val1, val2) { | ||
return val1 === val2 || (val1 !== val1 && val2 !== val2); | ||
}; | ||
module.exports = Similar; | ||
@@ -112,79 +117,81 @@ },{}],3:[function(_dereq_,module,exports){ | ||
module.exports = function (limit) { | ||
var cache = new MapOrSimilar(), | ||
lru = []; | ||
var cache = new MapOrSimilar(), | ||
lru = []; | ||
return function (fn) { | ||
var memoizerific = function () { | ||
var currentCache = cache, | ||
newMap, | ||
fnResult, | ||
argsLengthMinusOne = arguments.length - 1, | ||
lruPath = Array(argsLengthMinusOne + 1), | ||
isMemoized = true, | ||
i; | ||
return function (fn) { | ||
var memoizerific = function () { | ||
var currentCache = cache, | ||
newMap, | ||
fnResult, | ||
argsLengthMinusOne = arguments.length - 1, | ||
lruPath = Array(argsLengthMinusOne + 1), | ||
isMemoized = true, | ||
i; | ||
// loop through each argument to traverse the map tree | ||
for (i = 0; i < argsLengthMinusOne; i++) { | ||
lruPath[i] = { | ||
cacheItem: currentCache, | ||
arg: arguments[i] | ||
}; | ||
// loop through each argument to traverse the map tree | ||
for (i = 0; i < argsLengthMinusOne; i++) { | ||
lruPath[i] = { | ||
cacheItem: currentCache, | ||
arg: arguments[i] | ||
}; | ||
// if all arguments exist in map tree, the memoized result will be last value to be retrieved | ||
if (currentCache.has(arguments[i])) { | ||
currentCache = currentCache.get(arguments[i]); | ||
continue; | ||
} | ||
// if all arguments exist in map tree, the memoized result will be last value to be retrieved | ||
if (currentCache.has(arguments[i])) { | ||
currentCache = currentCache.get(arguments[i]); | ||
continue; | ||
} | ||
isMemoized = false; | ||
isMemoized = false; | ||
// make maps until last value | ||
newMap = new MapOrSimilar(); | ||
currentCache.set(arguments[i], newMap); | ||
currentCache = newMap; | ||
} | ||
// make maps until last value | ||
newMap = new MapOrSimilar(); | ||
currentCache.set(arguments[i], newMap); | ||
currentCache = newMap; | ||
} | ||
// we are at the last arg, check if it is really memoized | ||
if (isMemoized) { | ||
if (currentCache.has(arguments[argsLengthMinusOne])) { | ||
fnResult = currentCache.get(arguments[argsLengthMinusOne]); | ||
} else { | ||
isMemoized = false; | ||
} | ||
} | ||
// we are at the last arg, check if it is really memoized | ||
if (isMemoized) { | ||
if (currentCache.has(arguments[argsLengthMinusOne])) { | ||
fnResult = currentCache.get(arguments[argsLengthMinusOne]); | ||
} | ||
else { | ||
isMemoized = false; | ||
} | ||
} | ||
if (!isMemoized) { | ||
fnResult = fn.apply(null, arguments); | ||
currentCache.set(arguments[argsLengthMinusOne], fnResult); | ||
} | ||
if (!isMemoized) { | ||
fnResult = fn.apply(null, arguments); | ||
currentCache.set(arguments[argsLengthMinusOne], fnResult); | ||
} | ||
if (limit > 0) { | ||
lruPath[argsLengthMinusOne] = { | ||
cacheItem: currentCache, | ||
arg: arguments[argsLengthMinusOne] | ||
}; | ||
if (limit > 0) { | ||
lruPath[argsLengthMinusOne] = { | ||
cacheItem: currentCache, | ||
arg: arguments[argsLengthMinusOne] | ||
}; | ||
if (isMemoized) { | ||
moveToMostRecentLru(lru, lruPath); | ||
} else { | ||
lru.push(lruPath); | ||
} | ||
if (isMemoized) { | ||
moveToMostRecentLru(lru, lruPath); | ||
} | ||
else { | ||
lru.push(lruPath); | ||
} | ||
if (lru.length > limit) { | ||
removeCachedResult(lru.shift()); | ||
} | ||
} | ||
if (lru.length > limit) { | ||
removeCachedResult(lru.shift()); | ||
} | ||
} | ||
memoizerific.wasMemoized = isMemoized; | ||
memoizerific.wasMemoized = isMemoized; | ||
return fnResult; | ||
}; | ||
return fnResult; | ||
}; | ||
memoizerific.limit = limit; | ||
memoizerific.wasMemoized = false; | ||
memoizerific.cache = cache; | ||
memoizerific.lru = lru; | ||
memoizerific.limit = limit; | ||
memoizerific.wasMemoized = false; | ||
memoizerific.cache = cache; | ||
memoizerific.lru = lru; | ||
return memoizerific; | ||
}; | ||
return memoizerific; | ||
}; | ||
}; | ||
@@ -194,21 +201,21 @@ | ||
function moveToMostRecentLru(lru, lruPath) { | ||
var lruLen = lru.length, | ||
lruPathLen = lruPath.length, | ||
isMatch, | ||
i, ii; | ||
var lruLen = lru.length, | ||
lruPathLen = lruPath.length, | ||
isMatch, | ||
i, ii; | ||
for (i = 0; i < lruLen; i++) { | ||
isMatch = true; | ||
for (ii = 0; ii < lruPathLen; ii++) { | ||
if (lru[i][ii].arg !== lruPath[ii].arg) { | ||
isMatch = false; | ||
break; | ||
} | ||
} | ||
if (isMatch) { | ||
break; | ||
} | ||
} | ||
for (i = 0; i < lruLen; i++) { | ||
isMatch = true; | ||
for (ii = 0; ii < lruPathLen; ii++) { | ||
if (!isEqual(lru[i][ii].arg, lruPath[ii].arg)) { | ||
isMatch = false; | ||
break; | ||
} | ||
} | ||
if (isMatch) { | ||
break; | ||
} | ||
} | ||
lru.push(lru.splice(i, 1)[0]); | ||
lru.push(lru.splice(i, 1)[0]); | ||
} | ||
@@ -218,23 +225,27 @@ | ||
function removeCachedResult(removedLru) { | ||
var removedLruLen = removedLru.length, | ||
currentLru = removedLru[removedLruLen - 1], | ||
tmp, | ||
i; | ||
var removedLruLen = removedLru.length, | ||
currentLru = removedLru[removedLruLen - 1], | ||
tmp, | ||
i; | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
// walk down the tree removing dead branches (size 0) along the way | ||
for (i = removedLruLen - 2; i >= 0; i--) { | ||
currentLru = removedLru[i]; | ||
tmp = currentLru.cacheItem.get(currentLru.arg); | ||
// walk down the tree removing dead branches (size 0) along the way | ||
for (i = removedLruLen - 2; i >= 0; i--) { | ||
currentLru = removedLru[i]; | ||
tmp = currentLru.cacheItem.get(currentLru.arg); | ||
if (!tmp || !tmp.size) { | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
} else { | ||
break; | ||
} | ||
} | ||
if (!tmp || !tmp.size) { | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
// check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) | ||
function isEqual(val1, val2) { | ||
return val1 === val2 || (val1 !== val1 && val2 !== val2); | ||
} | ||
},{"map-or-similar":1}]},{},[3])(3) | ||
}); |
@@ -1,3 +0,6 @@ | ||
� W�VQo�6~߯����0��ɛT���4C�>B��T�U"5�J����;��m�^��/6u:�}w��i%+�DoD�F��O������*���ǣJ�y*$_����B���c����"��������G�Q�c��b���bb���3�qz.닐k����9��\=�|���z��K��L�J��Z�"q�5ڵ7p,�DD��J�A�n`X����E#FT�̡X�دx�rarz�'��U Mi�ۣ����r:�ag��M�65�����V�~cR*;�����F6���fZ�� Qkh��݇��>��?�~��ӇIk��;ݴ3 7u�V�8HX���79d��*h�8�W6�ڥ�X���Td���(��n�\��e�B%.��7�"��"��9�O6��d�52��;5�����K�7��;nܲr�-�J����g8VW`�kp�����ꏻ�_nno>^}^��Q��ș�p���ds�2��crq | ||
p�+<lkq� ra,uG�y`��X^�g%փ�7 4��� �*Wb��-=��z��p�q�1��_�x��[��!N#p��K!,�:[�>�����=�����%����NS���!'�ś��!r���7m h�k�����2Y��G6��`GmX�[�s���9���ޚ�5��7e.�7� ���p3f~�d���bHb8�5��%�Y9������H��X�t|�m��� �O���~�.+�Έd��cP�h�щ~���&{51�% �o�Ǿdj[�$��n��$��%]32� g��g�Ěk�Ձ\���5�OC�H�[�D��<zԜ}��Kc��(�QG�ԩ�ͮ5{t tŧ����`$I���� &��hʧ�r ��> ��?�^�<4�������c��_A �+�JOwZ��2��2� 0 �}=��p����Q�[\��6��IB��f�(��1)�4ʦ%�$[�Q 3IV%\ػ:@�p��$w���2�yӛ�5D�eNҶ�܉pσ���4�]�p��q��W'����P�v�*�V��+�U�@�n�$g� | ||
�L.܄x|���-� ��Px�% �mK���M&)|�AX�0s�?״ U�U��(�R{��Q�609p���DT]�k��,Ἆ� %���K\�藿��-�z | ||
� �z=W�VQo�6~߯����0��ɛT��(�4C�>B��TĕU�J����;��e�^6}������ҪH��oЖ��X>��3&ļ�L�#������d\��m�^���M%r��U%�G�����~o�Y�L�7�������qG�OT�X��9�ϼ������4�|�b�>g54����&�� g��?��)O,�����AM83�#�L��Q�72>H�F۽D��&�_�حX��f9�žU\AR�Ed���D�֟ ��Yy�ɊVf�f�`ϣk����Т�f�7m�Fo�S9���dJ>�� �H����/��?����y���1�jk/%6v�mkn�:���8H�~ڕ2��Q\�kw�R>_�Р��?�drW�Z�e�Y��Ě+�O��$�H�Ձ`ţ�"9�"�k��}��]��>Z�m{�{n��r�+�L���O�FU� ���������_��>��y���������\P5Fa�Nj�=�/�_����X,g��!�e�?T�����I��h�Mܺ��l��<2C��Ƣ����d�����[E�?������P� �3�A�}�M�fK2_ ϓ=�5�P�?� | ||
��a�z:f-�~:x�$zXP���U���Ɔ���>4�&������t6TE})�Sg�(%&�a������RP�תj����R���t\ ]9��gT�B"z�b���[%��5M��\���ü�o��#Ǹ��v��N9��P��l�9��~&+�+ts��%�gR�6��Lwat��-����G`�2����<�� �0��c���WW�<b��5a�Ra�1�v��l��� | ||
�昂T/iD\\���U���!o=(F�֠��[vm�QR�����.�}|��1�X��Cy��5�s="�+�f��A��s | ||
N�C}�����w;�������>���� ^��&��L���ʉ�R�p�y3H@����5��ht(9zّ��-^��Ya�Kw�� �R����t�piK�7�ˡ��2�r(`���]�� | ||
�½1ح����?��� �I�@��e������@g��_%T��z��� �q ���))Z���/*ф��Љ�*�)����dH��k`+ [���q�B�x��=Ӧt ����O�M | ||
fi�L��{�nH�ӺCF��sn�9ҁ�P�0�(��pL�ھ>��.�ض3^_�ȿD5�~��wȖ! |
@@ -1,1 +0,1 @@ | ||
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.memoizerific=t()}}(function(){var t,e,i;return function t(e,i,s){function r(a,o){if(!i[a]){if(!e[a]){var l="function"==typeof require&&require;if(!o&&l)return l(a,!0);if(n)return n(a,!0);var f=new Error("Cannot find module '"+a+"'");throw f.code="MODULE_NOT_FOUND",f}var u=i[a]={exports:{}};e[a][0].call(u.exports,function(t){var i=e[a][1][t];return r(i?i:t)},u,u.exports,t,e,i,s)}return i[a].exports}for(var n="function"==typeof require&&require,a=0;a<s.length;a++)r(s[a]);return r}({1:[function(t,e,i){"function"!=typeof Map||process&&process.env&&"true"===process.env.TEST_MAPORSIMILAR?e.exports=t("./similar"):e.exports=Map},{"./similar":2}],2:[function(t,e,i){function s(){return this.list=[],this.lastItem=void 0,this.size=0,this}s.prototype.get=function(t){var e;return this.lastItem&&this.lastItem.key===t?this.lastItem.val:(e=this.indexOf(t),e>=0?(this.lastItem=this.list[e],this.list[e].val):void 0)},s.prototype.set=function(t,e){var i;return this.lastItem&&this.lastItem.key===t?(this.lastItem.val=e,this):(i=this.indexOf(t),i>=0?(this.lastItem=this.list[i],this.list[i].val=e,this):(this.lastItem={key:t,val:e},this.list.push(this.lastItem),this.size++,this))},s.prototype.delete=function(t){var e;return this.lastItem&&this.lastItem.key===t&&(this.lastItem=void 0),e=this.indexOf(t),e>=0?(this.size--,this.list.splice(e,1)[0]):void 0},s.prototype.has=function(t){var e;return this.lastItem&&this.lastItem.key===t?!0:(e=this.indexOf(t),e>=0?(this.lastItem=this.list[e],!0):!1)},s.prototype.forEach=function(t,e){var i;for(i=0;i<this.size;i++)t.call(e||this,this.list[i].val,this.list[i].key,this)},s.prototype.indexOf=function(t){var e;for(e=0;e<this.size;e++)if(this.list[e].key===t)return e;return-1},e.exports=s},{}],3:[function(t,e,i){function s(t,e){var i=t.length,s=e.length,r,n,a;for(n=0;i>n;n++){for(r=!0,a=0;s>a;a++)if(t[n][a].arg!==e[a].arg){r=!1;break}if(r)break}t.push(t.splice(n,1)[0])}function r(t){var e=t.length,i=t[e-1],s,r;for(i.cacheItem.delete(i.arg),r=e-2;r>=0&&(i=t[r],s=i.cacheItem.get(i.arg),!s||!s.size);r--)i.cacheItem.delete(i.arg)}var n=t("map-or-similar");e.exports=function(t){var e=new n,i=[];return function(a){var o=function(){var l=e,f,u,h=arguments.length-1,c=Array(h+1),m=!0,p;for(p=0;h>p;p++)c[p]={cacheItem:l,arg:arguments[p]},l.has(arguments[p])?l=l.get(arguments[p]):(m=!1,f=new n,l.set(arguments[p],f),l=f);return m&&(l.has(arguments[h])?u=l.get(arguments[h]):m=!1),m||(u=a.apply(null,arguments),l.set(arguments[h],u)),t>0&&(c[h]={cacheItem:l,arg:arguments[h]},m?s(i,c):i.push(c),i.length>t&&r(i.shift())),o.wasMemoized=m,u};return o.limit=t,o.wasMemoized=!1,o.cache=e,o.lru=i,o}}},{"map-or-similar":1}]},{},[3])(3)}); | ||
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.memoizerific=t()}}(function(){var t,e,i;return function t(e,i,s){function r(o,a){if(!i[o]){if(!e[o]){var l="function"==typeof require&&require;if(!a&&l)return l(o,!0);if(n)return n(o,!0);var h=new Error("Cannot find module '"+o+"'");throw h.code="MODULE_NOT_FOUND",h}var f=i[o]={exports:{}};e[o][0].call(f.exports,function(t){var i=e[o][1][t];return r(i?i:t)},f,f.exports,t,e,i,s)}return i[o].exports}for(var n="function"==typeof require&&require,o=0;o<s.length;o++)r(s[o]);return r}({1:[function(t,e,i){"function"!=typeof Map||process&&process.env&&"true"===process.env.TEST_MAPORSIMILAR?e.exports=t("./similar"):e.exports=Map},{"./similar":2}],2:[function(t,e,i){function s(){return this.list=[],this.lastItem=void 0,this.size=0,this}s.prototype.get=function(t){var e;return this.lastItem&&this.isEqual(this.lastItem.key,t)?this.lastItem.val:(e=this.indexOf(t),e>=0?(this.lastItem=this.list[e],this.list[e].val):void 0)},s.prototype.set=function(t,e){var i;return this.lastItem&&this.isEqual(this.lastItem.key,t)?(this.lastItem.val=e,this):(i=this.indexOf(t),i>=0?(this.lastItem=this.list[i],this.list[i].val=e,this):(this.lastItem={key:t,val:e},this.list.push(this.lastItem),this.size++,this))},s.prototype.delete=function(t){var e;return this.lastItem&&this.isEqual(this.lastItem.key,t)&&(this.lastItem=void 0),e=this.indexOf(t),e>=0?(this.size--,this.list.splice(e,1)[0]):void 0},s.prototype.has=function(t){var e;return this.lastItem&&this.isEqual(this.lastItem.key,t)?!0:(e=this.indexOf(t),e>=0?(this.lastItem=this.list[e],!0):!1)},s.prototype.forEach=function(t,e){var i;for(i=0;i<this.size;i++)t.call(e||this,this.list[i].val,this.list[i].key,this)},s.prototype.indexOf=function(t){var e;for(e=0;e<this.size;e++)if(this.isEqual(this.list[e].key,t))return e;return-1},s.prototype.isEqual=function(t,e){return t===e||t!==t&&e!==e},e.exports=s},{}],3:[function(t,e,i){function s(t,e){var i=t.length,s=e.length,r,o,a;for(o=0;i>o;o++){for(r=!0,a=0;s>a;a++)if(!n(t[o][a].arg,e[a].arg)){r=!1;break}if(r)break}t.push(t.splice(o,1)[0])}function r(t){var e=t.length,i=t[e-1],s,r;for(i.cacheItem.delete(i.arg),r=e-2;r>=0&&(i=t[r],s=i.cacheItem.get(i.arg),!s||!s.size);r--)i.cacheItem.delete(i.arg)}function n(t,e){return t===e||t!==t&&e!==e}var o=t("map-or-similar");e.exports=function(t){var e=new o,i=[];return function(n){var a=function(){var l=e,h,f,u=arguments.length-1,c=Array(u+1),p=!0,m;for(m=0;u>m;m++)c[m]={cacheItem:l,arg:arguments[m]},l.has(arguments[m])?l=l.get(arguments[m]):(p=!1,h=new o,l.set(arguments[m],h),l=h);return p&&(l.has(arguments[u])?f=l.get(arguments[u]):p=!1),p||(f=n.apply(null,arguments),l.set(arguments[u],f)),t>0&&(c[u]={cacheItem:l,arg:arguments[u]},p?s(i,c):i.push(c),i.length>t&&r(i.shift())),a.wasMemoized=p,f};return a.limit=t,a.wasMemoized=!1,a.cache=e,a.lru=i,a}}},{"map-or-similar":1}]},{},[3])(3)}); |
{ | ||
"name": "memoizerific", | ||
"version": "1.5.6", | ||
"version": "1.7.0", | ||
"description": "Fastest, smallest, most-efficient JavaScript memoization lib to memoize JS functions", | ||
@@ -25,3 +25,3 @@ "author": "@thinkloop", | ||
"build:gzip": "gzip --best -v -c", | ||
"dist": "npm run build && git add --all && git commit -m 'build & publish' && npm version patch && git push && git push --tags && npm publish" | ||
"prepublish": "npm run build && git add --all && git commit -m 'build & publish' && npm version minor && git push && git push --tags" | ||
}, | ||
@@ -40,12 +40,12 @@ "keywords": [ | ||
"dependencies": { | ||
"map-or-similar": "^1.1.3" | ||
"map-or-similar": "^1.2.1" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^13.0.0", | ||
"browserify": "^13.0.1", | ||
"derequire": "^2.0.3", | ||
"jasmine": "^2.4.1", | ||
"npm-check-updates": "^2.6.3", | ||
"npm-check-updates": "^2.6.5", | ||
"uglify-js": "^2.6.2", | ||
"watch": "^0.17.1" | ||
"watch": "^0.18.0" | ||
} | ||
} |
var MapOrSimilar = require('map-or-similar'); | ||
module.exports = function (limit) { | ||
var cache = new MapOrSimilar(), | ||
lru = []; | ||
var cache = new MapOrSimilar(), | ||
lru = []; | ||
return function (fn) { | ||
var memoizerific = function () { | ||
var currentCache = cache, | ||
newMap, | ||
fnResult, | ||
argsLengthMinusOne = arguments.length - 1, | ||
lruPath = Array(argsLengthMinusOne + 1), | ||
isMemoized = true, | ||
i; | ||
return function (fn) { | ||
var memoizerific = function () { | ||
var currentCache = cache, | ||
newMap, | ||
fnResult, | ||
argsLengthMinusOne = arguments.length - 1, | ||
lruPath = Array(argsLengthMinusOne + 1), | ||
isMemoized = true, | ||
i; | ||
// loop through each argument to traverse the map tree | ||
for (i = 0; i < argsLengthMinusOne; i++) { | ||
lruPath[i] = { | ||
cacheItem: currentCache, | ||
arg: arguments[i] | ||
}; | ||
// loop through each argument to traverse the map tree | ||
for (i = 0; i < argsLengthMinusOne; i++) { | ||
lruPath[i] = { | ||
cacheItem: currentCache, | ||
arg: arguments[i] | ||
}; | ||
// if all arguments exist in map tree, the memoized result will be last value to be retrieved | ||
if (currentCache.has(arguments[i])) { | ||
currentCache = currentCache.get(arguments[i]); | ||
continue; | ||
} | ||
// if all arguments exist in map tree, the memoized result will be last value to be retrieved | ||
if (currentCache.has(arguments[i])) { | ||
currentCache = currentCache.get(arguments[i]); | ||
continue; | ||
} | ||
isMemoized = false; | ||
isMemoized = false; | ||
// make maps until last value | ||
newMap = new MapOrSimilar(); | ||
currentCache.set(arguments[i], newMap); | ||
currentCache = newMap; | ||
} | ||
// make maps until last value | ||
newMap = new MapOrSimilar(); | ||
currentCache.set(arguments[i], newMap); | ||
currentCache = newMap; | ||
} | ||
// we are at the last arg, check if it is really memoized | ||
if (isMemoized) { | ||
if (currentCache.has(arguments[argsLengthMinusOne])) { | ||
fnResult = currentCache.get(arguments[argsLengthMinusOne]); | ||
} else { | ||
isMemoized = false; | ||
} | ||
} | ||
// we are at the last arg, check if it is really memoized | ||
if (isMemoized) { | ||
if (currentCache.has(arguments[argsLengthMinusOne])) { | ||
fnResult = currentCache.get(arguments[argsLengthMinusOne]); | ||
} | ||
else { | ||
isMemoized = false; | ||
} | ||
} | ||
if (!isMemoized) { | ||
fnResult = fn.apply(null, arguments); | ||
currentCache.set(arguments[argsLengthMinusOne], fnResult); | ||
} | ||
if (!isMemoized) { | ||
fnResult = fn.apply(null, arguments); | ||
currentCache.set(arguments[argsLengthMinusOne], fnResult); | ||
} | ||
if (limit > 0) { | ||
lruPath[argsLengthMinusOne] = { | ||
cacheItem: currentCache, | ||
arg: arguments[argsLengthMinusOne] | ||
}; | ||
if (limit > 0) { | ||
lruPath[argsLengthMinusOne] = { | ||
cacheItem: currentCache, | ||
arg: arguments[argsLengthMinusOne] | ||
}; | ||
if (isMemoized) { | ||
moveToMostRecentLru(lru, lruPath); | ||
} else { | ||
lru.push(lruPath); | ||
} | ||
if (isMemoized) { | ||
moveToMostRecentLru(lru, lruPath); | ||
} | ||
else { | ||
lru.push(lruPath); | ||
} | ||
if (lru.length > limit) { | ||
removeCachedResult(lru.shift()); | ||
} | ||
} | ||
if (lru.length > limit) { | ||
removeCachedResult(lru.shift()); | ||
} | ||
} | ||
memoizerific.wasMemoized = isMemoized; | ||
memoizerific.wasMemoized = isMemoized; | ||
return fnResult; | ||
}; | ||
return fnResult; | ||
}; | ||
memoizerific.limit = limit; | ||
memoizerific.wasMemoized = false; | ||
memoizerific.cache = cache; | ||
memoizerific.lru = lru; | ||
memoizerific.limit = limit; | ||
memoizerific.wasMemoized = false; | ||
memoizerific.cache = cache; | ||
memoizerific.lru = lru; | ||
return memoizerific; | ||
}; | ||
return memoizerific; | ||
}; | ||
}; | ||
@@ -85,21 +87,21 @@ | ||
function moveToMostRecentLru(lru, lruPath) { | ||
var lruLen = lru.length, | ||
lruPathLen = lruPath.length, | ||
isMatch, | ||
i, ii; | ||
var lruLen = lru.length, | ||
lruPathLen = lruPath.length, | ||
isMatch, | ||
i, ii; | ||
for (i = 0; i < lruLen; i++) { | ||
isMatch = true; | ||
for (ii = 0; ii < lruPathLen; ii++) { | ||
if (lru[i][ii].arg !== lruPath[ii].arg) { | ||
isMatch = false; | ||
break; | ||
} | ||
} | ||
if (isMatch) { | ||
break; | ||
} | ||
} | ||
for (i = 0; i < lruLen; i++) { | ||
isMatch = true; | ||
for (ii = 0; ii < lruPathLen; ii++) { | ||
if (!isEqual(lru[i][ii].arg, lruPath[ii].arg)) { | ||
isMatch = false; | ||
break; | ||
} | ||
} | ||
if (isMatch) { | ||
break; | ||
} | ||
} | ||
lru.push(lru.splice(i, 1)[0]); | ||
lru.push(lru.splice(i, 1)[0]); | ||
} | ||
@@ -109,20 +111,25 @@ | ||
function removeCachedResult(removedLru) { | ||
var removedLruLen = removedLru.length, | ||
currentLru = removedLru[removedLruLen - 1], | ||
tmp, | ||
i; | ||
var removedLruLen = removedLru.length, | ||
currentLru = removedLru[removedLruLen - 1], | ||
tmp, | ||
i; | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
// walk down the tree removing dead branches (size 0) along the way | ||
for (i = removedLruLen - 2; i >= 0; i--) { | ||
currentLru = removedLru[i]; | ||
tmp = currentLru.cacheItem.get(currentLru.arg); | ||
// walk down the tree removing dead branches (size 0) along the way | ||
for (i = removedLruLen - 2; i >= 0; i--) { | ||
currentLru = removedLru[i]; | ||
tmp = currentLru.cacheItem.get(currentLru.arg); | ||
if (!tmp || !tmp.size) { | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
} else { | ||
break; | ||
} | ||
} | ||
if (!tmp || !tmp.size) { | ||
currentLru.cacheItem.delete(currentLru.arg); | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
// check if the numbers are equal, or whether they are both precisely NaN (isNaN returns true for all non-numbers) | ||
function isEqual(val1, val2) { | ||
return val1 === val2 || (val1 !== val1 && val2 !== val2); | ||
} |
var Memoizerific = require('../src/memoizerific'); | ||
describe("complex args", () => { | ||
var memoizedFn, | ||
arg1 = { a: { b: 3 }, num: 3 }, | ||
arg2 = { c: { d: 3 }, num: 7 }, | ||
arg3 = [{ f: { g: 3 }, num: 11 }, { h: { i: 3 }, num: 4 }, { j: { k: 3 }, num: 6 }]; | ||
var memoizedFn, | ||
arg1 = { a: { b: 3 }, num: 3 }, | ||
arg2 = { c: { d: 3 }, num: 7 }, | ||
arg3 = [{ f: { g: 3 }, num: 11 }, { h: { i: 3 }, num: 4 }, { j: { k: 3 }, num: 6 }]; | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(50)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
memoizedFn(arg1, arg2, arg3); | ||
}); | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(50)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
memoizedFn(arg1, arg2, arg3); | ||
}); | ||
it("should be map or similar", () => { expect(memoizedFn.cache instanceof Map).toEqual(process.env.TEST_MAPORSIMILAR !== 'true'); }); | ||
it("should be map or similar", () => { expect(memoizedFn.cache instanceof Map).toEqual(process.env.TEST_MAPORSIMILAR !== 'true'); }); | ||
it("should not be memoized", () => { | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
expect(memoizedFn.lru.length).toEqual(1); | ||
}); | ||
it("should not be memoized", () => { | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
expect(memoizedFn.lru.length).toEqual(1); | ||
}); | ||
it("should be memoized", () => { | ||
memoizedFn(arg1, arg2, arg3); | ||
expect(memoizedFn.wasMemoized).toEqual(true); | ||
expect(memoizedFn.lru.length).toEqual(1); | ||
}); | ||
it("should be memoized", () => { | ||
memoizedFn(arg1, arg2, arg3); | ||
expect(memoizedFn.wasMemoized).toEqual(true); | ||
expect(memoizedFn.lru.length).toEqual(1); | ||
}); | ||
it("should have multiple cached items", () => { | ||
memoizedFn(arg1, arg2, arg3); | ||
memoizedFn(arg1, arg2, 1); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
expect(memoizedFn.lru.length).toEqual(2); | ||
}); | ||
it("should have multiple cached items", () => { | ||
memoizedFn(arg1, arg2, arg3); | ||
memoizedFn(arg1, arg2, 1); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
expect(memoizedFn.lru.length).toEqual(2); | ||
}); | ||
}); |
var Memoizerific = require('../src/memoizerific'); | ||
describe("fibonacci", () => { | ||
var fibonacci, | ||
fibonacciMemoized, | ||
fibonacciResult, | ||
fibonacciMemoizedResult, | ||
fibonacciTime, | ||
fibonacciMemoizedTime, | ||
ratioDifference; | ||
var fibonacci, | ||
fibonacciMemoized, | ||
fibonacciResult, | ||
fibonacciMemoizedResult, | ||
fibonacciTime, | ||
fibonacciMemoizedTime, | ||
ratioDifference; | ||
fibonacci = function (n) { | ||
if (n < 2){ | ||
return 1; | ||
} | ||
else { | ||
return fibonacci(n-2) + fibonacci(n-1); | ||
} | ||
}; | ||
fibonacci = function (n) { | ||
if (n < 2){ | ||
return 1; | ||
} | ||
else { | ||
return fibonacci(n-2) + fibonacci(n-1); | ||
} | ||
}; | ||
fibonacciMemoized = Memoizerific(50)(function (n) { | ||
if (n < 2){ | ||
return 1; | ||
} | ||
else { | ||
return fibonacciMemoized(n-2) + fibonacciMemoized(n-1); | ||
} | ||
}); | ||
fibonacciMemoized = Memoizerific(50)(function (n) { | ||
if (n < 2){ | ||
return 1; | ||
} | ||
else { | ||
return fibonacciMemoized(n-2) + fibonacciMemoized(n-1); | ||
} | ||
}); | ||
fibonacciTime = process.hrtime(); | ||
fibonacciResult = fibonacci(40); | ||
fibonacciTime = process.hrtime(fibonacciTime); | ||
fibonacciTime = process.hrtime(); | ||
fibonacciResult = fibonacci(40); | ||
fibonacciTime = process.hrtime(fibonacciTime); | ||
fibonacciMemoizedTime = process.hrtime(); | ||
fibonacciMemoizedResult = fibonacciMemoized(40); | ||
fibonacciMemoizedTime = process.hrtime(fibonacciMemoizedTime); | ||
fibonacciMemoizedTime = process.hrtime(); | ||
fibonacciMemoizedResult = fibonacciMemoized(40); | ||
fibonacciMemoizedTime = process.hrtime(fibonacciMemoizedTime); | ||
ratioDifference = ((fibonacciTime[0] * 1000000000) + fibonacciTime[1]) / ((fibonacciMemoizedTime[0] * 1000000000) + fibonacciMemoizedTime[1]); | ||
ratioDifference = ((fibonacciTime[0] * 1000000000) + fibonacciTime[1]) / ((fibonacciMemoizedTime[0] * 1000000000) + fibonacciMemoizedTime[1]); | ||
it("should be map or similar", () => { expect(fibonacciMemoized.cache instanceof Map).toEqual(process.env.TEST_MAPORSIMILAR !== 'true'); }); | ||
it("should equal non-memoized result", () => { expect(fibonacciResult).toEqual(fibonacciMemoizedResult); }); | ||
it("should have proper lru length", () => { expect(fibonacciMemoized.lru.length).toEqual(41); }); | ||
it("should be at least 10x faster", () => { expect(ratioDifference).toBeGreaterThan(10); }); | ||
it("should be map or similar", () => { expect(fibonacciMemoized.cache instanceof Map).toEqual(process.env.TEST_MAPORSIMILAR !== 'true'); }); | ||
it("should equal non-memoized result", () => { expect(fibonacciResult).toEqual(fibonacciMemoizedResult); }); | ||
it("should have proper lru length", () => { expect(fibonacciMemoized.lru.length).toEqual(41); }); | ||
it("should be at least 10x faster", () => { expect(ratioDifference).toBeGreaterThan(10); }); | ||
}); |
var Memoizerific = require('../src/memoizerific'); | ||
describe("wasMemoized", () => { | ||
var memoizedFn; | ||
var memoizedFn; | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(50)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
}); | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(50)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
}); | ||
it("should be false before any invocations", () => { | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
it("should be false before any invocations", () => { | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
it("should be false after one invocation", () => { | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
it("should be false after one invocation", () => { | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
it("should be true", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.wasMemoized).toEqual(true); | ||
}); | ||
it("should be true", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.wasMemoized).toEqual(true); | ||
}); | ||
it("should be false", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(4, 5, 6); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
it("should be false", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(4, 5, 6); | ||
expect(memoizedFn.wasMemoized).toEqual(false); | ||
}); | ||
}); | ||
describe("limit", () => { | ||
var memoizedFn; | ||
var memoizedFn; | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(43)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
}); | ||
beforeEach(function() { | ||
memoizedFn = Memoizerific(43)(function(arg1, arg2, arg3) { | ||
return arg1.num * arg2.num; | ||
}); | ||
}); | ||
it("should be correct after no invocations", () => { | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
it("should be correct after no invocations", () => { | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
it("should be correct after one invocation", () => { | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
it("should be correct after one invocation", () => { | ||
memoizedFn(1, 2, 3); | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
it("should be correct after multiple invocations", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(4, 5, 6); | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
it("should be correct after multiple invocations", () => { | ||
memoizedFn(1, 2, 3); | ||
memoizedFn(4, 5, 6); | ||
expect(memoizedFn.limit).toEqual(43); | ||
}); | ||
}); |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
14
7.69%479
10.62%32505
-1.69%11
10%1
Infinity%Updated