serializable and hashable BitArray. Comparable BitList. Small improvements
This commit is contained in:
		
							parent
							
								
									2696f1546d
								
							
						
					
					
						commit
						3481a718b1
					
				@ -21,10 +21,10 @@ import lyng.time
 | 
			
		||||
//
 | 
			
		||||
// After all optimizations it takes ~120ms.
 | 
			
		||||
//
 | 
			
		||||
//for( r in 1..100 ) {
 | 
			
		||||
//    val start = Instant.now()
 | 
			
		||||
for( r in 1..100 ) {
 | 
			
		||||
    val start = Instant.now()
 | 
			
		||||
    val found = naiveCountHappyNumbers()
 | 
			
		||||
//    println("Found happy numbers: %d time %s"(found, Instant.now() - start))
 | 
			
		||||
    println("Found happy numbers: %d time %s"(found, Instant.now() - start))
 | 
			
		||||
    assert( found == 55252 )
 | 
			
		||||
//    delay(0.01)
 | 
			
		||||
//}
 | 
			
		||||
    delay(0.1)
 | 
			
		||||
}
 | 
			
		||||
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
 | 
			
		||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
 | 
			
		||||
 | 
			
		||||
group = "net.sergeych"
 | 
			
		||||
version = "0.9.1-SNAPSHOT"
 | 
			
		||||
version = "0.9.2-SNAPSHOT"
 | 
			
		||||
 | 
			
		||||
