94 lines
3.4 KiB
Kotlin
94 lines
3.4 KiB
Kotlin
package io.gitlab.jfronny.inceptum.gtk.util
|
|
|
|
import io.gitlab.jfronny.commons.OSUtils
|
|
import io.gitlab.jfronny.inceptum.common.Utils
|
|
import java.io.IOException
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import java.util.regex.Pattern
|
|
|
|
object Memory {
|
|
const val KB: Long = 1024
|
|
const val MB = KB * 1024
|
|
const val GB = MB * 1024
|
|
private val impl = when (OSUtils.TYPE) {
|
|
OSUtils.Type.LINUX -> LinuxMI
|
|
OSUtils.Type.WINDOWS -> WindowsMI
|
|
OSUtils.Type.MAC_OS -> MacOsMI
|
|
}
|
|
private val totalMemory by lazy { impl.getTotalMemory() }
|
|
val maxMBForInstance: Long get() = (totalMemory / MB - 1024).coerceAtLeast(1024)
|
|
|
|
private interface MI {
|
|
fun getTotalMemory(): Long
|
|
}
|
|
|
|
private object LinuxMI : MI {
|
|
override fun getTotalMemory(): Long {
|
|
try {
|
|
Files.lines(Path.of("/proc/meminfo")).use { stream ->
|
|
val memTotal = stream
|
|
.filter { s: String -> s.startsWith("MemTotal:") }
|
|
.map { s: String -> s.substring("MemTotal:".length) }
|
|
.map { obj: String -> obj.trim { it <= ' ' } }
|
|
.findFirst()
|
|
return if (memTotal.isPresent()) {
|
|
parseDecimalMemorySizeToBinary(memTotal.get())
|
|
} else {
|
|
Utils.LOGGER.error("Could not find total memory")
|
|
32 * GB
|
|
}
|
|
}
|
|
} catch (e: IOException) {
|
|
Utils.LOGGER.error("Could not get total memory", e)
|
|
return 32 * GB
|
|
}
|
|
}
|
|
|
|
// Taken from oshi
|
|
private val BYTES_PATTERN = Pattern.compile("(\\d+) ?([kKMGT]?B?).*")
|
|
private val WHITESPACES = Pattern.compile("\\s+")
|
|
private fun parseDecimalMemorySizeToBinary(size: String): Long {
|
|
var mem = WHITESPACES.split(size)
|
|
if (mem.size < 2) {
|
|
// If no spaces, use regexp
|
|
val matcher = BYTES_PATTERN.matcher(size.trim { it <= ' ' })
|
|
if (matcher.find() && matcher.groupCount() == 2) {
|
|
mem = arrayOfNulls(2)
|
|
mem[0] = matcher.group(1)
|
|
mem[1] = matcher.group(2)
|
|
}
|
|
}
|
|
var capacity = parseLongOrDefault(mem[0], 0L)
|
|
if (mem.size == 2 && mem[1]!!.length > 1) {
|
|
when (mem[1]!![0]) {
|
|
'T' -> capacity = capacity shl 40
|
|
'G' -> capacity = capacity shl 30
|
|
'M' -> capacity = capacity shl 20
|
|
'K', 'k' -> capacity = capacity shl 10
|
|
else -> {}
|
|
}
|
|
}
|
|
return capacity
|
|
}
|
|
|
|
private fun parseLongOrDefault(s: String, defaultLong: Long): Long = try {
|
|
s.toLong()
|
|
} catch (e: NumberFormatException) {
|
|
defaultLong
|
|
}
|
|
}
|
|
|
|
private object WindowsMI : MI {
|
|
override fun getTotalMemory(): Long {
|
|
return 32 * GB // This is currently unsupported, but any implementations by Windows user using panama are welcome
|
|
}
|
|
}
|
|
|
|
private object MacOsMI : MI {
|
|
override fun getTotalMemory(): Long {
|
|
return 32 * GB // This is currently unsupported, but any implementations by MacOS user using panama are welcome
|
|
}
|
|
}
|
|
}
|