optimization: ise varint on field counter for extendable format (it's rare for a struct to have so many fields so smartint will be better).
This commit is contained in:
		
							parent
							
								
									e556d4bc3d
								
							
						
					
					
						commit
						149a0e1850
					
				@ -22,6 +22,11 @@ interface DataSink {
 | 
				
			|||||||
    fun writeBytes(data: ByteArray) {
 | 
					    fun writeBytes(data: ByteArray) {
 | 
				
			||||||
        for(d in data) writeByte(d)
 | 
					        for(d in data) writeByte(d)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun writeVarUInt(value: UInt) { Varint.encodeUnsigned(value.toULong())}
 | 
				
			||||||
 | 
					    fun writeVarInt(value: UInt) { Varint.encodeSigned(value.toLong())}
 | 
				
			||||||
 | 
					    fun writeSmartUInt(value: UInt) { Smartint.encodeUnsigned(value.toULong())}
 | 
				
			||||||
 | 
					    fun writeSmartInt(value: UInt) { Smartint.encodeSigned(value.toLong())}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline fun <reified T:Any>DataSink.writeNumber(value: T) {
 | 
					inline fun <reified T:Any>DataSink.writeNumber(value: T) {
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,14 @@ interface DataSource {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun readFloat() = Float.fromBits(readI32()).toFloat()
 | 
					    fun readFloat() = Float.fromBits(readI32()).toFloat()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun readSmartUInt(): UInt = Smartint.decodeUnsigned(this).toUInt()
 | 
				
			||||||
 | 
					    fun readSmartInt(): Int = Smartint.decodeSigned(this).toInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun readVarUInt(): UInt = Varint.decodeUnsigned(this).toUInt()
 | 
				
			||||||
 | 
					    fun readVarInt(): Int = Varint.decodeSigned(this).toInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fun ByteArray.toDataSource(): DataSource =
 | 
					fun ByteArray.toDataSource(): DataSource =
 | 
				
			||||||
 | 
				
			|||||||
@ -59,8 +59,8 @@ class BipackDecoder(val input: DataSource, var elementsCount: Int = 0,val isColl
 | 
				
			|||||||
        // CRC-calculating one, and the fields below are CRC protected too:
 | 
					        // CRC-calculating one, and the fields below are CRC protected too:
 | 
				
			||||||
        var count = descriptor.elementsCount
 | 
					        var count = descriptor.elementsCount
 | 
				
			||||||
        for (a in descriptor.annotations) {
 | 
					        for (a in descriptor.annotations) {
 | 
				
			||||||
            if (a is ExtendableFormat)
 | 
					            if (a is Extendable)
 | 
				
			||||||
                count = source.readNumber<UInt>().toInt()
 | 
					                count = source.readSmartUInt().toInt()
 | 
				
			||||||
            else if (a is Framed) {
 | 
					            else if (a is Framed) {
 | 
				
			||||||
                val code = CRC.crc32(descriptor.serialName.encodeToByteArray())
 | 
					                val code = CRC.crc32(descriptor.serialName.encodeToByteArray())
 | 
				
			||||||
                // if we fail to read CRC, it is IO error, so DataSource.EndOfData will be
 | 
					                // if we fail to read CRC, it is IO error, so DataSource.EndOfData will be
 | 
				
			||||||
 | 
				
			|||||||
@ -72,8 +72,8 @@ class BipackEncoder(val output: DataSink) : AbstractEncoder() {
 | 
				
			|||||||
                sink.writeU32(
 | 
					                sink.writeU32(
 | 
				
			||||||
                    CRC.crc32(descriptor.serialName.encodeToByteArray())
 | 
					                    CRC.crc32(descriptor.serialName.encodeToByteArray())
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            } else if (a is ExtendableFormat) {
 | 
					            } else if (a is Extendable) {
 | 
				
			||||||
                sink.writeNumber(descriptor.elementsCount.toUInt())
 | 
					                sink.writeSmartUInt(descriptor.elementsCount.toUInt())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return BipackEncoder(sink)
 | 
					        return BipackEncoder(sink)
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ import kotlinx.serialization.SerialInfo
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
@Target(AnnotationTarget.CLASS)
 | 
					@Target(AnnotationTarget.CLASS)
 | 
				
			||||||
@SerialInfo
 | 
					@SerialInfo
 | 
				
			||||||
annotation class ExtendableFormat
 | 
					annotation class Extendable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -29,7 +29,7 @@ annotation class Framed
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 * Allow to CRC-protect structures (we suppose to use it with classes only). After the
 | 
					 * Allow to CRC-protect structures (we suppose to use it with classes only). After the
 | 
				
			||||||
 * data block its CRC32 will be written and checked. It is memory-wise: it calculates CRC
 | 
					 * data block its CRC32 will be written and checked. It is memory-wise: it calculates CRC
 | 
				
			||||||
 * on the fly without buffering the data. If used with [Framed] and [ExtendableFormat] the extra
 | 
					 * on the fly without buffering the data. If used with [Framed] and [Extendable] the extra
 | 
				
			||||||
 * data is protected too.
 | 
					 * data is protected too.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * __Common pitfalls__. When unpacking corrupted data protected this way, the not only [InvalidFrameCRCException]
 | 
					 * __Common pitfalls__. When unpacking corrupted data protected this way, the not only [InvalidFrameCRCException]
 | 
				
			||||||
 | 
				
			|||||||
@ -11,11 +11,11 @@ import kotlin.test.*
 | 
				
			|||||||
data class Foobar1N(val bar: Int, val foo: Int = 117)
 | 
					data class Foobar1N(val bar: Int, val foo: Int = 117)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
@ExtendableFormat
 | 
					@Extendable
 | 
				
			||||||
data class Foobar1(val bar: Int, val foo: Int = 117)
 | 
					data class Foobar1(val bar: Int, val foo: Int = 117)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
@ExtendableFormat
 | 
					@Extendable
 | 
				
			||||||
@SerialName("bipack.Foobar1")
 | 
					@SerialName("bipack.Foobar1")
 | 
				
			||||||
data class Foobar2(val bar: Int, val foo: Int, val other: Int = -1)
 | 
					data class Foobar2(val bar: Int, val foo: Int, val other: Int = -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,12 +30,12 @@ data class FoobarF2(val bar: Int, val foo: Int, val other: Int = -1)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
@Framed
 | 
					@Framed
 | 
				
			||||||
@ExtendableFormat
 | 
					@Extendable
 | 
				
			||||||
data class FoobarF3(val bar: Int, val foo: Int, val other: Int = -1)
 | 
					data class FoobarF3(val bar: Int, val foo: Int, val other: Int = -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Serializable
 | 
					@Serializable
 | 
				
			||||||
@Framed
 | 
					@Framed
 | 
				
			||||||
@ExtendableFormat
 | 
					@Extendable
 | 
				
			||||||
@CrcProtected()
 | 
					@CrcProtected()
 | 
				
			||||||
data class FoobarFP1(val bar: Int, val foo: Int, val other: Int = -1)
 | 
					data class FoobarFP1(val bar: Int, val foo: Int, val other: Int = -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user