mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 09:26:11 -04:00
FragmentedArrayFloatList: fix broken batch adding in rare cases + test
This commit is contained in:
parent
c714fe483e
commit
ae1a8562de
@ -47,14 +47,18 @@ class FragmentedArrayFloatList(
|
||||
if (needed == 0) {
|
||||
return
|
||||
}
|
||||
grow(needed)
|
||||
tryGrow(needed)
|
||||
}
|
||||
|
||||
private fun grow(size: Int): FloatBuffer {
|
||||
private fun tryGrow(size: Int): FloatBuffer {
|
||||
if (finished) throw IllegalStateException()
|
||||
if (limit - this.size >= size) {
|
||||
return this.incomplete[0]
|
||||
}
|
||||
return grow(size)
|
||||
}
|
||||
|
||||
private fun grow(size: Int): FloatBuffer {
|
||||
val grow = if (nextGrowStep < size) {
|
||||
(size / nextGrowStep + 1) * nextGrowStep
|
||||
} else {
|
||||
@ -71,46 +75,63 @@ class FragmentedArrayFloatList(
|
||||
}
|
||||
|
||||
override fun add(value: Float) {
|
||||
val buffer = grow(1)
|
||||
val buffer = tryGrow(1)
|
||||
buffer.put(value)
|
||||
size += 1
|
||||
tryPush(buffer)
|
||||
invalidateOutput()
|
||||
}
|
||||
|
||||
private fun batchAdd(value: Float, buffer: FloatBuffer, left: Int): FloatBuffer {
|
||||
buffer.put(value)
|
||||
if (!tryPush(buffer)) {
|
||||
return buffer
|
||||
}
|
||||
if (left == 0) return buffer
|
||||
return grow(left)
|
||||
}
|
||||
|
||||
fun add(value1: Float, value2: Float) {
|
||||
var buffer = grow(2)
|
||||
buffer.put(value1); if (tryPush(buffer)) buffer = grow(1)
|
||||
buffer.put(value2)
|
||||
var buffer = tryGrow(1)
|
||||
buffer = batchAdd(value1, buffer, 1)
|
||||
batchAdd(value2, buffer, 0)
|
||||
|
||||
size += 2
|
||||
tryPush(buffer)
|
||||
invalidateOutput()
|
||||
}
|
||||
|
||||
fun add(value1: Float, value2: Float, value3: Float) {
|
||||
var buffer = grow(3)
|
||||
buffer.put(value1); if (tryPush(buffer)) buffer = grow(2)
|
||||
buffer.put(value2); if (tryPush(buffer)) buffer = grow(1)
|
||||
buffer.put(value3)
|
||||
var buffer = tryGrow(1)
|
||||
buffer = batchAdd(value1, buffer, 2)
|
||||
buffer = batchAdd(value2, buffer, 1)
|
||||
batchAdd(value3, buffer, 0)
|
||||
|
||||
size += 3
|
||||
tryPush(buffer)
|
||||
invalidateOutput()
|
||||
}
|
||||
|
||||
fun add(value1: Float, value2: Float, value3: Float, value4: Float) {
|
||||
var buffer = tryGrow(1)
|
||||
buffer = batchAdd(value1, buffer, 3)
|
||||
buffer = batchAdd(value2, buffer, 2)
|
||||
buffer = batchAdd(value3, buffer, 1)
|
||||
batchAdd(value4, buffer, 0)
|
||||
|
||||
size += 4
|
||||
invalidateOutput()
|
||||
}
|
||||
|
||||
fun add(value1: Float, value2: Float, value3: Float, value4: Float, value5: Float, value6: Float, value7: Float) {
|
||||
var buffer = grow(7)
|
||||
buffer.put(value1); if (tryPush(buffer)) buffer = grow(6)
|
||||
buffer.put(value2); if (tryPush(buffer)) buffer = grow(5)
|
||||
buffer.put(value3); if (tryPush(buffer)) buffer = grow(4)
|
||||
buffer.put(value4); if (tryPush(buffer)) buffer = grow(3)
|
||||
buffer.put(value5); if (tryPush(buffer)) buffer = grow(2)
|
||||
buffer.put(value6); if (tryPush(buffer)) buffer = grow(1)
|
||||
buffer.put(value7)
|
||||
var buffer = tryGrow(1)
|
||||
buffer = batchAdd(value1, buffer, 6)
|
||||
buffer = batchAdd(value2, buffer, 5)
|
||||
buffer = batchAdd(value3, buffer, 4)
|
||||
buffer = batchAdd(value4, buffer, 3)
|
||||
buffer = batchAdd(value5, buffer, 2)
|
||||
buffer = batchAdd(value6, buffer, 1)
|
||||
batchAdd(value7, buffer, 0)
|
||||
|
||||
size += 7
|
||||
tryPush(buffer)
|
||||
invalidateOutput()
|
||||
}
|
||||
|
||||
@ -147,7 +168,7 @@ class FragmentedArrayFloatList(
|
||||
}
|
||||
size += offset
|
||||
val length = array.size - offset
|
||||
val next = grow(length)
|
||||
val next = tryGrow(length)
|
||||
next.put(array, offset, length)
|
||||
size += length
|
||||
next.position(length)
|
||||
@ -179,7 +200,7 @@ class FragmentedArrayFloatList(
|
||||
}
|
||||
size += offset
|
||||
val length = position - offset
|
||||
val next = grow(length)
|
||||
val next = tryGrow(length)
|
||||
buffer.copy(offset, next, 0, length)
|
||||
next.position(length)
|
||||
size += length
|
||||
|
@ -15,6 +15,7 @@ package de.bixilon.minosoft.util.collections.floats
|
||||
|
||||
import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class FragmentedFloatListTest : DirectFloatListTest() {
|
||||
@ -53,4 +54,35 @@ class FragmentedFloatListTest : DirectFloatListTest() {
|
||||
assertEquals(14, list.complete.size)
|
||||
assertEquals(0, list.incomplete.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `batch adding 7 floats`() {
|
||||
val list = FragmentedArrayFloatList(1)
|
||||
for (i in 0 until 100) {
|
||||
val offset = i * 7.0f
|
||||
list.add(offset + 0, offset + 1, offset + 2, offset + 3, offset + 4, offset + 5, offset + 6)
|
||||
}
|
||||
assertEquals(list.size, 700)
|
||||
val expected = FloatArray(700) { it.toFloat() }
|
||||
println(expected.contentToString())
|
||||
val array = list.toArray()
|
||||
println(array.contentToString())
|
||||
assertContentEquals(expected, array)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `batch adding float array`() {
|
||||
val list = FragmentedArrayFloatList(1)
|
||||
for (i in 0 until 100) {
|
||||
val offset = i * 7.0f
|
||||
val a = floatArrayOf(offset + 0, offset + 1, offset + 2, offset + 3, offset + 4, offset + 5, offset + 6)
|
||||
list += a
|
||||
}
|
||||
assertEquals(list.size, 700)
|
||||
val expected = FloatArray(700) { it.toFloat() }
|
||||
println(expected.contentToString())
|
||||
val array = list.toArray()
|
||||
println(array.contentToString())
|
||||
assertContentEquals(expected, array)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user