Allow allocating indices sparsingly in IDAllocator
This commit is contained in:
parent
bb501e2c7e
commit
389d0648b1
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user