upgraded to k1.8, upgraded stools, added more docs on codecs
This commit is contained in:
parent
8fb052c4f9
commit
6e65a216c5
@ -14,4 +14,4 @@ Goals:
|
|||||||
|
|
||||||
## SmartInt codec
|
## SmartInt codec
|
||||||
|
|
||||||
Variable-length signed and unsigned integer codec, see `object SmartInt`. For not too small numbers it is slightly more effective than `VarInt` codec, for example on `Long` values it saves a byte.
|
Variable-length signed and unsigned integer codec, see [src:Smartint]. For not too small numbers it is slightly more effective than `VarInt` codec, for example on `Long` values it saves a byte.
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform") version "1.7.21"
|
kotlin("multiplatform") version "1.8.10"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
@ -23,9 +23,9 @@ kotlin {
|
|||||||
}
|
}
|
||||||
js(IR) {
|
js(IR) {
|
||||||
browser {
|
browser {
|
||||||
commonWebpackConfig {
|
// commonWebpackConfig {
|
||||||
cssSupport.enabled = true
|
// cssSupport.enabled = true
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val hostOs = System.getProperty("os.name")
|
val hostOs = System.getProperty("os.name")
|
||||||
@ -42,7 +42,7 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
|
||||||
api("net.sergeych:mp_stools:1.3.2")
|
api("net.sergeych:mp_stools:[1.3.3,)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
|
@ -21,31 +21,50 @@ import net.sergeych.bintools.*
|
|||||||
* | 10 | 64 | --- |
|
* | 10 | 64 | --- |
|
||||||
*
|
*
|
||||||
* In other words, except for very small numbers smartint
|
* In other words, except for very small numbers smartint
|
||||||
* gives 1 bit gain. So, full sized 64 bits with smartint takes
|
* gives 1 data bit gain for the same packed byte size. For example,
|
||||||
* 9 bytes, while varint needs 10. This could be important.
|
* full size 64 bits number with smartint takes one byte less (9 bytes vs. 10 in Varint).
|
||||||
*
|
*
|
||||||
* Encoding is the following:
|
* So, except for values in range 32..63 it gives same or better byte size effectiveness
|
||||||
|
* than `Varint`. In particular:
|
||||||
*
|
*
|
||||||
* Byte 0: bits 0..1 : type
|
* The effect of it could be interpreted as:
|
||||||
* bits 2..7 : v0
|
|
||||||
*
|
*
|
||||||
* Then depending on the type:
|
* | number values | size |
|
||||||
|
* |:--------------|:------:|
|
||||||
|
* | 0..31 | same |
|
||||||
|
* | 32..63 | worse 1 byte |
|
||||||
|
* | 64..1048573 | same |
|
||||||
|
* | 1048576..2097151 | 1 byte better |
|
||||||
|
* | 2097152..134217727 | same |
|
||||||
|
* | 134217728..268435456 | 1 byte better |
|
||||||
*
|
*
|
||||||
* type = 0:
|
* etc.
|
||||||
* v0 is the resul 0..64 (or -32..32)
|
|
||||||
*
|
*
|
||||||
* type = 1:
|
* ## Encoding format
|
||||||
* v0, v1 is the result, 14 bits
|
|
||||||
*
|
*
|
||||||
* type = 2:
|
* Enncoded data could be 1 or more bytes in length. Data are
|
||||||
* v0, v1, v2 are the result, 22bits
|
* packed as follows:
|
||||||
*
|
*
|
||||||
* type = 3:
|
* | byte offset | bits range | field |
|
||||||
* v0, v1, v2, varint encoded
|
* |-------------|------------|-------|
|
||||||
|
* | 0 | 0..1 | type |
|
||||||
|
* | 0 | 2..7 | v0 |
|
||||||
|
* | 1 | 0..7 | v1 (when used) |
|
||||||
|
* | 2 | 0..7 | v2 (when used) |
|
||||||
*
|
*
|
||||||
* Varint encodes bytes with last bit reserved as end
|
* Then depending on the `type` field:
|
||||||
* flag and first 7 bits are data bits. Last bit 0 means end of the
|
*
|
||||||
* sequence.
|
* | type | encoded |
|
||||||
|
* |------|---------|
|
||||||
|
* | 0 | v0 is the result 0..64 (or -32..32) |
|
||||||
|
* | 1 | v0 ## v1 are the result, 14 bits |
|
||||||
|
* | 2 | v0 ## v1 ## v2 are the result, 22bits
|
||||||
|
* | 3 | v0, ## v1 ## v2 ## (varint encoded rest) |
|
||||||
|
*
|
||||||
|
* Where `##` means bits concatenation. The bits are interpreted as BIG ENDIAN,
|
||||||
|
* for example `24573` will be encoded to `EA FF 02`
|
||||||
|
*
|
||||||
|
* See also [Varint] for its encoding description.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
object Smartint : IntCodec {
|
object Smartint : IntCodec {
|
||||||
|
@ -10,7 +10,7 @@ import kotlin.test.assertEquals
|
|||||||
|
|
||||||
class SmartintTest {
|
class SmartintTest {
|
||||||
|
|
||||||
inline fun <reified T:Number>testValue(x: T) {
|
inline fun <reified T : Number> testValue(x: T) {
|
||||||
assertEquals(x, Smartint.decode(Smartint.encode(x)))
|
assertEquals(x, Smartint.decode(Smartint.encode(x)))
|
||||||
println("+ ${x}: ${Smartint.encode(x).encodeToHex()}")
|
println("+ ${x}: ${Smartint.encode(x).encodeToHex()}")
|
||||||
}
|
}
|
||||||
@ -19,12 +19,12 @@ class SmartintTest {
|
|||||||
println("----- $bits -----")
|
println("----- $bits -----")
|
||||||
val window = 5
|
val window = 5
|
||||||
var median: Long = (1.toULong() shl bits).toLong()
|
var median: Long = (1.toULong() shl bits).toLong()
|
||||||
for( x in (median-2)..(median+2)) {
|
for (x in (median - 2)..(median + 2)) {
|
||||||
testValue(x)
|
testValue(x)
|
||||||
testValue(-x)
|
testValue(-x)
|
||||||
}
|
}
|
||||||
median = median * 3 / 2
|
median = median * 3 / 2
|
||||||
for( x in (median-5)..(median+5)) {
|
for (x in (median - 5)..(median + 5)) {
|
||||||
testValue(x)
|
testValue(x)
|
||||||
testValue(-x)
|
testValue(-x)
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ class SmartintTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun encode() {
|
fun encode() {
|
||||||
for( i in 0..70) testValue(i.toLong())
|
for (i in 0..70) testValue(i.toLong())
|
||||||
testAround(6)
|
testAround(6)
|
||||||
testAround(14)
|
testAround(14)
|
||||||
testAround(22)
|
testAround(22)
|
||||||
@ -42,14 +42,30 @@ class SmartintTest {
|
|||||||
// testAround(28)
|
// testAround(28)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
// @Test
|
||||||
fun compareTest() {
|
fun compareTest() {
|
||||||
for( x in listOf<ULong>(0uL, 1uL, 66uL, 129uL, 219uL, 0x1122uL, 0xFFEEuL, 0xAAbbCCdduL,
|
// for( x in listOf<ULong>(0uL, 1uL, 66uL, 129uL, 219uL, 0x1122uL, 0xFFEEuL, 0xAAbbCCdduL,
|
||||||
0x1111222233334444uL, (1UL shl 63))) {
|
// 0x1111222233334444uL, (1UL shl 63))) {
|
||||||
|
var lastDelta = 0
|
||||||
|
for (x in 0..3000000000) {
|
||||||
|
val n1 = Varint.encode(x).size
|
||||||
|
val n2 = Smartint.encode(x).size
|
||||||
|
val delta = n1 - n2
|
||||||
|
if (delta != lastDelta) {
|
||||||
|
when {
|
||||||
|
delta < 0 -> println("LOSS: $delta from $x")
|
||||||
|
delta > 0 -> println("GAIN: $delta from $x")
|
||||||
|
delta == 0 -> println("SAME: from $x")
|
||||||
|
}
|
||||||
|
lastDelta = delta
|
||||||
|
}
|
||||||
|
// for( x in listOf<ULong>(0uL, 1uL, (1UL shl 17)+11UL)) {
|
||||||
|
// 0x1111222233334444uL, (1UL shl 63))) {
|
||||||
// 1--12--23--34--4
|
// 1--12--23--34--4
|
||||||
println("--- $x / 0x${x.encodeToHex(8)}")
|
// println("--- $x / 0x${x.encodeToHex(8)}")
|
||||||
println("V: ${Varint.encode(x).encodeToHex()}")
|
// println("V: ${Varint.encode(x).encodeToHex()}")
|
||||||
println("S: ${Smartint.encode(x).encodeToHex()}")
|
// println("S: ${Smartint.encode(x).encodeToHex()}")
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user