radix.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. ;(function(){
  2. function Radix(){
  3. var radix = function(key, val, t){
  4. radix.unit = 0;
  5. if(!t && u !== val){
  6. radix.last = (''+key < radix.last)? radix.last : ''+key;
  7. delete (radix.$||{})[_];
  8. }
  9. t = t || radix.$ || (radix.$ = {});
  10. if(!key && Object.keys(t).length){ return t }
  11. key = ''+key;
  12. var i = 0, l = key.length-1, k = key[i], at, tmp;
  13. while(!(at = t[k]) && i < l){
  14. k += key[++i];
  15. }
  16. if(!at){
  17. if(!map(t, function(r, s){
  18. var ii = 0, kk = '';
  19. if((s||'').length){ while(s[ii] == key[ii]){
  20. kk += s[ii++];
  21. } }
  22. if(kk){
  23. if(u === val){
  24. if(ii <= l){ return }
  25. (tmp || (tmp = {}))[s.slice(ii)] = r;
  26. //(tmp[_] = function $(){ $.sort = Object.keys(tmp).sort(); return $ }()); // get rid of this one, cause it is on read?
  27. return r;
  28. }
  29. var __ = {};
  30. __[s.slice(ii)] = r;
  31. ii = key.slice(ii);
  32. ('' === ii)? (__[''] = val) : ((__[ii] = {})[''] = val);
  33. //(__[_] = function $(){ $.sort = Object.keys(__).sort(); return $ }());
  34. t[kk] = __;
  35. delete t[s];
  36. //(t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }());
  37. return true;
  38. }
  39. })){
  40. if(u === val){ return; }
  41. (t[k] || (t[k] = {}))[''] = val;
  42. //(t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }());
  43. }
  44. if(u === val){
  45. return tmp;
  46. }
  47. } else
  48. if(i == l){
  49. //if(u === val){ return (u === (tmp = at['']))? at : tmp } // THIS CODE IS CORRECT, below is
  50. if(u === val){ return (u === (tmp = at['']))? at : ((radix.unit = 1) && tmp) } // temporary help??
  51. at[''] = val;
  52. //(at[_] = function $(){ $.sort = Object.keys(at).sort(); return $ }());
  53. } else {
  54. if(u !== val){ delete at[_] }
  55. //at && (at[_] = function $(){ $.sort = Object.keys(at).sort(); return $ }());
  56. return radix(key.slice(++i), val, at || (at = {}));
  57. }
  58. }
  59. return radix;
  60. };
  61. Radix.map = function rap(radix, cb, opt, pre){ pre = pre || []; // TODO: BUG: most out-of-memory crashes come from here.
  62. var t = ('function' == typeof radix)? radix.$ || {} : radix;
  63. //!opt && console.log("WHAT IS T?", JSON.stringify(t).length);
  64. if(!t){ return }
  65. var keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort, rev; // ONLY 17% of ops are pre-sorted!
  66. //var keys = Object.keys(t).sort();
  67. opt = (true === opt)? {branch: true} : (opt || {});
  68. if(rev = opt.reverse){ keys = keys.slice(0).reverse() }
  69. var start = opt.start, end = opt.end, END = '\uffff';
  70. var i = 0, l = keys.length;
  71. for(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt;
  72. if(!tree || '' === key || _ === key){ continue }
  73. p = pre.slice(0); p.push(key);
  74. pt = p.join('');
  75. if(u !== start && pt < (start||'').slice(0,pt.length)){ continue }
  76. if(u !== end && (end || END) < pt){ continue }
  77. if(rev){ // children must be checked first when going in reverse.
  78. tmp = rap(tree, cb, opt, p);
  79. if(u !== tmp){ return tmp }
  80. }
  81. if(u !== (tmp = tree[''])){
  82. var yes = 1;
  83. if(u !== start && pt < (start||'')){ yes = 0 }
  84. if(u !== end && pt > (end || END)){ yes = 0 }
  85. if(yes){
  86. tmp = cb(tmp, pt, key, pre);
  87. if(u !== tmp){ return tmp }
  88. }
  89. } else
  90. if(opt.branch){
  91. tmp = cb(u, pt, key, pre);
  92. if(u !== tmp){ return tmp }
  93. }
  94. pre = p;
  95. if(!rev){
  96. tmp = rap(tree, cb, opt, pre);
  97. if(u !== tmp){ return tmp }
  98. }
  99. pre.pop();
  100. }
  101. };
  102. Object.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }
  103. if(typeof window !== "undefined"){
  104. var Gun = window.Gun;
  105. window.Radix = Radix;
  106. } else {
  107. var Gun = require('../gun');
  108. try{ module.exports = Radix }catch(e){}
  109. }
  110. var map = Gun.obj.map, no = {}, u;
  111. var _ = String.fromCharCode(24);
  112. }());