buildscript {
 | 
			
		||||
    repositories {
 | 
			
		||||
@ -66,6 +66,7 @@ kotlin {
 | 
			
		||||
//    iosArm64()
 | 
			
		||||
//    iosSimulatorArm64()
 | 
			
		||||
    linuxX64()
 | 
			
		||||
    linuxArm64()
 | 
			
		||||
    js {
 | 
			
		||||
        browser()
 | 
			
		||||
        nodejs()
 | 
			
		||||
@ -79,9 +80,9 @@ kotlin {
 | 
			
		||||
    sourceSets {
 | 
			
		||||
        all {
 | 
			
		||||
            languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
 | 
			
		||||
            languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
 | 
			
		||||
            languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
 | 
			
		||||
            languageSettings.optIn("kotlin.coroutines.DelicateCoroutinesApi")
 | 
			
		||||
            languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
 | 
			
		||||
            languageSettings.optIn("kotlinx.coroutines.flow.DelicateCoroutinesApi")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -164,6 +164,7 @@ class CompilerContext(val tokens: List<Token>) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suppress("NOTHING_TO_INLINE")
 | 
			
		||||
    inline fun addBreak() {
 | 
			
		||||
        breakFound = true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import net.sergeych.lynon.ObjLynonClass
 | 
			
		||||
import net.sergeych.mp_tools.globalDefer
 | 
			
		||||
import kotlin.math.*
 | 
			
		||||
 | 
			
		||||
@Suppress("TYPE_INTERSECTION_AS_REIFIED_WARNING")
 | 
			
		||||
class Script(
 | 
			
		||||
    override val pos: Pos,
 | 
			
		||||
    private val statements: List<Statement> = emptyList(),
 | 
			
		||||
 | 
			
		||||
@ -367,6 +367,7 @@ open class Obj {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        @Suppress("NOTHING_TO_INLINE")
 | 
			
		||||
        inline fun from(obj: Any?): Obj {
 | 
			
		||||
            @Suppress("UNCHECKED_CAST")
 | 
			
		||||
            return when (obj) {
 | 
			
		||||
 | 
			
		||||
@ -35,12 +35,12 @@ class ObjBitBuffer(val bitArray: BitArray) : Obj() {
 | 
			
		||||
        }.apply {
 | 
			
		||||
            addFn("toBuffer") {
 | 
			
		||||
                requireNoArgs()
 | 
			
		||||
                ObjBuffer(thisAs<ObjBitBuffer>().bitArray.asUbyteArray())
 | 
			
		||||
                ObjBuffer(thisAs<ObjBitBuffer>().bitArray.asUByteArray())
 | 
			
		||||
            }
 | 
			
		||||
            addFn("toDump") {
 | 
			
		||||
                requireNoArgs()
 | 
			
		||||
                ObjString(
 | 
			
		||||
                    thisAs<ObjBitBuffer>().bitArray.asUbyteArray().toDump()
 | 
			
		||||
                    thisAs<ObjBitBuffer>().bitArray.asUByteArray().toDump()
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
            addFn("size") {
 | 
			
		||||
 | 
			
		||||
@ -17,8 +17,10 @@
 | 
			
		||||
 | 
			
		||||
package net.sergeych.lynon
 | 
			
		||||
 | 
			
		||||
import kotlin.math.min
 | 
			
		||||
 | 
			
		||||
@Suppress("unused")
 | 
			
		||||
interface BitList {
 | 
			
		||||
interface BitList: Comparable<BitList> {
 | 
			
		||||
    operator fun get(bitIndex: Long): Int
 | 
			
		||||
    operator fun set(bitIndex: Long,value: Int)
 | 
			
		||||
    val size: Long
 | 
			
		||||
@ -31,6 +33,22 @@ interface BitList {
 | 
			
		||||
            if( index < size) this@BitList[index++]
 | 
			
		||||
            else null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun compareTo(other: BitList): Int {
 | 
			
		||||
        val m = min(size, other.size)
 | 
			
		||||
        for( i in 0 ..< m) {
 | 
			
		||||
            val a = this[i]
 | 
			
		||||
            val b = other[i]
 | 
			
		||||
            when {
 | 
			
		||||
                a < b -> return -1
 | 
			
		||||
                a > b -> return 1
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if( size > other.size) return 1
 | 
			
		||||
        if( size < other.size) return -1
 | 
			
		||||
        return 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun bitListOf(vararg bits: Int): BitList {
 | 
			
		||||
 | 
			
		||||
@ -17,13 +17,18 @@
 | 
			
		||||
 | 
			
		||||
package net.sergeych.lynon
 | 
			
		||||
 | 
			
		||||
import kotlinx.serialization.Serializable
 | 
			
		||||
import kotlin.math.min
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * BitList implementation as fixed suze array of bits; indexing works exactly same as if
 | 
			
		||||
 * [MemoryBitInput] is used with [MemoryBitInput.getBit]. See [MemoryBitOutput] for
 | 
			
		||||
 * bits order and more information.
 | 
			
		||||
 *
 | 
			
		||||
 * It is [BitList] - comparable, and provides valid [hashCode] and [equals], so it could
 | 
			
		||||
 * also be used as a key in maps.
 | 
			
		||||
 */
 | 
			
		||||
@Serializable
 | 
			
		||||
class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
 | 
			
		||||
 | 
			
		||||
    val bytesSize: Int get() = bytes.size
 | 
			
		||||
@ -73,7 +78,15 @@ class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
 | 
			
		||||
    fun asByteArray(): ByteArray = bytes.asByteArray()
 | 
			
		||||
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    fun asUbyteArray(): UByteArray = bytes
 | 
			
		||||
    fun asUByteArray(): UByteArray = bytes
 | 
			
		||||
 | 
			
		||||
    override fun equals(other: Any?): Boolean {
 | 
			
		||||
        return other is BitList && this.compareTo(other) == 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun hashCode(): Int {
 | 
			
		||||
        return bytes.contentHashCode()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@
 | 
			
		||||
package net.sergeych.lynon
 | 
			
		||||
 | 
			
		||||
import net.sergeych.collections.SortedList
 | 
			
		||||
import net.sergeych.lynon.Huffman.Alphabet
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -285,7 +284,7 @@ object Huffman {
 | 
			
		||||
 | 
			
		||||
    fun <T>decompress(bin: BitInput,alphabet: Alphabet<T>): UByteArray {
 | 
			
		||||
        val codes = deserializeCanonicCodes(bin, alphabet)
 | 
			
		||||
        return decompressUsingCodes(bin, codes, alphabet).asUbyteArray()
 | 
			
		||||
        return decompressUsingCodes(bin, codes, alphabet).asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -56,7 +56,7 @@ object ObjLynonClass : ObjClass("Lynon") {
 | 
			
		||||
@Suppress("unused")
 | 
			
		||||
suspend fun lynonEncodeAny(scope: Scope, value: Obj): UByteArray =
 | 
			
		||||
    (ObjLynonClass.encodeAny(scope, value))
 | 
			
		||||
        .bitArray.asUbyteArray()
 | 
			
		||||
        .bitArray.asUByteArray()
 | 
			
		||||
 | 
			
		||||
@Suppress("unused")
 | 
			
		||||
suspend fun lynonDecodeAny(scope: Scope, encoded: UByteArray): Obj =
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,10 @@ import net.sergeych.lyng.Source
 | 
			
		||||
import net.sergeych.lyng.eval
 | 
			
		||||
import net.sergeych.lyng.pacman.InlineSourcesImportProvider
 | 
			
		||||
import net.sergeych.lyng.toSource
 | 
			
		||||
import net.sergeych.lynon.BitArray
 | 
			
		||||
import net.sergeych.lynon.BitList
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
import kotlin.test.assertNotEquals
 | 
			
		||||
 | 
			
		||||
class OtherTests {
 | 
			
		||||
    @Test
 | 
			
		||||
@ -67,4 +70,33 @@ class OtherTests {
 | 
			
		||||
        Unit
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testBitArrayEqAndHash() {
 | 
			
		||||
 | 
			
		||||
        val b1 = BitArray.ofBits(1, 0, 1, 1)
 | 
			
		||||
        val b11 = BitArray.ofBits(1, 0, 1, 1)
 | 
			
		||||
        val b2 = BitArray.ofBits(1, 1, 1, 1)
 | 
			
		||||
        val b3 = BitArray.ofBits(1, 0, 1, 1, 0)
 | 
			
		||||
 | 
			
		||||
        assert( b3 > b1 )
 | 
			
		||||
        assert( b2 > b1)
 | 
			
		||||
        assert( b11.compareTo(b1) == 0)
 | 
			
		||||
 | 
			
		||||
        assertEquals(b1, b11)
 | 
			
		||||
        assertNotEquals(b1, b2)
 | 
			
		||||
        assertNotEquals(b1, b3)
 | 
			
		||||
 | 
			
		||||
        assert( b1.hashCode() == b11.hashCode() )
 | 
			
		||||
 | 
			
		||||
        val x = mutableMapOf<BitList,String>()
 | 
			
		||||
        x[b1] = "wrong"
 | 
			
		||||
        x[b11] = "OK"
 | 
			
		||||
        x[b2] = "other"
 | 
			
		||||
 | 
			
		||||
        assertEquals("OK", x[b11])
 | 
			
		||||
        assertEquals("OK", x[b1])
 | 
			
		||||
        assertEquals("other", x[b2])
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user