1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.ShaMapLeaf = exports.ShaMapNode = exports.ShaMap = void 0;
|
4 | const assert_1 = require("assert");
|
5 | const types_1 = require("./types");
|
6 | const hash_prefixes_1 = require("./hash-prefixes");
|
7 | const hashes_1 = require("./hashes");
|
8 | const buffer_1 = require("buffer/");
|
9 |
|
10 |
|
11 |
|
12 | class ShaMapNode {
|
13 | }
|
14 | exports.ShaMapNode = ShaMapNode;
|
15 |
|
16 |
|
17 |
|
18 | class ShaMapLeaf extends ShaMapNode {
|
19 | constructor(index, item) {
|
20 | super();
|
21 | this.index = index;
|
22 | this.item = item;
|
23 | }
|
24 | |
25 |
|
26 |
|
27 | isLeaf() {
|
28 | return true;
|
29 | }
|
30 | |
31 |
|
32 |
|
33 | isInner() {
|
34 | return false;
|
35 | }
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 | hashPrefix() {
|
42 | return this.item === undefined ? buffer_1.Buffer.alloc(0) : this.item.hashPrefix();
|
43 | }
|
44 | |
45 |
|
46 |
|
47 |
|
48 |
|
49 | hash() {
|
50 | const hash = hashes_1.Sha512Half.put(this.hashPrefix());
|
51 | this.toBytesSink(hash);
|
52 | return hash.finish();
|
53 | }
|
54 | |
55 |
|
56 |
|
57 |
|
58 | toBytesSink(list) {
|
59 | if (this.item !== undefined) {
|
60 | this.item.toBytesSink(list);
|
61 | }
|
62 | this.index.toBytesSink(list);
|
63 | }
|
64 | }
|
65 | exports.ShaMapLeaf = ShaMapLeaf;
|
66 |
|
67 |
|
68 |
|
69 | class 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 |
|
78 |
|
79 | isInner() {
|
80 | return true;
|
81 | }
|
82 | |
83 |
|
84 |
|
85 | isLeaf() {
|
86 | return false;
|
87 | }
|
88 | |
89 |
|
90 |
|
91 |
|
92 |
|
93 | hashPrefix() {
|
94 | return hash_prefixes_1.HashPrefix.innerNode;
|
95 | }
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | setBranch(slot, branch) {
|
103 | this.slotBits = this.slotBits | (1 << slot);
|
104 | this.branches[slot] = branch;
|
105 | }
|
106 | |
107 |
|
108 |
|
109 | empty() {
|
110 | return this.slotBits === 0;
|
111 | }
|
112 | |
113 |
|
114 |
|
115 |
|
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 |
|
127 |
|
128 |
|
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 |
|
141 |
|
142 |
|
143 |
|
144 |
|
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 | }
|
169 | class ShaMap extends ShaMapInner {
|
170 | }
|
171 | exports.ShaMap = ShaMap;
|
172 |
|
\ | No newline at end of file |