-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Konyaco/cache
[Code] Support for caching.
- Loading branch information
Showing
14 changed files
with
300 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
android/src/main/java/me/konyaco/collinsdictionary/MyApplication.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package me.konyaco.collinsdictionary | ||
|
||
import android.app.Application | ||
import me.konyaco.collinsdictionary.repository.Repository | ||
import me.konyaco.collinsdictionary.service.CollinsOnlineDictionary | ||
import me.konyaco.collinsdictionary.service.LocalCacheDictionary | ||
import me.konyaco.collinsdictionary.store.FileBasedLocalStorage | ||
|
||
class MyApplication : Application() { | ||
lateinit var repository: Repository | ||
|
||
override fun onCreate() { | ||
super.onCreate() | ||
repository = Repository( | ||
CollinsOnlineDictionary(), | ||
LocalCacheDictionary(FileBasedLocalStorage(filesDir.resolve("cache").also { | ||
if (!it.exists()) it.mkdir() | ||
})) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
common/src/androidMain/kotlin/me/konyaco/collinsdictionary/store/FileBasedLocalStorage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// This file is copied from jvmMain source. | ||
package me.konyaco.collinsdictionary.store | ||
|
||
import java.io.File | ||
|
||
class FileBasedLocalStorage( | ||
private val dir: File | ||
) : LocalStorage { | ||
private val searchDir = dir.resolve("search").also { it.mkdirIfNotExists() } | ||
private val definitionDir = dir.resolve("definition").also { it.mkdirIfNotExists() } | ||
|
||
override fun getSearch(word: String): String? { | ||
return searchDir.resolve(word).takeIf { it.exists() }?.readText() | ||
} | ||
|
||
override fun getDefinition(word: String): String? { | ||
return definitionDir.resolve(word).takeIf { it.exists() }?.readText() | ||
} | ||
|
||
override fun saveSearch(word: String, value: String) { | ||
searchDir.resolve(word).writeText(value) | ||
} | ||
|
||
override fun saveDefinition(word: String, value: String) { | ||
definitionDir.resolve(word).writeText(value) | ||
} | ||
|
||
override fun deleteSearch(word: String) { | ||
searchDir.resolve(word).deleteIfExists() | ||
} | ||
|
||
override fun deleteDefinition(word: String) { | ||
definitionDir.resolve(word).deleteIfExists() | ||
} | ||
} | ||
|
||
private fun File.deleteIfExists() { | ||
if (exists()) delete() | ||
} | ||
|
||
private fun File.mkdirIfNotExists() { | ||
if (!exists()) mkdir() | ||
} |
45 changes: 45 additions & 0 deletions
45
common/src/commonMain/kotlin/me/konyaco/collinsdictionary/repository/Repository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package me.konyaco.collinsdictionary.repository | ||
|
||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.flow | ||
import me.konyaco.collinsdictionary.service.CollinsOnlineDictionary | ||
import me.konyaco.collinsdictionary.service.LocalCacheDictionary | ||
import me.konyaco.collinsdictionary.service.SearchResult | ||
import me.konyaco.collinsdictionary.service.Word | ||
|
||
class Repository( | ||
private val onlineDictionary: CollinsOnlineDictionary, | ||
private val localCacheDictionary: LocalCacheDictionary | ||
) { | ||
data class Result<out T>( | ||
val source: Source, | ||
val data: T | ||
) { | ||
enum class Source { | ||
REMOTE, LOCAL | ||
} | ||
} | ||
|
||
fun search(word: String): Flow<Result<SearchResult>> = flow { | ||
val localResult = localCacheDictionary.search(word) | ||
when (localResult) { | ||
is SearchResult.PreciseWord -> emit(Result(Result.Source.LOCAL, localResult)) | ||
is SearchResult.Redirect -> emit(Result(Result.Source.LOCAL, localResult)) | ||
} | ||
val remoteResult = onlineDictionary.search(word) | ||
localCacheDictionary.cacheSearchResult(word, remoteResult) | ||
emit(Result(Result.Source.REMOTE, remoteResult)) | ||
} | ||
|
||
fun getDefinition(word: String): Flow<Result<Word?>> = flow { | ||
val localDefinition = localCacheDictionary.getDefinition(word) | ||
if (localDefinition != null) { | ||
emit(Result(Result.Source.LOCAL, localDefinition)) | ||
} | ||
val remoteDefinition = onlineDictionary.getDefinition(word) | ||
remoteDefinition?.let { | ||
localCacheDictionary.cacheDefinition(word, remoteDefinition) | ||
} | ||
emit(Result(Result.Source.REMOTE, remoteDefinition)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
common/src/commonMain/kotlin/me/konyaco/collinsdictionary/service/LocalCacheDictionary.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package me.konyaco.collinsdictionary.service | ||
|
||
import kotlinx.serialization.decodeFromString | ||
import kotlinx.serialization.encodeToString | ||
import kotlinx.serialization.json.Json | ||
import me.konyaco.collinsdictionary.store.LocalStorage | ||
|
||
class LocalCacheDictionary(private val localStorage: LocalStorage) : CollinsDictionary { | ||
private val json = Json { | ||
ignoreUnknownKeys = true | ||
prettyPrint = false | ||
} | ||
|
||
override fun search(word: String): SearchResult { | ||
return when (val text = localStorage.getSearch(word)) { | ||
null -> SearchResult.NotFound(emptyList()) | ||
word -> SearchResult.PreciseWord(word) | ||
else -> SearchResult.Redirect(text) | ||
} | ||
} | ||
|
||
override fun getDefinition(word: String): Word? { | ||
val text = localStorage.getDefinition(word) ?: return null | ||
return json.decodeFromString<Word>(text) | ||
} | ||
|
||
fun cacheSearchResult(word: String, searchResult: SearchResult) { | ||
when (searchResult) { | ||
is SearchResult.PreciseWord -> localStorage.saveSearch(word, word) | ||
is SearchResult.Redirect -> { | ||
localStorage.saveSearch(word, searchResult.redirectTo) | ||
localStorage.saveSearch(searchResult.redirectTo, searchResult.redirectTo) | ||
} | ||
is SearchResult.NotFound -> {} | ||
} | ||
} | ||
|
||
fun cacheDefinition(word: String, definition: Word) { | ||
localStorage.saveDefinition(word, json.encodeToString(definition)) | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
common/src/commonMain/kotlin/me/konyaco/collinsdictionary/store/LocalStorage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package me.konyaco.collinsdictionary.store | ||
|
||
interface LocalStorage { | ||
fun getSearch(word: String): String? | ||
fun getDefinition(word: String): String? | ||
fun saveSearch(word: String, value: String) | ||
fun saveDefinition(word: String, value: String) | ||
fun deleteSearch(word: String) | ||
fun deleteDefinition(word: String) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.