diff --git a/app/src/main/java/xyz/ksharma/krail/MainActivity.kt b/app/src/main/java/xyz/ksharma/krail/MainActivity.kt index 3ed572d6..7abbcc99 100644 --- a/app/src/main/java/xyz/ksharma/krail/MainActivity.kt +++ b/app/src/main/java/xyz/ksharma/krail/MainActivity.kt @@ -6,11 +6,18 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import timber.log.Timber import xyz.ksharma.krail.database.sydney.trains.database.api.SydneyTrainsStaticDB import xyz.ksharma.krail.design.system.theme.StartTheme +import xyz.ksharma.krail.model.sydneytrains.GTFSFeedFileNames +import xyz.ksharma.krail.sydney.trains.database.real.parser.StopTimesParser.parseStopTimes import xyz.ksharma.krail.sydney.trains.network.api.repository.SydneyTrainsRepository +import xyz.ksharma.krail.utils.toPath +import java.time.Instant +import java.time.temporal.ChronoUnit import javax.inject.Inject @AndroidEntryPoint @@ -33,8 +40,7 @@ class MainActivity : ComponentActivity() { repository.fetchStaticSydneyTrainsScheduleAndCache() - - /*val startTime = Instant.now() + val startTime = Instant.now() parseStopTimes( path = applicationContext.toPath(GTFSFeedFileNames.STOP_TIMES.fileName), ioDispatcher = Dispatchers.IO, @@ -46,7 +52,7 @@ class MainActivity : ComponentActivity() { Timber.d("Time taken - $diff") val dataSize = realSydneyTrainsStaticDb.stopTimesSize() - Timber.d("DATA SIZE: $dataSize")*/ + Timber.d("DATA SIZE: $dataSize") } setContent { diff --git a/feature/sydney-trains/database/api/src/main/kotlin/xyz/ksharma/krail/database/sydney/trains/database/api/ZipEntryCacheManager.kt b/feature/sydney-trains/database/api/src/main/kotlin/xyz/ksharma/krail/database/sydney/trains/database/api/ZipEntryCacheManager.kt index dc4a014b..4a4fe939 100644 --- a/feature/sydney-trains/database/api/src/main/kotlin/xyz/ksharma/krail/database/sydney/trains/database/api/ZipEntryCacheManager.kt +++ b/feature/sydney-trains/database/api/src/main/kotlin/xyz/ksharma/krail/database/sydney/trains/database/api/ZipEntryCacheManager.kt @@ -1,6 +1,5 @@ package xyz.ksharma.krail.database.sydney.trains.database.api -import java.io.IOException import okhttp3.Response interface ZipEntryCacheManager { @@ -11,10 +10,8 @@ interface ZipEntryCacheManager { * provided context. This function operates on a specified coroutine dispatcher for asynchronous * execution. * - * @throws IOException If an I/O error occurs during the caching process, - * or if the response code is unexpected. - * @param dispatcher The coroutine dispatcher to use for suspending operations. - * @param context The context that provides the cache directory path. + * @param response - The Okhttp [Response] from API, which contains the zip data. + * */ suspend fun cacheZipResponse(response: Response) } diff --git a/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/RealZipCacheManager.kt b/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/RealZipCacheManager.kt index 816908b2..590d14a5 100644 --- a/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/RealZipCacheManager.kt +++ b/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/RealZipCacheManager.kt @@ -3,17 +3,15 @@ package xyz.ksharma.krail.sydney.trains.database.real import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineDispatcher -import xyz.ksharma.krail.database.sydney.trains.database.api.ZipEntryCacheManager -import xyz.ksharma.krail.di.AppDispatchers -import xyz.ksharma.krail.di.Dispatcher -import java.io.IOException import okhttp3.Response import timber.log.Timber import xyz.ksharma.krail.coroutines.ext.safeResult -import xyz.ksharma.krail.database.sydney.trains.database.api.SydneyTrainsStaticDB -import xyz.ksharma.krail.model.sydneytrains.GTFSFeedFileNames +import xyz.ksharma.krail.database.sydney.trains.database.api.ZipEntryCacheManager +import xyz.ksharma.krail.di.AppDispatchers +import xyz.ksharma.krail.di.Dispatcher import xyz.ksharma.krail.utils.toPath import java.io.File +import java.io.IOException import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardCopyOption @@ -25,7 +23,6 @@ import javax.inject.Singleton class RealZipCacheManager @Inject constructor( @Dispatcher(AppDispatchers.IO) val ioDispatcher: CoroutineDispatcher, @ApplicationContext val context: Context, -// val sydneyTrainsStaticDB : SydneyTrainsStaticDB ) : ZipEntryCacheManager { override suspend fun cacheZipResponse(response: Response) = safeResult(ioDispatcher) { @@ -44,9 +41,6 @@ class RealZipCacheManager @Inject constructor( val isDirectory = zipEntry.name.endsWith(File.separator) val path: Path = context.toPath(zipEntry.name) - /*if (zipEntry.name == GTFSFeedFileNames.STOP_TIMES.fileName) { - sydneyTrainsStaticDB.insertStopTimes() - }*/ inputStream.writeToCache(isDirectory, path) zipEntry = inputStream.nextEntry diff --git a/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/parser/StopTimesParser.kt b/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/parser/StopTimesParser.kt index 60e7cab1..e4289fef 100644 --- a/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/parser/StopTimesParser.kt +++ b/feature/sydney-trains/database/real/src/main/kotlin/xyz/ksharma/krail/sydney/trains/database/real/parser/StopTimesParser.kt @@ -20,53 +20,47 @@ object StopTimesParser { path: Path, ioDispatcher: CoroutineDispatcher, db: SydneyTrainsStaticDB, - ) = withContext(ioDispatcher) { - try { - BufferedReader(FileReader(path.toString())).use { reader -> - val headersList = reader.readLine().split(",").trimQuotes() - Timber.d("headersList: $headersList") + ): Unit = withContext(ioDispatcher) { + runCatching { + BufferedReader(FileReader(path.toString())).use { reader -> - val stopTimesList = mutableListOf() + val headersList = reader.readLine().split(",").trimQuotes() + Timber.d("headersList: $headersList") + val stopTimesList = mutableListOf() + var line: String? + val transactionBatchSize = 5_000 - var line: String? - while (true) { - line = reader.readLine() ?: break + while (true) { + line = reader.readLine() ?: break - val fieldsList = line.split(",").trimQuotes() + val fieldsList = line.split(",").trimQuotes() - stopTimesList.add( - StopTimes( - trip_id = fieldsList[0], - arrival_time = fieldsList[1], - departure_time = fieldsList[2], - stop_id = fieldsList[3], - stop_sequence = fieldsList[4].toLong(), - stop_headsign = fieldsList[5], - pickup_type = fieldsList[6].toLong(), - drop_off_type = fieldsList[7].toLong(), - ) + stopTimesList.add( + StopTimes( + trip_id = fieldsList[0], + arrival_time = fieldsList[1], + departure_time = fieldsList[2], + stop_id = fieldsList[3], + stop_sequence = fieldsList[4].toLong(), + stop_headsign = fieldsList[5], + pickup_type = fieldsList[6].toLong(), + drop_off_type = fieldsList[7].toLong(), ) + ) - // Insert in batches to improve performance - if (stopTimesList.size == 5_000) { - // Timber.d("insert 100 stop times") - db.insertStopTimesBatch(stopTimesList) - stopTimesList.clear() // Clear the batch - } - } - - // Insert any remaining stop times - if (stopTimesList.isNotEmpty()) { -// Timber.d("insert last left stop times") + // Insert in batches to improve performance + if (stopTimesList.size == transactionBatchSize) { + // Timber.d("insert $transactionBatchSize stop times") db.insertStopTimesBatch(stopTimesList) + stopTimesList.clear() // Clear the batch } } - } catch (e: IOException) { - e.printStackTrace() - Timber.e(e, "readStopsFromCSV: ") - } catch (e: IllegalArgumentException) { - e.printStackTrace() - Timber.e(e, "readStopsFromCSV: ") + + // Insert any remaining stop times + if (stopTimesList.isNotEmpty()) { + db.insertStopTimesBatch(stopTimesList) + } } - } + }.getOrElse { e -> Timber.e(e, "Error while parsing stop times") } + } }