Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to kotlinx-datetime #4471

Merged
merged 9 commits into from
Oct 18, 2022
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinxCoroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinxCoroutinesVersion")

// Date/time
api("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")

// scheduling background jobs
implementation("androidx.work:work-runtime:2.7.1")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.westnordost.streetcomplete.data.download.tiles

import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
Expand All @@ -24,15 +25,15 @@ class DownloadedTilesDaoTest : ApplicationDbTestCase() {

@Test fun putGetOld() {
dao.put(r(5, 8, 5, 8), "Huhu")
val huhus = dao.get(r(5, 8, 5, 8), System.currentTimeMillis() + 1000)
val huhus = dao.get(r(5, 8, 5, 8), nowAsEpochMilliseconds() + 1000)
assertTrue(huhus.isEmpty())
}

@Test fun putSomeOld() {
dao.put(r(0, 0, 1, 3), "Huhu")
Thread.sleep(2000)
dao.put(r(1, 3, 5, 5), "Huhu")
val huhus = dao.get(r(0, 0, 2, 2), System.currentTimeMillis() - 1000)
val huhus = dao.get(r(0, 0, 2, 2), nowAsEpochMilliseconds() - 1000)
assertTrue(huhus.isEmpty())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package de.westnordost.streetcomplete.data.osm.mapdata

import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import java.lang.System.currentTimeMillis

class NodeDaoTest : ApplicationDbTestCase() {
private lateinit var dao: NodeDao
Expand Down Expand Up @@ -76,13 +76,13 @@ class NodeDaoTest : ApplicationDbTestCase() {

@Test fun getUnusedAndOldIds() {
dao.putAll(listOf(nd(1L), nd(2L), nd(3L)))
val unusedIds = dao.getIdsOlderThan(currentTimeMillis() + 10)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10)
assertTrue(unusedIds.containsExactlyInAnyOrder(listOf(1L, 2L, 3L)))
}

@Test fun getUnusedAndOldIdsButAtMostX() {
dao.putAll(listOf(nd(1L), nd(2L), nd(3L)))
val unusedIds = dao.getIdsOlderThan(currentTimeMillis() + 10, 2)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10, 2)
assertEquals(2, unusedIds.size)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import de.westnordost.streetcomplete.data.osm.mapdata.ElementType.NODE
import de.westnordost.streetcomplete.data.osm.mapdata.ElementType.RELATION
import de.westnordost.streetcomplete.data.osm.mapdata.ElementType.WAY
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
Expand Down Expand Up @@ -148,13 +149,13 @@ class RelationDaoTest : ApplicationDbTestCase() {

@Test fun getUnusedAndOldIds() {
dao.putAll(listOf(rel(1L), rel(2L), rel(3L)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10)
assertTrue(unusedIds.containsExactlyInAnyOrder(listOf(1L, 2L, 3L)))
}

@Test fun getUnusedAndOldIdsButAtMostX() {
dao.putAll(listOf(rel(1L), rel(2L), rel(3L)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10, 2)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10, 2)
assertEquals(2, unusedIds.size)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.westnordost.streetcomplete.data.osm.mapdata

import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
Expand Down Expand Up @@ -103,13 +104,13 @@ class WayDaoTest : ApplicationDbTestCase() {

@Test fun getUnusedAndOldIds() {
dao.putAll(listOf(way(1L), way(2L), way(3L)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10)
assertTrue(unusedIds.containsExactlyInAnyOrder(listOf(1L, 2L, 3L)))
}

@Test fun getUnusedAndOldIdsButAtMostX() {
dao.putAll(listOf(way(1L), way(2L), way(3L)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10, 2)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10, 2)
assertEquals(2, unusedIds.size)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.data.osm.mapdata.ElementType
import de.westnordost.streetcomplete.data.quest.OsmQuestKey
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
Expand Down Expand Up @@ -44,7 +45,7 @@ class OsmQuestsHiddenDaoTest : ApplicationDbTestCase() {
)
dao.add(keys[0])
delay(200)
val time = System.currentTimeMillis()
val time = nowAsEpochMilliseconds()
dao.add(keys[1])
val result = dao.getNewerThan(time - 100).single()
assertEquals(keys[1], result.osmQuestKey)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import de.westnordost.streetcomplete.data.osm.mapdata.BoundingBox
import de.westnordost.streetcomplete.data.osm.mapdata.LatLon
import de.westnordost.streetcomplete.data.user.User
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
Expand Down Expand Up @@ -101,13 +102,13 @@ class NoteDaoTest : ApplicationDbTestCase() {

@Test fun getUnusedAndOldIds() {
dao.putAll(listOf(createNote(1), createNote(2), createNote(3)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10)
assertTrue(unusedIds.containsExactlyInAnyOrder(listOf(1L, 2L, 3L)))
}

@Test fun getUnusedAndOldIdsButAtMostX() {
dao.putAll(listOf(createNote(1), createNote(2), createNote(3)))
val unusedIds = dao.getIdsOlderThan(System.currentTimeMillis() + 10, 2)
val unusedIds = dao.getIdsOlderThan(nowAsEpochMilliseconds() + 10, 2)
assertEquals(2, unusedIds.size)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package de.westnordost.streetcomplete.data.osmnotes.notequests

import de.westnordost.streetcomplete.data.ApplicationDbTestCase
import de.westnordost.streetcomplete.util.ktx.containsExactlyInAnyOrder
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
Expand Down Expand Up @@ -42,7 +43,7 @@ class NoteQuestsHiddenDaoTest : ApplicationDbTestCase() {
@Test fun getNewerThan() = runBlocking {
dao.add(1L)
delay(200)
val time = System.currentTimeMillis()
val time = nowAsEpochMilliseconds()
dao.add(2L)
val result = dao.getNewerThan(time - 100).single()
assertEquals(2L, result.noteId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import de.westnordost.streetcomplete.util.CrashReportExceptionHandler
import de.westnordost.streetcomplete.util.getSelectedLocale
import de.westnordost.streetcomplete.util.getSystemLocales
import de.westnordost.streetcomplete.util.ktx.addedToFront
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import de.westnordost.streetcomplete.util.setDefaultLocales
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
Expand All @@ -58,7 +59,6 @@ import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.workmanager.koin.workManagerFactory
import org.koin.core.context.startKoin
import java.lang.System.currentTimeMillis
import java.util.concurrent.TimeUnit

class StreetCompleteApplication : Application() {
Expand Down Expand Up @@ -131,7 +131,7 @@ class StreetCompleteApplication : Application() {

applicationScope.launch {
preloader.preload()
editHistoryController.deleteSyncedOlderThan(currentTimeMillis() - ApplicationConstants.MAX_UNDO_HISTORY_AGE)
editHistoryController.deleteSyncedOlderThan(nowAsEpochMilliseconds() - ApplicationConstants.MAX_UNDO_HISTORY_AGE)
}

enqueuePeriodicCleanupWork()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import de.westnordost.streetcomplete.data.osm.mapdata.MapDataController
import de.westnordost.streetcomplete.data.osmnotes.NoteController
import de.westnordost.streetcomplete.data.quest.QuestTypeRegistry
import de.westnordost.streetcomplete.util.ktx.format
import java.lang.System.currentTimeMillis
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds

/** Deletes old unused data in the background */
class Cleaner(
Expand All @@ -15,15 +15,15 @@ class Cleaner(
private val questTypeRegistry: QuestTypeRegistry
) {
fun clean() {
val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()

val oldDataTimestamp = currentTimeMillis() - ApplicationConstants.DELETE_OLD_DATA_AFTER
val oldDataTimestamp = nowAsEpochMilliseconds() - ApplicationConstants.DELETE_OLD_DATA_AFTER
noteController.deleteOlderThan(oldDataTimestamp, MAX_DELETE_ELEMENTS)
mapDataController.deleteOlderThan(oldDataTimestamp, MAX_DELETE_ELEMENTS)
/* do this after cleaning map data and notes, because some metadata rely on map data */
questTypeRegistry.forEach { it.deleteMetadataOlderThan(oldDataTimestamp) }

Log.i(TAG, "Cleaning took ${((currentTimeMillis() - time) / 1000.0).format(1)}s")
Log.i(TAG, "Cleaning took ${((nowAsEpochMilliseconds() - time) / 1000.0).format(1)}s")
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import android.util.Log
import de.westnordost.countryboundaries.CountryBoundaries
import de.westnordost.osmfeatures.FeatureDictionary
import de.westnordost.streetcomplete.util.ktx.format
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.System.currentTimeMillis
import java.util.concurrent.FutureTask

/** Initialize certain singleton classes used elsewhere throughout the app in the background */
Expand All @@ -18,7 +18,7 @@ class Preloader(
) {

suspend fun preload() {
val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()
coroutineScope {
// country boundaries are necessary latest for when a quest is opened or on a download
launch { preloadCountryBoundaries() }
Expand All @@ -27,20 +27,20 @@ class Preloader(
launch { preloadFeatureDictionary() }
}

Log.i(TAG, "Preloading data took ${((currentTimeMillis() - time) / 1000.0).format(1)}s")
Log.i(TAG, "Preloading data took ${((nowAsEpochMilliseconds() - time) / 1000.0).format(1)}s")
}

private suspend fun preloadFeatureDictionary() = withContext(Dispatchers.IO) {
val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()
featuresDictionaryFuture.run()
val seconds = (currentTimeMillis() - time) / 1000.0
val seconds = (nowAsEpochMilliseconds() - time) / 1000.0
Log.i(TAG, "Loaded features dictionary in ${seconds.format(1)}s")
}

private suspend fun preloadCountryBoundaries() = withContext(Dispatchers.IO) {
val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()
countryBoundariesFuture.run()
val seconds = (currentTimeMillis() - time) / 1000.0
val seconds = (nowAsEpochMilliseconds() - time) / 1000.0
Log.i(TAG, "Loaded country boundaries in ${seconds.format(1)}s")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import de.westnordost.streetcomplete.data.maptiles.MapTilesDownloader
import de.westnordost.streetcomplete.data.osm.mapdata.MapDataDownloader
import de.westnordost.streetcomplete.data.osmnotes.NotesDownloader
import de.westnordost.streetcomplete.util.ktx.format
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import de.westnordost.streetcomplete.util.math.area
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.lang.System.currentTimeMillis
import kotlin.math.max

/** Downloads all the things */
Expand All @@ -36,7 +36,7 @@ class Downloader(
}
Log.i(TAG, "Starting download ($sqkm km², bbox: $bboxString)")

val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()

mutex.withLock {
coroutineScope {
Expand All @@ -48,13 +48,13 @@ class Downloader(
}
putDownloadedAlready(tiles)

val seconds = (currentTimeMillis() - time) / 1000.0
val seconds = (nowAsEpochMilliseconds() - time) / 1000.0
Log.i(TAG, "Finished download ($sqkm km², bbox: $bboxString) in ${seconds.format(1)}s")
}

private fun hasDownloadedAlready(tiles: TilesRect): Boolean {
val freshTime = ApplicationConstants.REFRESH_DATA_AFTER
val ignoreOlderThan = max(0, currentTimeMillis() - freshTime)
val ignoreOlderThan = max(0, nowAsEpochMilliseconds() - freshTime)
return downloadedTilesDb.get(tiles, ignoreOlderThan).contains(DownloadedTilesType.ALL)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import de.westnordost.streetcomplete.data.download.tiles.enclosingTilesRect
import de.westnordost.streetcomplete.data.osm.mapdata.BoundingBox
import de.westnordost.streetcomplete.data.osm.mapdata.LatLon
import de.westnordost.streetcomplete.data.osm.mapdata.MapDataController
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import de.westnordost.streetcomplete.util.math.area
import de.westnordost.streetcomplete.util.math.enclosingBoundingBox
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -79,7 +80,7 @@ abstract class AVariableRadiusStrategy(
/** return if data in the given tiles rect that hasn't been downloaded yet */
private suspend fun hasMissingDataFor(tilesRect: TilesRect): Boolean {
val dataExpirationTime = ApplicationConstants.REFRESH_DATA_AFTER
val ignoreOlderThan = max(0, System.currentTimeMillis() - dataExpirationTime)
val ignoreOlderThan = max(0, nowAsEpochMilliseconds() - dataExpirationTime)
val downloadedTiles =
withContext(Dispatchers.IO) { downloadedTilesDao.get(tilesRect, ignoreOlderThan) }
return !downloadedTiles.contains(DownloadedTilesType.ALL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import de.westnordost.streetcomplete.data.download.tiles.DownloadedTilesTable.Co
import de.westnordost.streetcomplete.data.download.tiles.DownloadedTilesTable.Columns.X
import de.westnordost.streetcomplete.data.download.tiles.DownloadedTilesTable.Columns.Y
import de.westnordost.streetcomplete.data.download.tiles.DownloadedTilesTable.NAME
import java.lang.System.currentTimeMillis
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds

/** Keeps info in which areas things have been downloaded already in a tile grid */
class DownloadedTilesDao(private val db: Database) {

/** Persist that the given type has been downloaded in every tile in the given tile range */
fun put(tilesRect: TilesRect, typeName: String) {
val time = currentTimeMillis()
val time = nowAsEpochMilliseconds()
db.replaceMany(NAME,
arrayOf(X, Y, TYPE, DATE),
tilesRect.asTilePosSequence().map { arrayOf<Any?>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import de.westnordost.streetcomplete.data.osmnotes.edits.NoteEditsController
import de.westnordost.streetcomplete.data.osmnotes.edits.NoteEditsSource
import de.westnordost.streetcomplete.data.osmnotes.notequests.OsmNoteQuestController
import de.westnordost.streetcomplete.data.osmnotes.notequests.OsmNoteQuestHidden
import java.lang.System.currentTimeMillis
import de.westnordost.streetcomplete.util.ktx.nowAsEpochMilliseconds
import java.util.concurrent.CopyOnWriteArrayList

/** All edits done by the user in one place: Edits made on notes, on map data, hidings of quests */
Expand Down Expand Up @@ -88,7 +88,7 @@ class EditHistoryController(
getAll().firstOrNull { it.isUndoable }

override fun getAll(): List<Edit> {
val maxAge = currentTimeMillis() - MAX_UNDO_HISTORY_AGE
val maxAge = nowAsEpochMilliseconds() - MAX_UNDO_HISTORY_AGE

val result = ArrayList<Edit>()
result += elementEditsController.getAll().filter { it.action !is IsRevertAction }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import de.westnordost.streetcomplete.data.osm.mapdata.Element
import de.westnordost.streetcomplete.osm.getLastCheckDateKeys
import de.westnordost.streetcomplete.osm.toCheckDate
import de.westnordost.streetcomplete.util.ktx.toLocalDate
import java.time.Instant
import java.time.LocalDate
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate

sealed interface ElementFilter : Matcher<Element> {
abstract override fun toString(): String
Expand Down Expand Up @@ -132,7 +132,7 @@ class TagNewerThan(key: String, dateFilter: DateFilter) : CompareTagAge(key, dat
abstract class CompareTagAge(val key: String, val dateFilter: DateFilter) : ElementFilter {
abstract fun compareTo(tagValue: LocalDate): Boolean
override fun matches(obj: Element): Boolean {
if (compareTo(Instant.ofEpochMilli(obj.timestampEdited).toLocalDate())) return true
if (compareTo(Instant.fromEpochMilliseconds(obj.timestampEdited).toLocalDate())) return true
return getLastCheckDateKeys(key)
.mapNotNull { obj.tags[it]?.toCheckDate() }
.any { compareTo(it) }
Expand All @@ -150,7 +150,7 @@ class ElementNewerThan(dateFilter: DateFilter) : CompareElementAge(dateFilter) {

abstract class CompareElementAge(val dateFilter: DateFilter) : ElementFilter {
abstract fun compareTo(tagValue: LocalDate): Boolean
override fun matches(obj: Element) = compareTo(Instant.ofEpochMilli(obj.timestampEdited).toLocalDate())
override fun matches(obj: Element) = compareTo(Instant.fromEpochMilliseconds(obj.timestampEdited).toLocalDate())
}

class CombineFilters(vararg val filters: ElementFilter) : ElementFilter {
Expand Down
Loading