shamap.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. "use strict";
  2. var __extends = (this && this.__extends) || (function () {
  3. var extendStatics = function (d, b) {
  4. extendStatics = Object.setPrototypeOf ||
  5. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  6. function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  7. return extendStatics(d, b);
  8. };
  9. return function (d, b) {
  10. if (typeof b !== "function" && b !== null)
  11. throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  12. extendStatics(d, b);
  13. function __() { this.constructor = d; }
  14. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  15. };
  16. })();
  17. Object.defineProperty(exports, "__esModule", { value: true });
  18. exports.ShaMapLeaf = exports.ShaMapNode = exports.ShaMap = void 0;
  19. var assert_1 = require("assert");
  20. var types_1 = require("./types");
  21. var hash_prefixes_1 = require("./hash-prefixes");
  22. var hashes_1 = require("./hashes");
  23. var buffer_1 = require("buffer/");
  24. /**
  25. * Abstract class describing a SHAMapNode
  26. */
  27. var ShaMapNode = /** @class */ (function () {
  28. function ShaMapNode() {
  29. }
  30. return ShaMapNode;
  31. }());
  32. exports.ShaMapNode = ShaMapNode;
  33. /**
  34. * Class describing a Leaf of SHAMap
  35. */
  36. var ShaMapLeaf = /** @class */ (function (_super) {
  37. __extends(ShaMapLeaf, _super);
  38. function ShaMapLeaf(index, item) {
  39. var _this = _super.call(this) || this;
  40. _this.index = index;
  41. _this.item = item;
  42. return _this;
  43. }
  44. /**
  45. * @returns true as ShaMapLeaf is a leaf node
  46. */
  47. ShaMapLeaf.prototype.isLeaf = function () {
  48. return true;
  49. };
  50. /**
  51. * @returns false as ShaMapLeaf is not an inner node
  52. */
  53. ShaMapLeaf.prototype.isInner = function () {
  54. return false;
  55. };
  56. /**
  57. * Get the prefix of the this.item
  58. *
  59. * @returns The hash prefix, unless this.item is undefined, then it returns an empty Buffer
  60. */
  61. ShaMapLeaf.prototype.hashPrefix = function () {
  62. return this.item === undefined ? buffer_1.Buffer.alloc(0) : this.item.hashPrefix();
  63. };
  64. /**
  65. * Hash the bytes representation of this
  66. *
  67. * @returns hash of this.item concatenated with this.index
  68. */
  69. ShaMapLeaf.prototype.hash = function () {
  70. var hash = hashes_1.Sha512Half.put(this.hashPrefix());
  71. this.toBytesSink(hash);
  72. return hash.finish();
  73. };
  74. /**
  75. * Write the bytes representation of this to a BytesList
  76. * @param list BytesList to write bytes to
  77. */
  78. ShaMapLeaf.prototype.toBytesSink = function (list) {
  79. if (this.item !== undefined) {
  80. this.item.toBytesSink(list);
  81. }
  82. this.index.toBytesSink(list);
  83. };
  84. return ShaMapLeaf;
  85. }(ShaMapNode));
  86. exports.ShaMapLeaf = ShaMapLeaf;
  87. /**
  88. * Class defining an Inner Node of a SHAMap
  89. */
  90. var ShaMapInner = /** @class */ (function (_super) {
  91. __extends(ShaMapInner, _super);
  92. function ShaMapInner(depth) {
  93. if (depth === void 0) { depth = 0; }
  94. var _this = _super.call(this) || this;
  95. _this.depth = depth;
  96. _this.slotBits = 0;
  97. _this.branches = Array(16);
  98. return _this;
  99. }
  100. /**
  101. * @returns true as ShaMapInner is an inner node
  102. */
  103. ShaMapInner.prototype.isInner = function () {
  104. return true;
  105. };
  106. /**
  107. * @returns false as ShaMapInner is not a leaf node
  108. */
  109. ShaMapInner.prototype.isLeaf = function () {
  110. return false;
  111. };
  112. /**
  113. * Get the hash prefix for this node
  114. *
  115. * @returns hash prefix describing an inner node
  116. */
  117. ShaMapInner.prototype.hashPrefix = function () {
  118. return hash_prefixes_1.HashPrefix.innerNode;
  119. };
  120. /**
  121. * Set a branch of this node to be another node
  122. *
  123. * @param slot Slot to add branch to this.branches
  124. * @param branch Branch to add
  125. */
  126. ShaMapInner.prototype.setBranch = function (slot, branch) {
  127. this.slotBits = this.slotBits | (1 << slot);
  128. this.branches[slot] = branch;
  129. };
  130. /**
  131. * @returns true if node is empty
  132. */
  133. ShaMapInner.prototype.empty = function () {
  134. return this.slotBits === 0;
  135. };
  136. /**
  137. * Compute the hash of this node
  138. *
  139. * @returns The hash of this node
  140. */
  141. ShaMapInner.prototype.hash = function () {
  142. if (this.empty()) {
  143. return types_1.coreTypes.Hash256.ZERO_256;
  144. }
  145. var hash = hashes_1.Sha512Half.put(this.hashPrefix());
  146. this.toBytesSink(hash);
  147. return hash.finish();
  148. };
  149. /**
  150. * Writes the bytes representation of this node to a BytesList
  151. *
  152. * @param list BytesList to write bytes to
  153. */
  154. ShaMapInner.prototype.toBytesSink = function (list) {
  155. for (var i = 0; i < this.branches.length; i++) {
  156. var branch = this.branches[i];
  157. var hash = branch ? branch.hash() : types_1.coreTypes.Hash256.ZERO_256;
  158. hash.toBytesSink(list);
  159. }
  160. };
  161. /**
  162. * Add item to the SHAMap
  163. *
  164. * @param index Hash of the index of the item being inserted
  165. * @param item Item to insert in the map
  166. * @param leaf Leaf node to insert when branch doesn't exist
  167. */
  168. ShaMapInner.prototype.addItem = function (index, item, leaf) {
  169. assert_1.strict.ok(index !== undefined);
  170. var nibble = index.nibblet(this.depth);
  171. var existing = this.branches[nibble];
  172. if (existing === undefined) {
  173. this.setBranch(nibble, leaf || new ShaMapLeaf(index, item));
  174. }
  175. else if (existing instanceof ShaMapLeaf) {
  176. var newInner = new ShaMapInner(this.depth + 1);
  177. newInner.addItem(existing.index, undefined, existing);
  178. newInner.addItem(index, item, leaf);
  179. this.setBranch(nibble, newInner);
  180. }
  181. else if (existing instanceof ShaMapInner) {
  182. existing.addItem(index, item, leaf);
  183. }
  184. else {
  185. throw new Error('invalid ShaMap.addItem call');
  186. }
  187. };
  188. return ShaMapInner;
  189. }(ShaMapNode));
  190. var ShaMap = /** @class */ (function (_super) {
  191. __extends(ShaMap, _super);
  192. function ShaMap() {
  193. return _super !== null && _super.apply(this, arguments) || this;
  194. }
  195. return ShaMap;
  196. }(ShaMapInner));
  197. exports.ShaMap = ShaMap;
  198. //# sourceMappingURL=shamap.js.map