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.aayushatharva.brotli4j.encoder.Encoder
|
||||||
import com.nisemoe.nise.integrations.CircleguardService
|
import com.nisemoe.nise.integrations.CircleguardService
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class CompressJudgements {
|
class CompressJudgements {
|
||||||
|
|
||||||
@ -19,25 +19,55 @@ class CompressJudgements {
|
|||||||
Brotli4jLoader.ensureAvailability()
|
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 {
|
fun serialize(judgements: List<CircleguardService.ScoreJudgement>): ByteArray {
|
||||||
val buffer = ByteBuffer.allocate(judgements.size * (2 + 4 + 4 + 1 + 2 + 2 + 2))
|
val byteStream = ByteArrayOutputStream()
|
||||||
var lastTime = 0.0
|
var lastTimestamp = 0.0
|
||||||
|
|
||||||
judgements.forEach { judgement ->
|
judgements.forEach { judgement ->
|
||||||
val deltaTime = (judgement.time - lastTime).toInt()
|
byteStream.use { stream ->
|
||||||
buffer.putShort(deltaTime.toShort())
|
/**
|
||||||
|
* We allocate an arbitrary amount of buffer which *hopefully* is enough.
|
||||||
buffer.putInt((round(judgement.x * 1000)).toInt())
|
*/
|
||||||
buffer.putInt((round(judgement.y * 1000)).toInt())
|
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.put(judgement.type.ordinal.toByte())
|
||||||
buffer.putShort((judgement.distance_center * 100).toInt().toShort())
|
buffer.putVLQ((judgement.distance_center * 100).toInt())
|
||||||
buffer.putShort((judgement.distance_edge * 100).toInt().toShort())
|
buffer.putVLQ((judgement.distance_edge * 100).toInt())
|
||||||
buffer.putShort(judgement.error.toInt().toShort())
|
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> {
|
fun deserialize(compressedData: ByteArray): List<CircleguardService.ScoreJudgement> {
|
||||||
@ -47,28 +77,18 @@ class CompressJudgements {
|
|||||||
var lastTime = 0.0
|
var lastTime = 0.0
|
||||||
|
|
||||||
while (buffer.hasRemaining()) {
|
while (buffer.hasRemaining()) {
|
||||||
val deltaTime = buffer.short.toInt()
|
val deltaTime = buffer.getVLQ()
|
||||||
lastTime += deltaTime
|
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(
|
judgements.add(
|
||||||
CircleguardService.ScoreJudgement(
|
CircleguardService.ScoreJudgement(
|
||||||
time = lastTime,
|
time = lastTime,
|
||||||
x = deltaX / 1000.0,
|
x = buffer.getVLQ() / 100.0,
|
||||||
y = deltaY / 1000.0,
|
y = buffer.getVLQ() / 100.0,
|
||||||
type = type,
|
type = CircleguardService.JudgementType.entries[buffer.get().toInt()],
|
||||||
distance_center = distanceCenter,
|
distance_center = buffer.getVLQ() / 100.0,
|
||||||
distance_edge = distanceEdge,
|
distance_edge = buffer.getVLQ() / 100.0,
|
||||||
error = error.toDouble()
|
error = buffer.getVLQ().toDouble()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user