UNPKG

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