Skip to content

Commit

Permalink
0.3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
andreypfau committed Sep 19, 2024
1 parent 7eb82e9 commit f0502a1
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 45 deletions.
8 changes: 7 additions & 1 deletion bitstring/src/BitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
public operator fun plus(bits: BooleanArray): BitString =
plus(bits.asIterable())


public operator fun plus(bits: Collection<Boolean>): BitString =
plus(bits.asIterable())

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

public operator fun plus(bits: BitString): BitString
public operator fun plus(bytes: ByteArray): BitString
public fun plus(bytes: ByteArray, bits: Int): BitString

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

public fun toBinary(): String = joinToString("") { if (it) "1" else "0" }
public fun toHex(): String

@Deprecated(message = "Use toHexString()", replaceWith = ReplaceWith("toHexString()"))
public fun toHex(): String = toHexString()

public fun toHexString(): String

public companion object {
@JvmStatic
Expand Down
24 changes: 13 additions & 11 deletions bitstring/src/ByteBackedBitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ public open class ByteBackedBitString protected constructor(
override val size: Int,
public open val bytes: ByteArray
) : BitString {
private val hashCode by lazy(LazyThreadSafetyMode.PUBLICATION) {
var result = size
result = 31 * result + bytes.contentHashCode()
result
}

override operator fun get(index: Int): Boolean = getOrNull(index) ?: throw BitStringUnderflowException()

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

override fun plus(bits: BitString): BitString = toMutableBitString().plus(bits)
override fun plus(bytes: ByteArray): BitString = toMutableBitString().plus(bytes)
override fun plus(bytes: ByteArray, bits: Int): BitString = toMutableBitString().plus(bytes, bits)

Expand Down Expand Up @@ -77,9 +84,9 @@ public open class ByteBackedBitString protected constructor(
}
}

override fun toString(): String = "x{${toHex()}}"
override fun toString(): String = "x{${toHexString()}}"

override fun toHex(): String {
override fun toHexString(): String {
if (size == 0) return ""
val data = appendTag(bytes, size)
val result = StringBuilder(data.toHexString())
Expand Down Expand Up @@ -111,11 +118,7 @@ public open class ByteBackedBitString protected constructor(
return true
}

override fun hashCode(): Int {
var result = size
result = 31 * result + bytes.contentHashCode()
return result
}
override fun hashCode(): Int = hashCode

internal open class BitStringIterator(
val bitString: BitString,
Expand Down Expand Up @@ -168,10 +171,9 @@ public open class ByteBackedBitString protected constructor(
@JvmStatic
protected fun expandByteArray(bytes: ByteArray, size: Int): ByteArray {
val requiredBytesSize = bytesSize(size)
return if (bytes.size == requiredBytesSize) {
bytes
} else {
constructByteArray(bytes, size)
return when {
bytes.size < requiredBytesSize -> constructByteArray(bytes, size)
else -> bytes
}
}

Expand Down
46 changes: 35 additions & 11 deletions bitstring/src/ByteBackedMutableBitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,28 @@ public open class ByteBackedMutableBitString(

override fun plus(bits: BooleanArray): ByteBackedMutableBitString = plus(bits.asIterable())
override fun plus(bytes: ByteArray): ByteBackedMutableBitString = plus(bytes, bytes.size * Byte.SIZE_BITS)
override fun plus(bits: Iterable<Boolean>): ByteBackedMutableBitString = plus(bits.toList())
override fun plus(bits: Collection<Boolean>): ByteBackedMutableBitString = apply {
if (bits is ByteBackedBitString) {
plus(bits.bytes, bits.size)
override fun plus(bits: Iterable<Boolean>): ByteBackedMutableBitString =
plus(if (bits is Collection<Boolean>) bits else bits.toList())

override fun plus(bits: BitString): BitString {
return if (bits is ByteBackedBitString) {
plus(bits)
} else {
val bitsCount = bits.size
plus(bits.toList())
}
}

val newBytes = expandByteArray(bytes, size + bitsCount)
bits.forEachIndexed { index, bit ->
set(newBytes, size + index, bit)
}
bytes = newBytes
size += bitsCount
public fun plus(bits: ByteBackedBitString): BitString = plus(bits.bytes, bits.size)

override fun plus(bits: Collection<Boolean>): ByteBackedMutableBitString = apply {
val bitsCount = bits.size

val newBytes = expandByteArray(bytes, size + bitsCount)
bits.forEachIndexed { index, bit ->
set(newBytes, size + index, bit)
}
bytes = newBytes
size += bitsCount
}

override fun plus(bit: Boolean): MutableBitString = plus(listOf(bit))
Expand Down Expand Up @@ -118,6 +126,22 @@ public open class ByteBackedMutableBitString(
}
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ByteBackedBitString) return false

if (size != other.size) return false
if (!bytes.contentEquals(other.bytes)) return false

return true
}

override fun hashCode(): Int {
var result = size
result = 31 * result + bytes.contentHashCode()
return result
}

public companion object {
@JvmStatic
public fun of(size: Int = 0): ByteBackedMutableBitString {
Expand Down
4 changes: 3 additions & 1 deletion bitstring/src/EmptyBitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ internal object EmptyBitString : BitString {

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

override fun plus(bits: BitString): BitString = bits

override fun plus(bits: Collection<Boolean>): BitString = BitString(bits)

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

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

override fun toHex(): String = ""
override fun toHexString(): String = ""

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {

allprojects {
group = "org.ton"
version = "0.4.0-SNAPSHOT"
version = "0.3.2"

repositories {
mavenCentral()
Expand Down
72 changes: 61 additions & 11 deletions tvm/src/boc/BagOfCellsUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,23 @@ internal fun Input.readBagOfCell(): BagOfCells {
val cellDescriptors = Array(cellCount) { CellDescriptor(0, 0) }

// measureTime {
val cellHashes = Array<List<Pair<ByteArray, Int>>?>(cellCount) { null }

repeat(cellCount) { cellIndex ->
val d1 = readByte()
val d2 = readByte()
val descriptor = CellDescriptor(d1, d2)

if (descriptor.hasHashes) {
discardExact(descriptor.hashCount * Cell.HASH_BYTES)
discardExact(descriptor.hashCount * Cell.DEPTH_BYTES)
val hashes = ArrayList<ByteArray>(descriptor.hashCount)
val depths = ArrayList<Int>(descriptor.hashCount)
repeat(descriptor.hashCount) {
hashes.add(readBytes(Cell.HASH_BYTES))
}
repeat(descriptor.hashCount) {
depths.add(readInt(2))
}
cellHashes[cellIndex] = hashes.zip(depths)
}

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

// Resolving references & constructing cells from leaves to roots
val cells = Array<CompletableDeferred<Cell>>(cellCount) { CompletableDeferred() }
val asyncCells = Array<CompletableDeferred<Cell>>(cellCount) { CompletableDeferred() }
GlobalScope.launch {
repeat(cellCount) { cellIndex ->
launch {
createCell(cellIndex, cells, cellBits, cellRefs, cellDescriptors)
createCell(cellIndex, asyncCells, cellBits, cellRefs, cellDescriptors, cellHashes)
}
}
}
Expand All @@ -120,30 +129,71 @@ internal fun Input.readBagOfCell(): BagOfCells {
readIntLittleEndian()
}

val cells = runBlocking {
asyncCells.toList().awaitAll()
}

val roots = rootIndexes.map { rootIndex ->
runBlocking {
cells[rootIndex].await()
}
cells[rootIndex]
}

return BagOfCells(roots)
return object : BagOfCells {
override val roots: List<Cell> = roots

override fun toString(): String = buildString {
roots.forEachIndexed { _, cell ->
Cell.toString(cell, this)
}
}

override fun iterator(): Iterator<Cell> = cells.iterator()
}
}

private suspend fun createCell(
index: Int,
cells: Array<CompletableDeferred<Cell>>,
bits: Array<BitString>,
refs: Array<IntArray>,
descriptors: Array<CellDescriptor>
descriptors: Array<CellDescriptor>,
cellHashes: Array<List<Pair<ByteArray, Int>>?>
) = coroutineScope {
val cellBits = bits[index]
val cellRefIndexes = refs[index]
val cellRefs = cellRefIndexes.map { refIndex ->
cells[refIndex].await()
}
val descriptor = descriptors[index]
val hashes = cellHashes[index]
// val cell = if (!descriptors[index].isExotic && hashes != null) {
// val new = buildCell {
// isExotic = descriptor.isExotic
// levelMask = descriptor.levelMask
// storeBits(cellBits)
// storeRefs(cellRefs)
// }
// fun List<Pair<ByteArray, Int>>.print() = map {
// it.first.toHexString()+"="+it.second
// }
// DataCell(descriptor, cellBits, cellRefs, hashes).also {
// if (new is DataCell && new.hashes != it.hashes) {
//// println("\nnew:${new.hashes.print()}\nit:${it.hashes.print()}")
// } else {
// println("\nWOW: ${it.hashes.print()}")
// }
// }
// new
// } else {
// buildCell {
// isExotic = descriptor.isExotic
// levelMask = descriptor.levelMask
// storeBits(cellBits)
// storeRefs(cellRefs)
// }
// }
val cell = buildCell {
isExotic = descriptors[index].isExotic
levelMask = descriptors[index].levelMask
isExotic = descriptor.isExotic
levelMask = descriptor.levelMask
storeBits(cellBits)
storeRefs(cellRefs)
}
Expand Down
5 changes: 3 additions & 2 deletions tvm/src/cell/CellBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public inline fun CellBuilder(cell: Cell): CellBuilder = CellBuilder.of(cell)
public inline fun CellBuilder(): CellBuilder = CellBuilder.beginCell()

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

var (d1, d2) = descriptor
val hasher = SHA256()
repeat(levels) { level ->
val hasher = SHA256()
hasher.reset()
val levelMask = if (descriptor.cellType == CellType.PRUNED_BRANCH) {
descriptor.levelMask
} else {
Expand Down
15 changes: 8 additions & 7 deletions tvm/src/cell/DataCell.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ public class DataCell(
override val descriptor: CellDescriptor,
override val bits: BitString,
override val refs: List<Cell>,
private val hashes: List<Pair<ByteArray, Int>>
internal val hashes: List<Pair<ByteArray, Int>>
) : Cell {
private val hashCode: Int by lazy(LazyThreadSafetyMode.PUBLICATION) {
var result = descriptor.hashCode()
result = 31 * result + hashes.hashCode()
result
}

override fun hash(level: Int): BitString {
val hashIndex = levelMask.apply(level).hashIndex
return BitString(hashes[hashIndex].first)
Expand Down Expand Up @@ -37,10 +43,5 @@ public class DataCell(
return refs == other.refs
}

override fun hashCode(): Int {
var result = descriptor.hashCode()
result = 31 * result + bits.hashCode()
result = 31 * result + refs.hashCode()
return result
}
override fun hashCode(): Int = hashCode
}

0 comments on commit f0502a1

Please sign in to comment.