byte vec & bit vec (bit set)

This commit is contained in:
alexander.nutz
2024-03-25 10:45:04 +01:00
parent 6e9300fac6
commit a2fcfd9ef4
8 changed files with 273 additions and 0 deletions

View File

@@ -15,6 +15,39 @@ interface ByteBatchIterator: BatchIterator<Byte> {
fun nextBytes(dest: ByteArray): Int
}
fun BatchIterator<Byte>.asByteBatchIterator(): ByteBatchIterator =
object : ByteBatchIterator {
override fun nextBytes(dest: ByteArray): Int {
val temp = Array<Byte>(dest.size) { 0 }
val am = this@asByteBatchIterator.next(temp)
temp.copyInto(dest)
return am
}
override fun next(dest: Array<Byte>): Int =
this@asByteBatchIterator.next(dest)
override fun next(limit: Int): List<Byte> =
this@asByteBatchIterator.next(limit)
override fun next(dest: MutableList<Byte>, limit: Int) =
this@asByteBatchIterator.next(dest, limit)
override fun nextBytes(limit: Int): ByteArray {
val temp = Array<Byte>(limit) { 0 }
val am = this@asByteBatchIterator.next(temp)
val o = ByteArray(am)
temp.copyInto(o)
return o
}
override fun next(): Byte =
this@asByteBatchIterator.next()
override fun hasNext(): Boolean =
this@asByteBatchIterator.hasNext()
}
interface BatchSequence<T>: Sequence<T> {
override fun iterator(): BatchIterator<T>
}

View File

@@ -0,0 +1,66 @@
package blitz.collections
import blitz.toBit2
import blitz.toBool
import blitz.toByte
import kotlin.math.ceil
// TODO: make it hybrid to a real bitset if a lot of elements
class BitVec private constructor(
private val byteVec: ByteVec
): Vec<Boolean> {
constructor(initCap: Int = 0): this(ByteVec(initCap))
override val size: Int
get() = byteVec.size
// TODO: implement better
fun toBytes(): ByteArray =
toString()
.padEnd(ceil(byteVec.size.toFloat() / 8).toInt(), '0')
.chunked(8)
.map { it.toByte(2) }
.toByteArray()
override fun flip() =
byteVec.flip()
override fun copy(): Vec<Boolean> =
BitVec(byteVec)
override fun reserve(amount: Int) =
byteVec.reserve(amount)
override fun popBack(): Boolean =
byteVec.popBack().toBool()
override fun pushBack(elem: Boolean) =
byteVec.pushBack(elem.toByte())
override fun get(index: Int): Boolean =
byteVec[index].toBool()
override fun iterator(): Iterator<Boolean> =
byteVec.iterator().mapModifier { it.toBool() }
override fun toString(): String =
joinToString(separator = "") { it.toBit2().toString() }
override fun set(index: Int, value: Boolean) {
byteVec[index] = value.toByte()
}
companion object {
// TODO: implement better
fun from(bytes: ByteArray): BitVec =
BitVec(ByteVec.from(
bytes.asSequence()
.map { it
.toString(2)
.map { c -> (c == '1').toByte() }
}
.flatten()
))
}
}

View File

@@ -0,0 +1,5 @@
package blitz.collections
fun Array<Byte>.copyInto(dest: ByteArray) {
forEachIndexed { i, byte -> dest[i] = byte }
}

View File

@@ -0,0 +1,79 @@
package blitz.collections
class ByteVec(initCap: Int = 0): Vec<Byte>, ByteBatchSequence {
override var size = 0
private var cap = initCap
private var array = ByteArray(initCap)
fun copyAsArray(): ByteArray =
array.copyOfRange(0, size)
fun copyIntoArray(arr: ByteArray, destOff: Int = 0, startOff: Int = 0) =
array.copyInto(arr, destOff, startOff, size)
override fun copy(): ByteVec =
ByteVec(size).also {
copyIntoArray(it.array)
}
override fun reserve(amount: Int) {
if (amount > 0 && cap - size >= amount)
return
array = array.copyOf(size + amount)
cap = size + amount
}
override fun popBack(): Byte =
array[size - 1].also {
reserve(-1)
size --
}
fun popBack(dest: ByteArray, destOff: Int = 0) {
copyIntoArray(dest, destOff, size - dest.size)
reserve(-dest.size)
size -= dest.size
}
override fun get(index: Int): Byte =
array[index]
override fun flip() {
array = array.reversedArray()
}
fun pushBack(arr: ByteArray) {
reserve(arr.size)
arr.copyInto(array, size)
size += arr.size
}
override fun pushBack(elem: Byte) {
reserve(8)
array[size] = elem
size ++
}
override fun iterator(): ByteBatchIterator =
array.asSequence().asBatch().iterator().asByteBatchIterator()
override fun toString(): String =
joinToString(prefix = "[", postfix = "]") { "0x${it.toUByte().toString(16)}" }
override fun set(index: Int, value: Byte) {
array[index] = value
}
companion object {
fun from(bytes: ByteArray) =
ByteVec(bytes.size).also {
bytes.copyInto(it.array)
it.size += bytes.size
}
fun from(bytes: Sequence<Byte>) =
ByteVec().also { bv ->
bytes.forEach(bv::pushBack)
}
}
}

View File

@@ -0,0 +1,10 @@
package blitz.collections
fun <T, R> Iterator<T>.mapModifier(fn: (T) -> R): Iterator<R> =
object : Iterator<R> {
override fun next(): R =
fn(this@mapModifier.next())
override fun hasNext(): Boolean =
this@mapModifier.hasNext()
}

View File

@@ -0,0 +1,31 @@
package blitz.collections
interface Vec<T>: IndexableSequence<T> {
val size: Int
fun flip()
fun copy(): Vec<T>
fun reserve(amount: Int)
fun pushBack(elem: T)
fun pushBack(elems: Array<T>) {
reserve(elems.size)
elems.forEach(::pushBack)
}
fun pushBack(elems: Collection<T>) {
reserve(elems.size)
elems.forEach(::pushBack)
}
fun popBack(): T
fun popBack(dest: Array<T>) {
var writer = 0
repeat(dest.size) {
dest[writer ++] = popBack()
}
}
operator fun set(index: Int, value: T)
}