@@ -80,14 +80,23 @@ internal fun Input.readBagOfCell(): BagOfCells {
80
80
val cellDescriptors = Array (cellCount) { CellDescriptor (0 , 0 ) }
81
81
82
82
// measureTime {
83
+ val cellHashes = Array <List <Pair <ByteArray , Int >>? > (cellCount) { null }
84
+
83
85
repeat(cellCount) { cellIndex ->
84
86
val d1 = readByte()
85
87
val d2 = readByte()
86
88
val descriptor = CellDescriptor (d1, d2)
87
89
88
90
if (descriptor.hasHashes) {
89
- discardExact(descriptor.hashCount * Cell .HASH_BYTES )
90
- discardExact(descriptor.hashCount * Cell .DEPTH_BYTES )
91
+ val hashes = ArrayList <ByteArray >(descriptor.hashCount)
92
+ val depths = ArrayList <Int >(descriptor.hashCount)
93
+ repeat(descriptor.hashCount) {
94
+ hashes.add(readBytes(Cell .HASH_BYTES ))
95
+ }
96
+ repeat(descriptor.hashCount) {
97
+ depths.add(readInt(2 ))
98
+ }
99
+ cellHashes[cellIndex] = hashes.zip(depths)
91
100
}
92
101
93
102
val cellData = readBytes(descriptor.dataLength)
@@ -106,11 +115,11 @@ internal fun Input.readBagOfCell(): BagOfCells {
106
115
// }
107
116
108
117
// Resolving references & constructing cells from leaves to roots
109
- val cells = Array <CompletableDeferred <Cell >>(cellCount) { CompletableDeferred () }
118
+ val asyncCells = Array <CompletableDeferred <Cell >>(cellCount) { CompletableDeferred () }
110
119
GlobalScope .launch {
111
120
repeat(cellCount) { cellIndex ->
112
121
launch {
113
- createCell(cellIndex, cells , cellBits, cellRefs, cellDescriptors)
122
+ createCell(cellIndex, asyncCells , cellBits, cellRefs, cellDescriptors, cellHashes )
114
123
}
115
124
}
116
125
}
@@ -120,30 +129,71 @@ internal fun Input.readBagOfCell(): BagOfCells {
120
129
readIntLittleEndian()
121
130
}
122
131
132
+ val cells = runBlocking {
133
+ asyncCells.toList().awaitAll()
134
+ }
135
+
123
136
val roots = rootIndexes.map { rootIndex ->
124
- runBlocking {
125
- cells[rootIndex].await()
126
- }
137
+ cells[rootIndex]
127
138
}
128
139
129
- return BagOfCells (roots)
140
+ return object : BagOfCells {
141
+ override val roots: List <Cell > = roots
142
+
143
+ override fun toString (): String = buildString {
144
+ roots.forEachIndexed { _, cell ->
145
+ Cell .toString(cell, this )
146
+ }
147
+ }
148
+
149
+ override fun iterator (): Iterator <Cell > = cells.iterator()
150
+ }
130
151
}
131
152
132
153
private suspend fun createCell (
133
154
index : Int ,
134
155
cells : Array <CompletableDeferred <Cell >>,
135
156
bits : Array <BitString >,
136
157
refs : Array <IntArray >,
137
- descriptors : Array <CellDescriptor >
158
+ descriptors : Array <CellDescriptor >,
159
+ cellHashes : Array <List <Pair <ByteArray , Int >>? >
138
160
) = coroutineScope {
139
161
val cellBits = bits[index]
140
162
val cellRefIndexes = refs[index]
141
163
val cellRefs = cellRefIndexes.map { refIndex ->
142
164
cells[refIndex].await()
143
165
}
166
+ val descriptor = descriptors[index]
167
+ val hashes = cellHashes[index]
168
+ // val cell = if (!descriptors[index].isExotic && hashes != null) {
169
+ // val new = buildCell {
170
+ // isExotic = descriptor.isExotic
171
+ // levelMask = descriptor.levelMask
172
+ // storeBits(cellBits)
173
+ // storeRefs(cellRefs)
174
+ // }
175
+ // fun List<Pair<ByteArray, Int>>.print() = map {
176
+ // it.first.toHexString()+"="+it.second
177
+ // }
178
+ // DataCell(descriptor, cellBits, cellRefs, hashes).also {
179
+ // if (new is DataCell && new.hashes != it.hashes) {
180
+ // // println("\nnew:${new.hashes.print()}\nit:${it.hashes.print()}")
181
+ // } else {
182
+ // println("\nWOW: ${it.hashes.print()}")
183
+ // }
184
+ // }
185
+ // new
186
+ // } else {
187
+ // buildCell {
188
+ // isExotic = descriptor.isExotic
189
+ // levelMask = descriptor.levelMask
190
+ // storeBits(cellBits)
191
+ // storeRefs(cellRefs)
192
+ // }
193
+ // }
144
194
val cell = buildCell {
145
- isExotic = descriptors[index] .isExotic
146
- levelMask = descriptors[index] .levelMask
195
+ isExotic = descriptor .isExotic
196
+ levelMask = descriptor .levelMask
147
197
storeBits(cellBits)
148
198
storeRefs(cellRefs)
149
199
}
0 commit comments