HashTable.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. var failed = false;
  6. var verifyMemoryUsage = false;
  7. var maxHashTableSizeShift = 5;
  8. var maxHashTableSize = 1 << maxHashTableSizeShift;
  9. function createHashTable() {
  10. var o = new Array(); // array so that we can transition its type handler to an ES5 array type handler
  11. var elements = new Array(maxHashTableSize);
  12. o.elementHash = function (i) {
  13. return Math.abs(i) & (maxHashTableSize - 1);
  14. };
  15. o.add = function (i) {
  16. var elementIndex = this.elementHash(i);
  17. if(elements[elementIndex] !== undefined) {
  18. // Delete up to 4 used elements to make room
  19. for(var j = elementIndex; j < elementIndex + 4 && j < maxHashTableSize; ++j) {
  20. var e = elements[j];
  21. if(e === undefined)
  22. continue;
  23. var h = "h" + e;
  24. assertAreEqual(e, this[h]);
  25. elements[j] = undefined;
  26. delete this[h];
  27. }
  28. }
  29. elements[elementIndex] = i;
  30. this["h" + i] = i;
  31. };
  32. o.verify = function () {
  33. for(var i = 0; i < maxHashTableSize; ++i) {
  34. var e = elements[i];
  35. if(e !== undefined)
  36. assertAreEqual(e, this["h" + e]);
  37. }
  38. for(var h in this) {
  39. if(h[0] !== "h")
  40. continue;
  41. assertAreEqual(h, "h" + elements[this.elementHash(this[h])]);
  42. }
  43. };
  44. return o;
  45. }
  46. function useAsHashTable(o, n) {
  47. for(var i = 0; n === 0 || i !== n; i = (i + 1) | 0) {
  48. for(var j = i; j !== (i + 4) | 0; j = (j + 1) | 0)
  49. o.add(j);
  50. if(!(i & 0xffff) && verifyMemoryUsage)
  51. WScript.Echo(i);
  52. }
  53. o.verify();
  54. }
  55. var o = createHashTable();
  56. useAsHashTable(o, verifyMemoryUsage ? 0 : 1024);
  57. // Transition to a DictionaryTypeHandler
  58. Object.defineProperty(
  59. o,
  60. "foo",
  61. { configurable: true, enumerable: true, get: function () { }, set: function (v) { } });
  62. useAsHashTable(o, 1024);
  63. // Transition to an ES5ArrayTypeHandler
  64. Object.defineProperty(
  65. o,
  66. "0",
  67. { configurable: true, writable: false, enumerable: true });
  68. useAsHashTable(o, 1024);
  69. if(!failed)
  70. WScript.Echo("pass");
  71. function assertAreEqual(expected, actual) {
  72. if(expected === actual)
  73. return;
  74. failed = true;
  75. WScript.Echo("Expected: " + expected + ", Actual: " + actual);
  76. }