diff --git a/TelegramCore/Account.swift b/TelegramCore/Account.swift index 04db69f7e2..1586b03158 100644 --- a/TelegramCore/Account.swift +++ b/TelegramCore/Account.swift @@ -534,7 +534,8 @@ public class Account { } } - let networkStateSignal = combineLatest(self.stateManager.isUpdating, network.connectionStatus) + let networkStateQueue = Queue() + let networkStateSignal = combineLatest(self.stateManager.isUpdating |> deliverOn(networkStateQueue), network.connectionStatus |> deliverOn(networkStateQueue)) |> map { isUpdating, connectionStatus -> AccountNetworkState in switch connectionStatus { case .waitingForNetwork: diff --git a/TelegramCore/FetchHttpResource.swift b/TelegramCore/FetchHttpResource.swift index 5503022619..5e7c367a56 100644 --- a/TelegramCore/FetchHttpResource.swift +++ b/TelegramCore/FetchHttpResource.swift @@ -9,7 +9,7 @@ import Foundation import MtProtoKitDynamic #endif -func fetchHttpResource(url: String) -> Signal { +public func fetchHttpResource(url: String) -> Signal { if let url = URL(string: url) { let signal = MTHttpRequestOperation.data(forHttpUrl: url)! return Signal { subscriber in diff --git a/TelegramCore/MergeLists.swift b/TelegramCore/MergeLists.swift index 8832fae9bd..fe83f021d7 100644 --- a/TelegramCore/MergeLists.swift +++ b/TelegramCore/MergeLists.swift @@ -1,11 +1,11 @@ import Foundation public protocol Identifiable { - associatedtype T: Hashable, Equatable + associatedtype T: Hashable var stableId: T { get } } -public func mergeListsStable(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)]) where T: Comparable, T: Equatable, T: Identifiable { +public func mergeListsStable(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)]) where T: Comparable, T: Identifiable { var removeIndices: [Int] = [] var insertItems: [(Int, T, Int?)] = [] @@ -85,7 +85,7 @@ public func mergeListsStable(leftList: [T], rightList: [T]) -> ([Int], [(Int, return (removeIndices, insertItems) } -public func mergeListsStableWithUpdates(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Equatable, T: Identifiable { +public func mergeListsStableWithUpdates(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable { var removeIndices: [Int] = [] var insertItems: [(Int, T, Int?)] = [] var updatedIndices: [(Int, T, Int)] = [] @@ -112,21 +112,6 @@ public func mergeListsStableWithUpdates(leftList: [T], rightList: [T]) -> ([I var currentList = leftList - /*print("-----------") - let newline = "\n" - print("left:\n") - var m = 0 - for left in leftList { - print("\(m): \(left.stableId)") - m += 1 - } - m = 0 - print("\nright:\n") - for right in rightList { - print("\(m): \(right.stableId)") - m += 1 - }*/ - var i = 0 var previousIndices: [T.T: Int] = [:] for left in leftList { @@ -271,16 +256,158 @@ public func mergeListsStableWithUpdates(leftList: [T], rightList: [T]) -> ([I currentList[index] = item } - //print("update after inserts:\n\(updatedIndices.map({ "\($0.0), \($0.1.stableId) (was \($0.2)))" }))") - - /*if currentList != rightList { - for l in 0 ..< currentList.count { - if currentList[l] != rightList[l] { - print("here \(currentList[l]) != \(rightList[l])") - } - } - }*/ assert(currentList == rightList, "currentList == rightList") return (removeIndices, insertItems, updatedIndices) } + +public func mergeListsStableWithUpdatesReversed(leftList: [T], rightList: [T]) -> ([Int], [(Int, T, Int?)], [(Int, T, Int)]) where T: Comparable, T: Identifiable { + var removeIndices: [Int] = [] + var insertItems: [(Int, T, Int?)] = [] + var updatedIndices: [(Int, T, Int)] = [] + + #if (arch(i386) || arch(x86_64)) && os(iOS) + var existingStableIds: [T.T: T] = [:] + for item in leftList { + if let _ = existingStableIds[item.stableId] { + assertionFailure() + } else { + existingStableIds[item.stableId] = item + } + } + existingStableIds.removeAll() + for item in rightList { + if let other = existingStableIds[item.stableId] { + print("\(other) has the same stableId as \(item): \(item.stableId)") + assertionFailure() + } else { + existingStableIds[item.stableId] = item + } + } + #endif + + var currentList = leftList + + var i = 0 + var previousIndices: [T.T: Int] = [:] + for left in leftList { + previousIndices[left.stableId] = i + i += 1 + } + + i = 0 + var j = 0 + while true { + let left: T? = i < currentList.count ? currentList[i] : nil + let right: T? = j < rightList.count ? rightList[j] : nil + + if let left = left, let right = right { + if left.stableId == right.stableId && left != right { + updatedIndices.append((i, right, previousIndices[left.stableId]!)) + i += 1 + j += 1 + } else { + if left == right { + i += 1 + j += 1 + } else if left > right { + removeIndices.append(i) + i += 1 + } else if !(left < right) { + removeIndices.append(i) + i += 1 + } else { + j += 1 + } + } + } else if let _ = left { + removeIndices.append(i) + i += 1 + } else if let _ = right { + j += 1 + } else { + break + } + } + + //print("remove:\n\(removeIndices)") + + for index in removeIndices.reversed() { + currentList.remove(at: index) + for i in 0 ..< updatedIndices.count { + if updatedIndices[i].0 >= index { + updatedIndices[i].0 -= 1 + } + } + } + + i = 0 + j = 0 + var k = 0 + while true { + let left: T? + + if k < updatedIndices.count && updatedIndices[k].0 < i { + k += 1 + } + + if k < updatedIndices.count { + if updatedIndices[k].0 == i { + left = updatedIndices[k].1 + } else { + left = i < currentList.count ? currentList[i] : nil + } + } else { + left = i < currentList.count ? currentList[i] : nil + } + + let right: T? = j < rightList.count ? rightList[j] : nil + + if let left = left, let right = right { + if left == right { + i += 1 + j += 1 + } else if left < right { + let previousIndex = previousIndices[right.stableId] + insertItems.append((i, right, previousIndex)) + currentList.insert(right, at: i) + if k < updatedIndices.count { + for l in k ..< updatedIndices.count { + updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2) + } + } + + i += 1 + j += 1 + } else { + i += 1 + } + } else if let _ = left { + i += 1 + } else if let right = right { + let previousIndex = previousIndices[right.stableId] + insertItems.append((i, right, previousIndex)) + currentList.insert(right, at: i) + + if k < updatedIndices.count { + for l in k ..< updatedIndices.count { + updatedIndices[l] = (updatedIndices[l].0 + 1, updatedIndices[l].1, updatedIndices[l].2) + } + } + + i += 1 + j += 1 + } else { + break + } + } + + for (index, item, _) in updatedIndices { + currentList[index] = item + } + + assert(currentList == rightList, "currentList == rightList") + + return (removeIndices, insertItems, updatedIndices) +} + diff --git a/TelegramCore/Network.swift b/TelegramCore/Network.swift index 2bfeb709cc..3d727d1cab 100644 --- a/TelegramCore/Network.swift +++ b/TelegramCore/Network.swift @@ -366,35 +366,28 @@ func initializedNetwork(arguments: NetworkInitializationArguments, supplementary let context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment)! - let seedAddressList: [Int: String] + let seedAddressList: [Int: [String]] if testingEnvironment { seedAddressList = [ - 1: "149.154.175.10", - 2: "149.154.167.40" + 1: ["149.154.175.10"], + 2: ["149.154.167.40"] ] } else { seedAddressList = [ - 1: "149.154.175.50", - 2: "149.154.167.50", - 3: "149.154.175.100", - 4: "149.154.167.91", - 5: "149.154.171.5" + 1: ["149.154.175.50", "2001:b28:f23d:f001::a"], + 2: ["149.154.167.50", "2001:67c:4e8:f002::a"], + 3: ["149.154.175.100", "2001:b28:f23d:f003::a"], + 4: ["149.154.167.91", "2001:67c:4e8:f004::a"], + 5: ["149.154.171.5", "2001:b28:f23f:f005::a"] ] } - for (id, ip) in seedAddressList { - context.setSeedAddressSetForDatacenterWithId(id, seedAddressSet: MTDatacenterAddressSet(addressList: [MTDatacenterAddress(ip: ip, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false)])) + for (id, ips) in seedAddressList { + context.setSeedAddressSetForDatacenterWithId(id, seedAddressSet: MTDatacenterAddressSet(addressList: ips.map { MTDatacenterAddress(ip: $0, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false) })) } context.keychain = keychain - - /*if testingEnvironment { - for (id, ip) in seedAddressList { - context.updateAddressSetForDatacenter(withId: id, addressSet: MTDatacenterAddressSet(addressList: [MTDatacenterAddress(ip: ip, port: 443, preferForMedia: false, restrictToTcp: false, cdn: false, preferForProxy: false)]), forceUpdateSchemes: true) - } - }*/ - context.setDiscoverBackupAddressListSignal(MTBackupAddressSignals.fetchBackupIps(testingEnvironment, currentContext: context)) let mtProto = MTProto(context: context, datacenterId: datacenterId, usageCalculationInfo: usageCalculationInfo(basePath: basePath, category: nil))!