in environment/src/main/kotlin/jetbrains/exodus/gc/UtilizationProfile.kt [64:126]
fun load() {
val ec = env.environmentConfig
if (ec.gcUtilizationFromScratch) {
computeUtilizationFromScratch()
} else {
val storedUtilization = ec.gcUtilizationFromFile
if (!storedUtilization.isEmpty()) {
loadUtilizationFromFile(storedUtilization)
} else {
env.executeInReadonlyTransaction { txn ->
if (!env.storeExists(GarbageCollector.UTILIZATION_PROFILE_STORE_NAME, txn)) {
if (env.allStoreCount == 0L && log.numberOfFiles <= 1) {
clearUtilization()
} else {
computeUtilizationFromScratch()
}
} else {
val filesUtilization = LongHashMap<MutableLong>()
val store = env.openStore(
GarbageCollector.UTILIZATION_PROFILE_STORE_NAME,
StoreConfig.WITHOUT_DUPLICATES,
txn
)
store.openCursor(txn).use { cursor ->
while (cursor.next) {
val fileAddress = LongBinding.compressedEntryToLong(cursor.key)
val freeBytes = CompressedUnsignedLongByteIterable.getLong(cursor.value)
// don't update utilization of files being reset but not deleted
// if they were not actually deleted they will be collected first
if (freeBytes != 0L) {
filesUtilization[fileAddress] = MutableLong(freeBytes)
}
}
}
// check of saved utilization is consistent, at least if it contains same files as the log
var inconsistent = false
with(PackedLongHashSet(filesUtilization.keys)) {
log.allFileAddresses.forEach {
if (!remove(it)) {
inconsistent = true
return@with
}
}
if (isNotEmpty()) {
inconsistent = true
}
}
if (inconsistent) {
computeUtilizationFromScratch()
} else {
this@UtilizationProfile.filesUtilization.synchronized {
clear()
putAll(filesUtilization)
}
estimateTotalBytesAndWakeGcIfNecessary()
}
}
}
}
}
}