ModelCache.kt 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* _____ _
  2. * |_ _| |_ _ _ ___ ___ _ __ __ _
  3. * | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. * |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. *
  6. * Threema for Android
  7. * Copyright (c) 2024 Threema GmbH
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. package ch.threema.data
  22. import ch.threema.data.models.BaseModel
  23. import ch.threema.data.models.ContactModel
  24. import ch.threema.data.models.EditHistoryListModel
  25. import ch.threema.data.models.EmojiReactionsModel
  26. import ch.threema.data.models.GroupIdentity
  27. import ch.threema.data.models.GroupModel
  28. import ch.threema.data.repositories.EmojiReactionsRepository
  29. /**
  30. * The model cache holds a [ModelTypeCache] for every model type.
  31. *
  32. * Note: This class should be initialized only once in the application
  33. * (except for use cases like testing).
  34. */
  35. class ModelCache {
  36. // Contacts are identified by their identity
  37. val contacts = ModelTypeCache<String, ContactModel>()
  38. // Groups are identified by their group identity (creator identity and group id)
  39. val groups = ModelTypeCache<GroupIdentity, GroupModel>()
  40. // Edit history entries are identified by their reference to a message's uid
  41. val editHistory = ModelTypeCache<String, EditHistoryListModel>()
  42. // Emoji reactions are uniquely identified by a composition of the message's id (int) and type
  43. val emojiReaction = ModelTypeCache<EmojiReactionsRepository.ReactionMessageIdentifier, EmojiReactionsModel>()
  44. }
  45. /**
  46. * The model type cache holds models of a certain type. It ensures that every model
  47. * is instantiated only once.
  48. *
  49. * Internally, it uses a [WeakValueMap], so the values are not prevented from being
  50. * garbage collected by the cache.
  51. */
  52. class ModelTypeCache<TIdentifier, TModel : BaseModel<*, *>> {
  53. private val map = WeakValueMap<TIdentifier, TModel>()
  54. /**
  55. * Return the cached model with the specified [identifier].
  56. */
  57. fun get(identifier: TIdentifier): TModel? = this.map.get(identifier)
  58. /**
  59. * Return the cached model with the specified [identifier].
  60. *
  61. * If it cannot be found, create the model using the [miss] function, cache it
  62. * and return it.
  63. */
  64. fun getOrCreate(identifier: TIdentifier, miss: () -> TModel?): TModel? = this.map.getOrCreate(identifier, miss)
  65. /**
  66. * Remove the model with the specified [identifier] from the cache and return it.
  67. */
  68. fun remove(identifier: TIdentifier): TModel? = this.map.remove(identifier)
  69. }