Merge pull request #989 from kiwix/remove-ordered-dependency

Remove OrderedCollections dependency
This commit is contained in:
Kelson 2024-09-27 09:09:55 +00:00 committed by GitHub
commit b0db47c59b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 132 additions and 15 deletions

View File

@ -0,0 +1,63 @@
// This file is part of Kiwix for iOS & macOS.
//
// Kiwix 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
// any later version.
//
// Kiwix 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 Kiwix; If not, see https://www.gnu.org/licenses/.
import XCTest
@testable import Kiwix
final class OrderedCacheTests: XCTestCase {
@MainActor
func testEmpty() {
let cache = OrderedCache<String, String>()
XCTAssertEqual(cache.count, 0)
XCTAssertNil(cache.findBy(key: "not to be found"))
}
@MainActor
func testOneItem() {
let cache = OrderedCache<String, String>()
let pastDate = Date.distantPast
cache.setValue("test_value", forKey: "keyOne", dated: pastDate)
XCTAssertEqual(cache.count, 1)
XCTAssertNil(cache.findBy(key: "not to be found"))
XCTAssertEqual(cache.findBy(key: "keyOne"), "test_value")
cache.removeOlderThan(pastDate)
XCTAssertEqual(cache.count, 1)
cache.removeOlderThan(Date.now)
XCTAssertEqual(cache.count, 0)
}
@MainActor
func testRemoveOlderThan() {
let cache = OrderedCache<String, String>()
let nowDate = Date.now
cache.setValue("test_value", forKey: "keyOne", dated: nowDate)
cache.setValue("old_value", forKey: "keyOld", dated: Date.distantPast)
XCTAssertEqual(cache.count, 2)
cache.removeOlderThan(nowDate.advanced(by: -1))
XCTAssertEqual(cache.count, 1)
}
@MainActor
func testRemoveByKey() {
let cache = OrderedCache<String, Int>()
cache.setValue(1, forKey: "one")
cache.setValue(0, forKey: "zero")
cache.removeValue(forKey: "zero")
XCTAssertNil(cache.findBy(key: "zero"))
XCTAssertEqual(cache.findBy(key: "one"), 1)
}
}

View File

@ -19,8 +19,6 @@ import CoreLocation
import WebKit
import Defaults
import os
import OrderedCollections
import CoreKiwix
// swiftlint:disable file_length
@ -28,23 +26,27 @@ import CoreKiwix
final class BrowserViewModel: NSObject, ObservableObject,
WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate,
NSFetchedResultsControllerDelegate {
private static var cache = OrderedDictionary<NSManagedObjectID, BrowserViewModel>()
@MainActor
private static var cache: OrderedCache<NSManagedObjectID, BrowserViewModel>?
@MainActor
static func getCached(tabID: NSManagedObjectID) -> BrowserViewModel {
let viewModel = cache[tabID] ?? BrowserViewModel(tabID: tabID)
cache.removeValue(forKey: tabID)
cache[tabID] = viewModel
if let cachedModel = cache?.findBy(key: tabID) {
return cachedModel
}
if cache == nil {
cache = .init()
}
let viewModel = BrowserViewModel(tabID: tabID)
cache?.removeValue(forKey: tabID)
cache?.setValue(viewModel, forKey: tabID)
return viewModel
}
static func purgeCache() {
guard cache.count > 10 else { return }
let range = 0 ..< cache.count - 5
cache.values[range].forEach { viewModel in
viewModel.persistState()
Task { @MainActor in
cache?.removeOlderThan(Date.now.advanced(by: -360)) // 6 minutes
}
cache.removeSubrange(range)
}
// MARK: - Properties

View File

@ -0,0 +1,56 @@
// This file is part of Kiwix for iOS & macOS.
//
// Kiwix 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
// any later version.
//
// Kiwix 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 Kiwix; If not, see https://www.gnu.org/licenses/.
import Foundation
@MainActor
final class OrderedCache<Key: Hashable, Value> {
private struct ValueDated<V> {
let value: V
let date: Date
}
private var dict: [Key: ValueDated<Value>] = [:]
var count: Int {
dict.count
}
func findBy(key: Key) -> Value? {
if let dateValue = dict[key] {
return dateValue.value
}
return nil
}
func removeAll() {
dict = [:]
}
func removeOlderThan(_ pastDate: Date) {
dict = dict.filter { (_, value: ValueDated<Value>) in
value.date >= pastDate
}
}
func setValue(_ value: Value, forKey key: Key, dated: Date = Date.now) {
dict[key] = ValueDated(value: value, date: dated)
}
func removeValue(forKey key: Key) {
dict.removeValue(forKey: key)
}
}

View File

@ -48,9 +48,6 @@ packages:
Defaults:
url: https://github.com/sindresorhus/Defaults
majorVersion: 6.0.0
OrderedCollections:
url: https://github.com/apple/swift-collections.git
majorVersion: 1.0.4
targetTemplates:
ApplicationTemplate:
@ -73,7 +70,6 @@ targetTemplates:
- sdk: NotificationCenter.framework
- sdk: QuickLook.framework
- package: Defaults
- package: OrderedCollections
sources:
- path: App
- path: Model