Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLW-2226: Snapshots loading optimisation #74

Merged
merged 2 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 43 additions & 19 deletions FearlessUtils/Classes/Runtime/TypeRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,25 @@ public class TypeRegistry: TypeRegistryProtocol {
private var allOverrides: Set<ConstantPath> = []

private var overrides: [ConstantPath: String] = [:]

public var registeredTypes: [Node] { graph.keys.compactMap { graph[$0] } }
public var registeredTypeNames: Set<String> { allKeys }
public var registeredOverrides: Set<ConstantPath> { allOverrides }

private let json: JSON
private let overridesJson: [JSON]?
private let additionalNodes: [Node]

public lazy var registeredTypes: [Node] = {
resolveJsons()
return graph.keys.compactMap { graph[$0] }
}()

public lazy var registeredTypeNames: Set<String> = {
resolveJsons()
return allKeys
}()

public lazy var registeredOverrides: Set<ConstantPath> = {
resolveJsons()
return allOverrides
}()

init(
json: JSON,
Expand All @@ -70,17 +85,14 @@ public class TypeRegistry: TypeRegistryProtocol {
) throws {
self.nodeFactory = nodeFactory
self.typeResolver = typeResolver

try parse(json: json)
parse(overrides: overrides)
override(nodes: additionalNodes)
resolveGenerics()

allKeys = Set(graph.keys)
allOverrides = Set(self.overrides.keys)
self.json = json
self.overridesJson = overrides
self.additionalNodes = additionalNodes
}

public func node(for key: String) -> Node? {
resolveJsons()

if let node = graph[key] {
return node
}
Expand All @@ -102,10 +114,24 @@ public class TypeRegistry: TypeRegistryProtocol {
}

public func override(for moduleName: String, constantName: String) -> String? {
overrides[.init(moduleName: moduleName, constantName: constantName)]
resolveJsons()
return overrides[.init(moduleName: moduleName, constantName: constantName)]
}

// MARK: Private

private func resolveJsons() {
guard graph.keys.isEmpty else {
return
}
parse(json: json)
parse(overrides: overridesJson)
override(nodes: additionalNodes)
resolveGenerics()

allKeys = Set(graph.keys)
allOverrides = Set(self.overrides.keys)
}

private func override(nodes: [Node]) {
for node in nodes {
Expand All @@ -129,18 +155,16 @@ public class TypeRegistry: TypeRegistryProtocol {
}
}

private func parse(json: JSON) throws {
private func parse(json: JSON) {
guard let dict = json.dictValue else {
throw TypeRegistryError.unexpectedJson
return
}

let keyParser = TermParser.generic()

let refinedDict = try dict.reduce(into: [String: JSON]()) { (result, item) in
let refinedDict = dict.reduce(into: [String: JSON]()) { (result, item) in
if let type = keyParser.parse(json: .stringValue(item.key))?.first?.stringValue {
result[type] = item.value
} else {
throw TypeRegistryError.invalidKey(item.key)
}
}

Expand All @@ -149,7 +173,7 @@ public class TypeRegistry: TypeRegistryProtocol {
}

for item in refinedDict {
if let node = try nodeFactory.buildNode(from: item.value, typeName: item.key, mediator: self) {
if let node = try? nodeFactory.buildNode(from: item.value, typeName: item.key, mediator: self) {
graph[item.key] = node
}
}
Expand Down
53 changes: 30 additions & 23 deletions FearlessUtils/Classes/Runtime/TypeRegistryCatalog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,10 @@ public class TypeRegistryCatalog: TypeRegistryCatalogProtocol {
public let runtimeMetadataRegistry: TypeRegistryProtocol
public let baseRegistry: TypeRegistryProtocol
public let versionedRegistries: [UInt64: TypeRegistryProtocol]
public let versionedTypes: [String: [UInt64]]
public let versionedOverrides: [ConstantPath: [UInt64]]
public let typeResolver: TypeResolving

public let allTypes: Set<String>
public let mutex = NSLock()
public var registryCache: [String: TypeRegistryProtocol] = [:]

public init(
baseRegistry: TypeRegistryProtocol,
versionedRegistries: [UInt64: TypeRegistryProtocol],
runtimeMetadataRegistry: TypeRegistryProtocol,
typeResolver: TypeResolving
) {
self.baseRegistry = baseRegistry
self.versionedRegistries = versionedRegistries
self.runtimeMetadataRegistry = runtimeMetadataRegistry
self.typeResolver = typeResolver

let allVersions = versionedRegistries.keys.sorted()

versionedTypes = allVersions.reduce(into: [String: [UInt64]]()) { (result, item) in

public lazy var versionedTypes: [String: [UInt64]] = {
let versionedTypes = allVersions.reduce(into: [String: [UInt64]]()) { (result, item) in
guard let typeRegistry = versionedRegistries[item] else { return }

let typeNames = typeRegistry.registeredTypeNames.filter { !(typeRegistry.node(for: $0) is GenericNode) }
Expand All @@ -57,7 +39,11 @@ public class TypeRegistryCatalog: TypeRegistryCatalogProtocol {
}
}

versionedOverrides = allVersions.reduce(into: [ConstantPath: [UInt64]]()) { result, item in
return versionedTypes
}()

public lazy var versionedOverrides: [ConstantPath: [UInt64]] = {
let versionedOverrides = allVersions.reduce(into: [ConstantPath: [UInt64]]()) { result, item in
guard let typeRegistry = versionedRegistries[item] else { return }
for constantPath in typeRegistry.registeredOverrides {
let versions: [UInt64] = result[constantPath] ?? []
Expand All @@ -67,8 +53,29 @@ public class TypeRegistryCatalog: TypeRegistryCatalogProtocol {
}
}
}

return versionedOverrides
}()

public lazy var allTypes: Set<String> = {
Set(versionedTypes.keys)
}()

public let mutex = NSLock()
public var registryCache: [String: TypeRegistryProtocol] = [:]
private let allVersions: [Dictionary<UInt64, TypeRegistryProtocol>.Keys.Element]

allTypes = Set(versionedTypes.keys)
public init(
baseRegistry: TypeRegistryProtocol,
versionedRegistries: [UInt64: TypeRegistryProtocol],
runtimeMetadataRegistry: TypeRegistryProtocol,
typeResolver: TypeResolving
) {
self.baseRegistry = baseRegistry
self.versionedRegistries = versionedRegistries
self.runtimeMetadataRegistry = runtimeMetadataRegistry
self.typeResolver = typeResolver
self.allVersions = versionedRegistries.keys.sorted()
}

public func node(for typeName: String, version: UInt64) -> Node? {
Expand Down