Use VLQ to store judgements
This commit is contained in:
parent
fbd61e0fa1
commit
f382a0ed48
@ -5,10 +5,10 @@ import com.aayushatharva.brotli4j.decoder.Decoder
|
||||
import com.aayushatharva.brotli4j.encoder.Encoder
|
||||
import com.nisemoe.nise.integrations.CircleguardService
|
||||
import org.springframework.stereotype.Service
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.math.round
|
||||
|
||||
|
||||
@Service
|
||||
class CompressJudgements {
|
||||
|
||||
@ -19,25 +19,55 @@ class CompressJudgements {
|
||||
Brotli4jLoader.ensureAvailability()
|
||||
}
|
||||
|
||||
fun ByteBuffer.putVLQ(value: Int) {
|
||||
var currentValue = value
|
||||
do {
|
||||
var temp = (currentValue and 0x7F)
|
||||
currentValue = currentValue ushr 7
|
||||
if (currentValue != 0) {
|
||||
temp = temp or 0x80
|
||||
}
|
||||
this.put(temp.toByte())
|
||||
} while (currentValue != 0)
|
||||
}
|
||||
|
||||
fun ByteBuffer.getVLQ(): Int {
|
||||
var result = 0
|
||||
var shift = 0
|
||||
var b: Byte
|
||||
do {
|
||||
b = this.get()
|
||||
result = result or ((b.toInt() and 0x7F) shl shift)
|
||||
shift += 7
|
||||
} while (b.toInt() and 0x80 != 0)
|
||||
return result
|
||||
}
|
||||
|
||||
fun serialize(judgements: List<CircleguardService.ScoreJudgement>): ByteArray {
|
||||
val buffer = ByteBuffer.allocate(judgements.size * (2 + 4 + 4 + 1 + 2 + 2 + 2))
|
||||
var lastTime = 0.0
|
||||
val byteStream = ByteArrayOutputStream()
|
||||
var lastTimestamp = 0.0
|
||||
|
||||
judgements.forEach { judgement ->
|
||||
val deltaTime = (judgement.time - lastTime).toInt()
|
||||
buffer.putShort(deltaTime.toShort())
|
||||
|
||||
buffer.putInt((round(judgement.x * 1000)).toInt())
|
||||
buffer.putInt((round(judgement.y * 1000)).toInt())
|
||||
|
||||
byteStream.use { stream ->
|
||||
/**
|
||||
* We allocate an arbitrary amount of buffer which *hopefully* is enough.
|
||||
*/
|
||||
ByteBuffer.allocate(4096).let { buffer ->
|
||||
buffer.putVLQ((judgement.time - lastTimestamp).toInt())
|
||||
buffer.putVLQ(round(judgement.x * 100).toInt())
|
||||
buffer.putVLQ(round(judgement.y * 100).toInt())
|
||||
buffer.put(judgement.type.ordinal.toByte())
|
||||
buffer.putShort((judgement.distance_center * 100).toInt().toShort())
|
||||
buffer.putShort((judgement.distance_edge * 100).toInt().toShort())
|
||||
buffer.putShort(judgement.error.toInt().toShort())
|
||||
buffer.putVLQ((judgement.distance_center * 100).toInt())
|
||||
buffer.putVLQ((judgement.distance_edge * 100).toInt())
|
||||
buffer.putVLQ(judgement.error.toInt())
|
||||
|
||||
lastTime = judgement.time
|
||||
lastTimestamp = judgement.time
|
||||
stream.write(buffer.array(), 0, buffer.position())
|
||||
}
|
||||
return Encoder.compress(buffer.array(), brotliParameters)
|
||||
}
|
||||
}
|
||||
|
||||
return Encoder.compress(byteStream.toByteArray(), brotliParameters)
|
||||
}
|
||||
|
||||
fun deserialize(compressedData: ByteArray): List<CircleguardService.ScoreJudgement> {
|
||||
@ -47,28 +77,18 @@ class CompressJudgements {
|
||||
var lastTime = 0.0
|
||||
|
||||
while (buffer.hasRemaining()) {
|
||||
val deltaTime = buffer.short.toInt()
|
||||
val deltaTime = buffer.getVLQ()
|
||||
lastTime += deltaTime
|
||||
|
||||
val deltaX = buffer.getInt()
|
||||
val deltaY = buffer.getInt()
|
||||
|
||||
val typeOrdinal = buffer.get().toInt()
|
||||
val type = CircleguardService.JudgementType.entries[typeOrdinal]
|
||||
|
||||
val distanceCenter = buffer.short.toInt() / 100.0
|
||||
val distanceEdge = buffer.short.toInt() / 100.0
|
||||
val error = buffer.short.toInt()
|
||||
|
||||
judgements.add(
|
||||
CircleguardService.ScoreJudgement(
|
||||
time = lastTime,
|
||||
x = deltaX / 1000.0,
|
||||
y = deltaY / 1000.0,
|
||||
type = type,
|
||||
distance_center = distanceCenter,
|
||||
distance_edge = distanceEdge,
|
||||
error = error.toDouble()
|
||||
x = buffer.getVLQ() / 100.0,
|
||||
y = buffer.getVLQ() / 100.0,
|
||||
type = CircleguardService.JudgementType.entries[buffer.get().toInt()],
|
||||
distance_center = buffer.getVLQ() / 100.0,
|
||||
distance_edge = buffer.getVLQ() / 100.0,
|
||||
error = buffer.getVLQ().toDouble()
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user