/js/lib/SortedLookupTable.js

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs · JavaScript · 200 lines · 78 code · 20 blank · 102 comment · 11 complexity · 97ff6611236f07be71506aca33db70ee MD5 · raw file

  1. /**
  2. File:
  3. SortedLookupTable.js
  4. Created By:
  5. (Class from http://blog.jcoglan.com/2010/10/18/i-am-a-fast-loop/)
  6. Copy->Pasted->Modified by Mario Gonzalez
  7. Project :
  8. Ogilvy Holiday Card 2010
  9. Abstract:
  10. A sorted LookupTable is a data structure that provides us a way to iterate thru objects at a speed
  11. comparable to reverse while, but also have named keys as we would if we used an object (which provides very slow iteration)
  12. It also gives us O(log n) removal of objects.
  13. Basic Usage:
  14. http://blog.jcoglan.com/2010/10/18/i-am-a-fast-loop/
  15. */
  16. // @getify's solution
  17. //var Set = (function()
  18. //{
  19. // var indexOf = Array.prototype.indexOf;
  20. //
  21. // if (typeof indexOf !== 'function')
  22. // {
  23. // indexOf = function(value)
  24. // {
  25. // for (var index = 0, length = this.length; index < length; index++)
  26. // {
  27. // if (this[index] === value)
  28. // {
  29. // return index;
  30. // }
  31. // }
  32. // return -1;
  33. // };
  34. // }
  35. //
  36. // function Set()
  37. // {
  38. // this.set = [];
  39. // }
  40. //
  41. // Set.prototype = {
  42. // 'constructor': Set,
  43. // 'put': function(value, key)
  44. // {
  45. // var index = indexOf.call(this.set, key);
  46. // if (index !== -1 && index % 2 === 0)
  47. // {
  48. // this.set.splice(index, 2);
  49. // }
  50. // this.set.push(key, value);
  51. // },
  52. // 'get': function(key)
  53. // {
  54. // var index = indexOf.call(this.set, key);
  55. // return (index !== -1 && index % 2 === 0) ? this.set[++index] : null;
  56. // },
  57. // 'containsKey': function(key)
  58. // {
  59. // var index = indexOf.call(this.set, key);
  60. // return (index !== -1 && index % 2 === 0);
  61. // },
  62. // 'containsValue': function(value)
  63. // {
  64. // var index = indexOf.call(this.set, value);
  65. // return (index !== -1 && index % 2 !== 0);
  66. // },
  67. // 'remove': function(key)
  68. // {
  69. // var index = indexOf.call(this.set, key),
  70. // value = null;
  71. // if (index !== -1 && index % 2 === 0)
  72. // {
  73. // value = this.set.splice(index, 2)[1];
  74. // }
  75. // return value;
  76. // },
  77. //
  78. // 'forEach': function(block, context)
  79. // {
  80. // var set = this.set,
  81. // i = this.set.length-1,
  82. // key;
  83. //
  84. // while (i > 0)
  85. // {
  86. // block.call(context, set[i - 1], set[key]);
  87. // i-=2;
  88. // }
  89. // }
  90. // };
  91. //
  92. // return Set;
  93. //}());
  94. (function() {
  95. /**
  96. * LookupTable
  97. */
  98. LookupTable = function()
  99. {
  100. this._keys = [];
  101. this._data = {};
  102. this.nextUUID = 0;
  103. };
  104. LookupTable.prototype.setObjectForKey = function(value, key)
  105. {
  106. if (!this._data.hasOwnProperty(key)) this._keys.push(key);
  107. this._data[key] = value;
  108. return value;
  109. };
  110. LookupTable.prototype.objectForKey = function(key)
  111. {
  112. return this._data[key];
  113. };
  114. LookupTable.prototype.forEach = function(block, context)
  115. {
  116. var keys = this._keys,
  117. data = this._data,
  118. i = keys.length,
  119. key;
  120. while (i--)
  121. {
  122. key = keys[i];
  123. block.call(context, key, data[key]);
  124. }
  125. };
  126. LookupTable.prototype.count = function()
  127. {
  128. return this._keys.length;
  129. };
  130. LookupTable.prototype.dealloc = function()
  131. {
  132. delete this._keys;
  133. delete this._data;
  134. };
  135. /**
  136. * Sorted LookupTable,
  137. */
  138. SortedLookupTable = function()
  139. {
  140. LookupTable.call(this);
  141. };
  142. SortedLookupTable.prototype = new LookupTable();
  143. SortedLookupTable.prototype.setObjectForKey = function(value, key)
  144. {
  145. if( !this._data.hasOwnProperty( key ) )
  146. {
  147. var index = this._indexOf(key);
  148. this._keys.splice(index, 0, key);
  149. }
  150. this._data[key] = value;
  151. return value;
  152. };
  153. SortedLookupTable.prototype.remove = function(key)
  154. {
  155. if (!this._data.hasOwnProperty(key)) return;
  156. delete this._data[key];
  157. var index = this._indexOf(key);
  158. this._keys.splice(index, 1);
  159. };
  160. SortedLookupTable.prototype._indexOf = function(key)
  161. {
  162. var keys = this._keys,
  163. n = keys.length,
  164. i = 0,
  165. d = n;
  166. if (n === 0) return 0;
  167. if (key < keys[0]) return 0;
  168. if (key > keys[n - 1]) return n;
  169. while (key !== keys[i] && d > 0.5) {
  170. d = d / 2;
  171. i += (key > keys[i] ? 1: -1) * Math.round(d);
  172. if (key > keys[i - 1] && key < keys[i]) d = 0;
  173. }
  174. return i;
  175. };
  176. return SortedLookupTable;
  177. })();