Further improvements and updated the memory allocation avoiding code

This commit is contained in:
ThomasSession 2024-08-20 13:58:06 +10:00
parent 7a209a852c
commit 4383158634

View File

@ -5,13 +5,15 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.localbroadcastmanager.content.LocalBroadcastManager
import org.session.libsignal.utilities.Log
import com.opencsv.CSVReader import com.opencsv.CSVReader
import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.snode.OnionRequestAPI
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.ThreadUtils import org.session.libsignal.utilities.ThreadUtils
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.FileReader import java.io.FileReader
import java.util.SortedMap
import java.util.TreeMap
class IP2Country private constructor(private val context: Context) { class IP2Country private constructor(private val context: Context) {
private val pathsBuiltEventReceiver: BroadcastReceiver private val pathsBuiltEventReceiver: BroadcastReceiver
@ -24,7 +26,7 @@ class IP2Country private constructor(private val context: Context) {
for (char in ip) { for (char in ip) {
if (char == '.' || char == '/') { if (char == '.' || char == '/') {
result = (result shl 8) or currentValue result = result or (currentValue shl (8 * (3 - octetIndex)))
currentValue = 0 currentValue = 0
octetIndex++ octetIndex++
if (char == '/') break if (char == '/') break
@ -34,33 +36,41 @@ class IP2Country private constructor(private val context: Context) {
} }
// Handle the last octet // Handle the last octet
result = (result shl 8) or currentValue result = result or (currentValue shl (8 * (3 - octetIndex)))
return result return result
} }
private val ipv4ToCountry by lazy { private val ipv4ToCountry: TreeMap<Long, Int?> by lazy {
val file = loadFile("geolite2_country_blocks_ipv4.csv") val file = loadFile("geolite2_country_blocks_ipv4.csv")
val csv = CSVReader(FileReader(file.absoluteFile)).apply { val csv = CSVReader(FileReader(file.absoluteFile)).apply {
skip(1) skip(1)
} }
csv.readAll() val ipCountries = csv.asSequence().associateTo(TreeMap()) { cols ->
.associate { cols -> Ipv4Int(cols[0]) to cols[1].toIntOrNull()
Ipv4Int(cols[0]) to cols[1].toIntOrNull() }
}
csv.close()
ipCountries
} }
private val countryToNames by lazy { private val countryToNames: Map<Int, String> by lazy {
val file = loadFile("geolite2_country_locations_english.csv") val file = loadFile("geolite2_country_locations_english.csv")
val csv = CSVReader(FileReader(file.absoluteFile)).apply { val csv = CSVReader(FileReader(file.absoluteFile)).apply {
skip(1) skip(1)
} }
csv.readAll()
.filter { cols -> !cols[0].isNullOrEmpty() && !cols[1].isNullOrEmpty() } val names = csv.asSequence()
.associate { cols -> .filter { cols -> !cols[0].isNullOrEmpty() && !cols[1].isNullOrEmpty() }
cols[0].toInt() to cols[5] .associate { cols ->
} cols[0].toInt() to cols[5]
}
csv.close()
names
} }
// region Initialization // region Initialization
@ -112,10 +122,8 @@ class IP2Country private constructor(private val context: Context) {
// return early if cached // return early if cached
countryNamesCache[ip]?.let { return it } countryNamesCache[ip]?.let { return it }
val comps = ipv4ToCountry.asSequence()
val ipInt = Ipv4Int(ip) val ipInt = Ipv4Int(ip)
val bestMatchCountry = comps.lastOrNull { it.key <= ipInt }?.let { (_, code) -> val bestMatchCountry = ipv4ToCountry.floorEntry(ipInt)?.let { (_, code) ->
if (code != null) { if (code != null) {
countryToNames[code] countryToNames[code]
} else { } else {
@ -145,3 +153,4 @@ class IP2Country private constructor(private val context: Context) {
} }
// endregion // endregion
} }