Allow allocating indices sparsingly in IDAllocator

This commit is contained in:
DBotThePony 2025-04-10 10:12:01 +07:00
parent bb501e2c7e
commit 389d0648b1
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,37 +1,58 @@
package ru.dbotthepony.mc.otm.util package ru.dbotthepony.mc.otm.util
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet import it.unimi.dsi.fastutil.ints.IntRBTreeSet
class IDAllocator { class IDAllocator {
private var highestID = 0 private var nextID = -1
private val gaps = IntAVLTreeSet() private val gaps = IntRBTreeSet()
private val sparseAllocations = IntRBTreeSet()
private fun increaseHighestID(): Int {
while (sparseAllocations.remove(++nextID)) {}
return nextID
}
fun allocate(): Int { fun allocate(): Int {
if (gaps.isEmpty()) { if (gaps.isEmpty()) {
return highestID++ return increaseHighestID()
} else { } else {
return gaps.removeFirst() return gaps.removeFirst()
} }
} }
fun release(id: Int) { fun allocate(id: Int): Boolean {
if (id >= 0) { if (id < 0) {
throw IllegalArgumentException("Invalid ID: $id") return true // not handling negative IDs
} else if (id >= highestID) { } else if (id > nextID) {
throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${highestID - 1})") sparseAllocations.add(id)
} else if (id in gaps) { return true
throw IllegalArgumentException("ID is already free: $id") } else if (id == nextID) {
increaseHighestID()
return true
} else {
return gaps.remove(id)
}
} }
if (id + 1 == highestID) { fun release(id: Int) {
highestID-- if (id < 0) {
return // not handling negative IDs
} else if (sparseAllocations.remove(id)) {
return // was allocated above highest ID
} else if (id > nextID) {
throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${nextID})")
} else if (id in gaps) {
throw IllegalArgumentException("ID is already free: $id")
} else if (id == nextID) {
nextID--
} else { } else {
gaps.add(id) check(gaps.add(id))
} }
} }
fun reset() { fun reset() {
highestID = 0 nextID = -1
gaps.clear() gaps.clear()
sparseAllocations.clear()
} }
} }