circular array is fixed and tested

This commit is contained in:
minjaesong
2019-01-09 05:43:56 +09:00
parent 9140d6d8b0
commit 8a0abf22da
7 changed files with 102 additions and 27 deletions

View File

@@ -2,6 +2,8 @@ package net.torvald.dataclass
/**
* buffer[head] contains the most recent item, whereas buffer[tail] contains the oldest one.
*
* Notes for particle storage:
* Particles does not need to be removed, just let it overwrite as their operation is rather
* lightweight. So, just flagDespawn = true if it need to be "deleted" so that it won't update
@@ -12,57 +14,63 @@ package net.torvald.dataclass
class CircularArray<T>(val size: Int) {
val buffer: Array<T> = arrayOfNulls<Any>(size) as Array<T>
var tail: Int = 0
var head: Int = 0
var tail: Int = 0; private set
var head: Int = -1; private set
private var unreliableAddCount = 0
val lastIndex = size - 1
/** elemCount == size means it has the exact elements and no more.
* If elemCount is greater by 1 against the size, it means it started to circle, elemCount won't increment at this point. */
val elemCount: Int
get() = if (tail >= head) tail - head else size
get() = unreliableAddCount
fun add(item: T) {
buffer[tail] = item // overwrites oldest item when eligible
tail = (tail + 1) % size
if (tail == head) {
head = (head + 1) % size
if (unreliableAddCount <= size) unreliableAddCount += 1
head = (head + 1) % size
if (unreliableAddCount > size) {
tail = (tail + 1) % size
}
buffer[head] = item // overwrites oldest item when eligible
//println("$this $unreliableAddCount")
}
inline fun forEach(action: (T) -> Unit) {
/**
* Iterates the array with oldest element first.
*/
fun forEach(action: (T) -> Unit) {
// has slightly better iteration performance than lambda
if (tail >= head) {
for (i in head..tail - 1)
if (unreliableAddCount <= size) {
for (i in 0..head)
action(buffer[i])
}
else {
for (i in 0..size - 1)
action(buffer[(i + head) % size])
action(buffer[(i + tail) % size])
}
}
// FIXME not working as intended
inline fun <R> fold(initial: R, operation: (R, T) -> R): R {
fun <R> fold(initial: R, operation: (R, T) -> R): R {
var accumulator = initial
//for (element in buffer) accumulator = operation(accumulator, element)
if (tail >= head) {
for (i in head..tail - 1)
operation(accumulator, buffer[i])
if (unreliableAddCount <= size) {
for (i in 0..head)
accumulator = operation(accumulator, buffer[i])
}
else {
for (i in 0..size - 1)
operation(accumulator, buffer[(i + head) % size])
accumulator = operation(accumulator, buffer[(i + tail) % size])
}
return accumulator
}
inline fun forEachConcurrent(action: (T) -> Unit) {
TODO()
}
inline fun forEachConcurrentWaitFor(action: (T) -> Unit) {
TODO()
}
override fun toString(): String {
return "CircularArray(size=" + buffer.size + ", head=" + head + ", tail=" + tail + ")"