src: add an in-memory map to cache db posts

Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
Aditya Wasan 2021-01-31 15:42:39 +05:30
parent d4ecf97436
commit a2c058877a
No known key found for this signature in database
GPG key ID: 6D6DF3BF15DE79B5
3 changed files with 39 additions and 29 deletions

View file

@ -2,35 +2,56 @@ package dev.msfjarvis.lobsters.data.repo
import dev.msfjarvis.lobsters.data.local.LobstersPost import dev.msfjarvis.lobsters.data.local.LobstersPost
import dev.msfjarvis.lobsters.database.LobstersDatabase import dev.msfjarvis.lobsters.database.LobstersDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import javax.inject.Inject import javax.inject.Inject
class LobstersRepository @Inject constructor(private val lobstersDatabase: LobstersDatabase) { class LobstersRepository @Inject constructor(private val lobstersDatabase: LobstersDatabase) {
private val savedPostsCache: MutableMap<String, LobstersPost> = mutableMapOf()
private val coroutineScope = CoroutineScope(Job() + Dispatchers.IO)
init {
coroutineScope.launch {
getAllPosts().forEach {
savedPostsCache.putIfAbsent(it.short_id, it)
}
}
}
fun isPostSaved(postId: String): Boolean { fun isPostSaved(postId: String): Boolean {
val post = lobstersDatabase.postQueries.isPostSaved(postId).executeAsOneOrNull() return savedPostsCache.containsKey(postId)
return post != null
} }
suspend fun getPost(postId: String): LobstersPost? = withContext(Dispatchers.IO) { fun getPostFromCache(postId: String): LobstersPost? {
return savedPostsCache[postId]
}
fun getAllPostsFromCache(): List<LobstersPost> {
return savedPostsCache.values.toList()
}
private suspend fun getPost(postId: String): LobstersPost? = withContext(Dispatchers.IO) {
return@withContext lobstersDatabase.postQueries.selectPost(postId).executeAsOneOrNull() return@withContext lobstersDatabase.postQueries.selectPost(postId).executeAsOneOrNull()
} }
suspend fun getSavedPosts(): List<LobstersPost> = withContext(Dispatchers.IO) { private suspend fun getAllPosts(): List<LobstersPost> = withContext(Dispatchers.IO) {
return@withContext lobstersDatabase.postQueries.selectSavedPosts().executeAsList() return@withContext lobstersDatabase.postQueries.selectAllPosts().executeAsList()
} }
suspend fun addPostToDB(post: LobstersPost) = withContext(Dispatchers.IO) { suspend fun addPost(post: LobstersPost) = withContext(Dispatchers.IO) {
lobstersDatabase.postQueries.insertOrReplacePost(post) if (!savedPostsCache.containsKey(post.short_id)) {
} savedPostsCache.putIfAbsent(post.short_id, post)
suspend fun savePost(post: LobstersPost) = withContext(Dispatchers.IO) {
lobstersDatabase.postQueries.insertOrReplacePost(post.copy(is_saved = true)) lobstersDatabase.postQueries.insertOrReplacePost(post.copy(is_saved = true))
}
} }
suspend fun removeSavedPost(post: LobstersPost) = withContext(Dispatchers.IO) { suspend fun removePost(post: LobstersPost) = withContext(Dispatchers.IO) {
if (isPostSaved(post.short_id)) { if (savedPostsCache.containsKey(post.short_id)) {
savedPostsCache.remove(post.short_id)
lobstersDatabase.postQueries.removeSavedPost(post.short_id) lobstersDatabase.postQueries.removeSavedPost(post.short_id)
} }
} }

View file

@ -64,8 +64,6 @@ fun LobstersApp() {
val savedPosts by viewModel.savedPosts.collectAsState() val savedPosts by viewModel.savedPosts.collectAsState()
val hottestPostsListState = rememberLazyListState() val hottestPostsListState = rememberLazyListState()
viewModel.getSavedPosts()
Scaffold( Scaffold(
bottomBar = { bottomBar = {
LobstersBottomNav( LobstersBottomNav(

View file

@ -17,12 +17,11 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class LobstersViewModel @Inject constructor( class LobstersViewModel @Inject constructor(
private val pagingSource: LobstersPagingSource,
private val lobstersRepository: LobstersRepository, private val lobstersRepository: LobstersRepository,
private val lobstersApi: LobstersApi, private val lobstersApi: LobstersApi,
) : ViewModel() { ) : ViewModel() {
private val _savedPosts = MutableStateFlow<List<LobstersPost>>(emptyList())
private lateinit var source: LobstersPagingSource private lateinit var source: LobstersPagingSource
private val _savedPosts = MutableStateFlow(lobstersRepository.getAllPostsFromCache())
val savedPosts = _savedPosts.asStateFlow() val savedPosts = _savedPosts.asStateFlow()
val posts = Pager(PagingConfig(25)) { val posts = Pager(PagingConfig(25)) {
source = LobstersPagingSource(lobstersApi, lobstersRepository) source = LobstersPagingSource(lobstersApi, lobstersRepository)
@ -37,29 +36,21 @@ class LobstersViewModel @Inject constructor(
} }
} }
fun getSavedPosts() { private fun invalidateSource() {
viewModelScope.launch {
lobstersRepository.getSavedPosts().forEach {
_savedPosts.value = _savedPosts.value + it
}
}
}
fun invalidateSource() {
source.invalidate() source.invalidate()
} }
private fun savePost(post: LobstersPost) { private fun savePost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
lobstersRepository.savePost(post) lobstersRepository.addPost(post)
_savedPosts.value = _savedPosts.value + post.copy(is_saved = true) _savedPosts.value = lobstersRepository.getAllPostsFromCache()
} }
} }
private fun removeSavedPost(post: LobstersPost) { private fun removeSavedPost(post: LobstersPost) {
viewModelScope.launch { viewModelScope.launch {
lobstersRepository.removeSavedPost(post) lobstersRepository.removePost(post)
_savedPosts.value = _savedPosts.value - post.copy(is_saved = true) _savedPosts.value = lobstersRepository.getAllPostsFromCache()
} }
} }
} }