mirror of
https://github.com/ProtonMail/ios-mail.git
synced 2026-06-14 09:54:45 +00:00
63 lines
2.1 KiB
Swift
63 lines
2.1 KiB
Swift
// Copyright (c) 2024 Proton Technologies AG
|
|
//
|
|
// This file is part of Proton Mail.
|
|
//
|
|
// Proton Mail is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Proton Mail is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
|
|
|
import InboxCore
|
|
import SwiftUI
|
|
|
|
/// Keeps `maxElements` in memory. When the limit is reached evicts from the cache the oldest element
|
|
final class MemoryCache<Key: Hashable & Sendable, Value: Sendable>: @unchecked Sendable {
|
|
private let maxElements: Int
|
|
private var dictionary = [Key: Value]()
|
|
private var fifoQueue = [Key]()
|
|
|
|
private let queue = DispatchQueue(label: "\(Bundle.defaultIdentifier).MemoryCache", attributes: .concurrent)
|
|
|
|
init(maxElements: Int = 30) {
|
|
self.maxElements = maxElements
|
|
}
|
|
|
|
func object(for key: Key) -> Value? {
|
|
var result: Value?
|
|
queue.sync {
|
|
result = dictionary[key]
|
|
if result != nil {
|
|
rearrangeFifoQueue(for: key)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func setObject(_ object: Value, for key: Key) {
|
|
queue.async(flags: .barrier) {
|
|
self.dictionary[key] = object
|
|
self.rearrangeFifoQueue(for: key)
|
|
if self.dictionary.count > self.maxElements {
|
|
let lastKey = self.fifoQueue.removeLast()
|
|
self.dictionary[lastKey] = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// Private helper method to rearrange the FIFO queue
|
|
private func rearrangeFifoQueue(for key: Key) {
|
|
if let index = fifoQueue.firstIndex(of: key) {
|
|
fifoQueue.remove(at: index)
|
|
}
|
|
fifoQueue.insert(key, at: 0)
|
|
}
|
|
}
|