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
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
||||
import it.unimi.dsi.fastutil.ints.IntRBTreeSet
|
||||
|
||||
class IDAllocator {
|
||||
private var highestID = 0
|
||||
private val gaps = IntAVLTreeSet()
|
||||
private var nextID = -1
|
||||
private val gaps = IntRBTreeSet()
|
||||
private val sparseAllocations = IntRBTreeSet()
|
||||
|
||||
private fun increaseHighestID(): Int {
|
||||
while (sparseAllocations.remove(++nextID)) {}
|
||||
return nextID
|
||||
}
|
||||
|
||||
fun allocate(): Int {
|
||||
if (gaps.isEmpty()) {
|
||||
return highestID++
|
||||
return increaseHighestID()
|
||||
} else {
|
||||
return gaps.removeFirst()
|
||||
}
|
||||
}
|
||||
|
||||
fun allocate(id: Int): Boolean {
|
||||
if (id < 0) {
|
||||
return true // not handling negative IDs
|
||||
} else if (id > nextID) {
|
||||
sparseAllocations.add(id)
|
||||
return true
|
||||
} else if (id == nextID) {
|
||||
increaseHighestID()
|
||||
return true
|
||||
} else {
|
||||
return gaps.remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun release(id: Int) {
|
||||
if (id >= 0) {
|
||||
throw IllegalArgumentException("Invalid ID: $id")
|
||||
} else if (id >= highestID) {
|
||||
throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${highestID - 1})")
|
||||
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")
|
||||
}
|
||||
|
||||
if (id + 1 == highestID) {
|
||||
highestID--
|
||||
} else if (id == nextID) {
|
||||
nextID--
|
||||
} else {
|
||||
gaps.add(id)
|
||||
check(gaps.add(id))
|
||||
}
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
highestID = 0
|
||||
nextID = -1
|
||||
gaps.clear()
|
||||
sparseAllocations.clear()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user