UNPKG

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