Skip to content

Commit f0502a1

Browse files
committed
0.3.2
1 parent 7eb82e9 commit f0502a1

8 files changed

+131
-45
lines changed

bitstring/src/BitString.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
3333
public operator fun plus(bits: BooleanArray): BitString =
3434
plus(bits.asIterable())
3535

36+
3637
public operator fun plus(bits: Collection<Boolean>): BitString =
3738
plus(bits.asIterable())
3839

3940
public operator fun plus(bits: Iterable<Boolean>): BitString =
4041
binary(toBinary() + bits.joinToString("") { if (it) "1" else "0" })
4142

43+
public operator fun plus(bits: BitString): BitString
4244
public operator fun plus(bytes: ByteArray): BitString
4345
public fun plus(bytes: ByteArray, bits: Int): BitString
4446

@@ -73,7 +75,11 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
7375
override fun toString(): String
7476

7577
public fun toBinary(): String = joinToString("") { if (it) "1" else "0" }
76-
public fun toHex(): String
78+
79+
@Deprecated(message = "Use toHexString()", replaceWith = ReplaceWith("toHexString()"))
80+
public fun toHex(): String = toHexString()
81+
82+
public fun toHexString(): String
7783

7884
public companion object {
7985
@JvmStatic

bitstring/src/ByteBackedBitString.kt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ public open class ByteBackedBitString protected constructor(
1111
override val size: Int,
1212
public open val bytes: ByteArray
1313
) : BitString {
14+
private val hashCode by lazy(LazyThreadSafetyMode.PUBLICATION) {
15+
var result = size
16+
result = 31 * result + bytes.contentHashCode()
17+
result
18+
}
19+
1420
override operator fun get(index: Int): Boolean = getOrNull(index) ?: throw BitStringUnderflowException()
1521

1622
override fun getOrNull(index: Int): Boolean? =
1723
if (index in 0..size) get(bytes, index) else null
1824

25+
override fun plus(bits: BitString): BitString = toMutableBitString().plus(bits)
1926
override fun plus(bytes: ByteArray): BitString = toMutableBitString().plus(bytes)
2027
override fun plus(bytes: ByteArray, bits: Int): BitString = toMutableBitString().plus(bytes, bits)
2128

@@ -77,9 +84,9 @@ public open class ByteBackedBitString protected constructor(
7784
}
7885
}
7986

80-
override fun toString(): String = "x{${toHex()}}"
87+
override fun toString(): String = "x{${toHexString()}}"
8188

82-
override fun toHex(): String {
89+
override fun toHexString(): String {
8390
if (size == 0) return ""
8491
val data = appendTag(bytes, size)
8592
val result = StringBuilder(data.toHexString())
@@ -111,11 +118,7 @@ public open class ByteBackedBitString protected constructor(
111118
return true
112119
}
113120

114-
override fun hashCode(): Int {
115-
var result = size
116-
result = 31 * result + bytes.contentHashCode()
117-
return result
118-
}
121+
override fun hashCode(): Int = hashCode
119122

120123
internal open class BitStringIterator(
121124
val bitString: BitString,
@@ -168,10 +171,9 @@ public open class ByteBackedBitString protected constructor(
168171
@JvmStatic
169172
protected fun expandByteArray(bytes: ByteArray, size: Int): ByteArray {
170173
val requiredBytesSize = bytesSize(size)
171-
return if (bytes.size == requiredBytesSize) {
172-
bytes
173-
} else {
174-
constructByteArray(bytes, size)
174+
return when {
175+
bytes.size < requiredBytesSize -> constructByteArray(bytes, size)
176+
else -> bytes
175177
}
176178
}
177179

bitstring/src/ByteBackedMutableBitString.kt

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,28 @@ public open class ByteBackedMutableBitString(
2222

2323
override fun plus(bits: BooleanArray): ByteBackedMutableBitString = plus(bits.asIterable())
2424
override fun plus(bytes: ByteArray): ByteBackedMutableBitString = plus(bytes, bytes.size * Byte.SIZE_BITS)
25-
override fun plus(bits: Iterable<Boolean>): ByteBackedMutableBitString = plus(bits.toList())
26-
override fun plus(bits: Collection<Boolean>): ByteBackedMutableBitString = apply {
27-
if (bits is ByteBackedBitString) {
28-
plus(bits.bytes, bits.size)
25+
override fun plus(bits: Iterable<Boolean>): ByteBackedMutableBitString =
26+
plus(if (bits is Collection<Boolean>) bits else bits.toList())
27+
28+
override fun plus(bits: BitString): BitString {
29+
return if (bits is ByteBackedBitString) {
30+
plus(bits)
2931
} else {
30-
val bitsCount = bits.size
32+
plus(bits.toList())
33+
}
34+
}
3135

32-
val newBytes = expandByteArray(bytes, size + bitsCount)
33-
bits.forEachIndexed { index, bit ->
34-
set(newBytes, size + index, bit)
35-
}
36-
bytes = newBytes
37-
size += bitsCount
36+
public fun plus(bits: ByteBackedBitString): BitString = plus(bits.bytes, bits.size)
37+
38+
override fun plus(bits: Collection<Boolean>): ByteBackedMutableBitString = apply {
39+
val bitsCount = bits.size
40+
41+
val newBytes = expandByteArray(bytes, size + bitsCount)
42+
bits.forEachIndexed { index, bit ->
43+
set(newBytes, size + index, bit)
3844
}
45+
bytes = newBytes
46+
size += bitsCount
3947
}
4048

4149
override fun plus(bit: Boolean): MutableBitString = plus(listOf(bit))
@@ -118,6 +126,22 @@ public open class ByteBackedMutableBitString(
118126
}
119127
}
120128

129+
override fun equals(other: Any?): Boolean {
130+
if (this === other) return true
131+
if (other !is ByteBackedBitString) return false
132+
133+
if (size != other.size) return false
134+
if (!bytes.contentEquals(other.bytes)) return false
135+
136+
return true
137+
}
138+
139+
override fun hashCode(): Int {
140+
var result = size
141+
result = 31 * result + bytes.contentHashCode()
142+
return result
143+
}
144+
121145
public companion object {
122146
@JvmStatic
123147
public fun of(size: Int = 0): ByteBackedMutableBitString {

bitstring/src/EmptyBitString.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ internal object EmptyBitString : BitString {
1111

1212
override fun plus(bits: Iterable<Boolean>): BitString = BitString(bits)
1313

14+
override fun plus(bits: BitString): BitString = bits
15+
1416
override fun plus(bits: Collection<Boolean>): BitString = BitString(bits)
1517

1618
override fun plus(bytes: ByteArray): BitString = BitString(bytes)
@@ -40,7 +42,7 @@ internal object EmptyBitString : BitString {
4042

4143
override fun toString(): String = "x{}"
4244

43-
override fun toHex(): String = ""
45+
override fun toHexString(): String = ""
4446

4547
override fun equals(other: Any?): Boolean {
4648
if (this === other) return true

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111

1212
allprojects {
1313
group = "org.ton"
14-
version = "0.4.0-SNAPSHOT"
14+
version = "0.3.2"
1515

1616
repositories {
1717
mavenCentral()

tvm/src/boc/BagOfCellsUtils.kt

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,23 @@ internal fun Input.readBagOfCell(): BagOfCells {
8080
val cellDescriptors = Array(cellCount) { CellDescriptor(0, 0) }
8181

8282
// measureTime {
83+
val cellHashes = Array<List<Pair<ByteArray, Int>>?>(cellCount) { null }
84+
8385
repeat(cellCount) { cellIndex ->
8486
val d1 = readByte()
8587
val d2 = readByte()
8688
val descriptor = CellDescriptor(d1, d2)
8789

8890
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)
91100
}
92101

93102
val cellData = readBytes(descriptor.dataLength)
@@ -106,11 +115,11 @@ internal fun Input.readBagOfCell(): BagOfCells {
106115
// }
107116

108117
// Resolving references & constructing cells from leaves to roots
109-
val cells = Array<CompletableDeferred<Cell>>(cellCount) { CompletableDeferred() }
118+
val asyncCells = Array<CompletableDeferred<Cell>>(cellCount) { CompletableDeferred() }
110119
GlobalScope.launch {
111120
repeat(cellCount) { cellIndex ->
112121
launch {
113-
createCell(cellIndex, cells, cellBits, cellRefs, cellDescriptors)
122+
createCell(cellIndex, asyncCells, cellBits, cellRefs, cellDescriptors, cellHashes)
114123
}
115124
}
116125
}
@@ -120,30 +129,71 @@ internal fun Input.readBagOfCell(): BagOfCells {
120129
readIntLittleEndian()
121130
}
122131

132+
val cells = runBlocking {
133+
asyncCells.toList().awaitAll()
134+
}
135+
123136
val roots = rootIndexes.map { rootIndex ->
124-
runBlocking {
125-
cells[rootIndex].await()
126-
}
137+
cells[rootIndex]
127138
}
128139

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+
}
130151
}
131152

132153
private suspend fun createCell(
133154
index: Int,
134155
cells: Array<CompletableDeferred<Cell>>,
135156
bits: Array<BitString>,
136157
refs: Array<IntArray>,
137-
descriptors: Array<CellDescriptor>
158+
descriptors: Array<CellDescriptor>,
159+
cellHashes: Array<List<Pair<ByteArray, Int>>?>
138160
) = coroutineScope {
139161
val cellBits = bits[index]
140162
val cellRefIndexes = refs[index]
141163
val cellRefs = cellRefIndexes.map { refIndex ->
142164
cells[refIndex].await()
143165
}
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+
// }
144194
val cell = buildCell {
145-
isExotic = descriptors[index].isExotic
146-
levelMask = descriptors[index].levelMask
195+
isExotic = descriptor.isExotic
196+
levelMask = descriptor.levelMask
147197
storeBits(cellBits)
148198
storeRefs(cellRefs)
149199
}

tvm/src/cell/CellBuilder.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public inline fun CellBuilder(cell: Cell): CellBuilder = CellBuilder.of(cell)
151151
public inline fun CellBuilder(): CellBuilder = CellBuilder.beginCell()
152152

153153
private class CellBuilderImpl(
154-
override var bits: MutableBitString = ByteBackedMutableBitString.of(),
154+
override var bits: MutableBitString = ByteBackedMutableBitString(ByteArray(128), 0),
155155
override var refs: MutableList<Cell> = ArrayList(),
156156
override var levelMask: LevelMask? = null,
157157
override var isExotic: Boolean = false
@@ -351,8 +351,9 @@ private class CellBuilderImpl(
351351
val hashes = ArrayList<Pair<ByteArray, Int>>(levels)
352352

353353
var (d1, d2) = descriptor
354+
val hasher = SHA256()
354355
repeat(levels) { level ->
355-
val hasher = SHA256()
356+
hasher.reset()
356357
val levelMask = if (descriptor.cellType == CellType.PRUNED_BRANCH) {
357358
descriptor.levelMask
358359
} else {

tvm/src/cell/DataCell.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ public class DataCell(
66
override val descriptor: CellDescriptor,
77
override val bits: BitString,
88
override val refs: List<Cell>,
9-
private val hashes: List<Pair<ByteArray, Int>>
9+
internal val hashes: List<Pair<ByteArray, Int>>
1010
) : Cell {
11+
private val hashCode: Int by lazy(LazyThreadSafetyMode.PUBLICATION) {
12+
var result = descriptor.hashCode()
13+
result = 31 * result + hashes.hashCode()
14+
result
15+
}
16+
1117
override fun hash(level: Int): BitString {
1218
val hashIndex = levelMask.apply(level).hashIndex
1319
return BitString(hashes[hashIndex].first)
@@ -37,10 +43,5 @@ public class DataCell(
3743
return refs == other.refs
3844
}
3945

40-
override fun hashCode(): Int {
41-
var result = descriptor.hashCode()
42-
result = 31 * result + bits.hashCode()
43-
result = 31 * result + refs.hashCode()
44-
return result
45-
}
46+
override fun hashCode(): Int = hashCode
4647
}

0 commit comments

Comments
 (0)