mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Optimize media deletion
This commit is contained in:
parent
c08b3c6f81
commit
c257d42967
@ -929,6 +929,32 @@ public final class MediaBox {
|
||||
unlink(paths.partial + ".meta")
|
||||
self.fileContexts.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
let uniqueIds = Set(ids.map { $0.id.uniqueId })
|
||||
|
||||
var pathsToDelete: [String] = []
|
||||
|
||||
for cacheType in ["cache", "short-cache"] {
|
||||
if let enumerator = FileManager.default.enumerator(at: URL(fileURLWithPath: "\(self.basePath)/\(cacheType)"), includingPropertiesForKeys: [], options: [.skipsSubdirectoryDescendants], errorHandler: nil) {
|
||||
while let item = enumerator.nextObject() {
|
||||
guard let url = item as? NSURL, let path = url.path, let fileName = url.lastPathComponent else {
|
||||
continue
|
||||
}
|
||||
|
||||
if let range = fileName.range(of: ":") {
|
||||
let resourceId = String(fileName[fileName.startIndex ..< range.lowerBound])
|
||||
if uniqueIds.contains(resourceId) {
|
||||
pathsToDelete.append(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for path in pathsToDelete {
|
||||
unlink(path)
|
||||
}
|
||||
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
return EmptyDisposable
|
||||
|
@ -2278,18 +2278,26 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
||||
}
|
||||
}
|
||||
case let .DeleteMessagesWithGlobalIds(ids):
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.deleteMessagesWithGlobalIds(ids, forEachMedia: { media in
|
||||
processRemovedMedia(mediaBox, media)
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
case let .DeleteMessages(ids):
|
||||
deleteMessages(transaction: transaction, mediaBox: mediaBox, ids: ids)
|
||||
case let .UpdateMinAvailableMessage(id):
|
||||
if let message = transaction.getMessage(id) {
|
||||
updatePeerChatInclusionWithMinTimestamp(transaction: transaction, id: id.peerId, minTimestamp: message.timestamp, forceRootGroupIfNotExists: false)
|
||||
}
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.deleteMessagesInRange(peerId: id.peerId, namespace: id.namespace, minId: 1, maxId: id.id, forEachMedia: { media in
|
||||
processRemovedMedia(mediaBox, media)
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
case let .UpdatePeerChatInclusion(peerId, groupId, changedGroup):
|
||||
let currentInclusion = transaction.getPeerChatListInclusion(peerId)
|
||||
var currentPinningIndex: UInt16?
|
||||
|
@ -4,48 +4,64 @@ import SwiftSignalKit
|
||||
|
||||
import SyncCore
|
||||
|
||||
private func removeMessageMedia(message: Message, mediaBox: MediaBox) {
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage {
|
||||
let _ = mediaBox.removeCachedResources(Set(image.representations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
let _ = mediaBox.removeCachedResources(Set(file.previewRepresentations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
||||
let _ = mediaBox.removeCachedResources(Set([WrappedMediaResourceId(file.resource.id)])).start()
|
||||
func addMessageMediaResourceIdsToRemove(media: Media, resourceIds: inout [WrappedMediaResourceId]) {
|
||||
if let image = media as? TelegramMediaImage {
|
||||
for representation in image.representations {
|
||||
resourceIds.append(WrappedMediaResourceId(representation.resource.id))
|
||||
}
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
for representation in file.previewRepresentations {
|
||||
resourceIds.append(WrappedMediaResourceId(representation.resource.id))
|
||||
}
|
||||
resourceIds.append(WrappedMediaResourceId(file.resource.id))
|
||||
}
|
||||
}
|
||||
|
||||
func addMessageMediaResourceIdsToRemove(message: Message, resourceIds: inout [WrappedMediaResourceId]) {
|
||||
for media in message.media {
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
}
|
||||
}
|
||||
|
||||
public func deleteMessages(transaction: Transaction, mediaBox: MediaBox, ids: [MessageId], deleteMedia: Bool = true) {
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
if deleteMedia {
|
||||
for id in ids {
|
||||
if id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
if let message = transaction.getMessage(id) {
|
||||
removeMessageMedia(message: message, mediaBox: mediaBox)
|
||||
addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
transaction.deleteMessages(ids, forEachMedia: { media in
|
||||
if deleteMedia {
|
||||
processRemovedMedia(mediaBox, media)
|
||||
}
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
transaction.deleteMessages(ids, forEachMedia: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
public func deleteAllMessagesWithAuthor(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace) {
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.removeAllMessagesWithAuthor(peerId, authorId: authorId, namespace: namespace, forEachMedia: { media in
|
||||
processRemovedMedia(mediaBox, media)
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
}
|
||||
|
||||
public func clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.withAllMessages(peerId: peerId, { message in
|
||||
removeMessageMedia(message: message, mediaBox: mediaBox)
|
||||
addMessageMediaResourceIdsToRemove(message: message, resourceIds: &resourceIds)
|
||||
return true
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
}
|
||||
transaction.clearHistory(peerId, namespaces: namespaces, forEachMedia: { media in
|
||||
processRemovedMedia(mediaBox, media)
|
||||
transaction.clearHistory(peerId, namespaces: namespaces, forEachMedia: { _ in
|
||||
})
|
||||
}
|
||||
|
@ -147,9 +147,7 @@ public func clearAuthorHistory(account: Account, peerId: PeerId, memberId: PeerI
|
||||
|> `catch` { success -> Signal<Void, NoError> in
|
||||
if success {
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
transaction.removeAllMessagesWithAuthor(peerId, authorId: memberId, namespace: Namespaces.Message.Cloud, forEachMedia: { media in
|
||||
processRemovedMedia(account.postbox.mediaBox, media)
|
||||
})
|
||||
deleteAllMessagesWithAuthor(transaction: transaction, mediaBox: account.postbox.mediaBox, peerId: peerId, authorId: memberId, namespace: Namespaces.Message.Cloud)
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
|
@ -1,13 +0,0 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
|
||||
import SyncCore
|
||||
|
||||
func processRemovedMedia(_ mediaBox: MediaBox, _ media: Media) {
|
||||
if let image = media as? TelegramMediaImage {
|
||||
let _ = mediaBox.removeCachedResources(Set(image.representations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
let _ = mediaBox.removeCachedResources(Set(file.previewRepresentations.map({ WrappedMediaResourceId($0.resource.id) }))).start()
|
||||
let _ = mediaBox.removeCachedResources(Set([WrappedMediaResourceId(file.resource.id)])).start()
|
||||
}
|
||||
}
|
@ -104,9 +104,13 @@ func managedApplyPendingScheduledMessagesActions(postbox: Postbox, network: Netw
|
||||
})
|
||||
|> then(
|
||||
postbox.transaction { transaction -> Void in
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.deleteMessages([entry.id], forEachMedia: { media in
|
||||
processRemovedMedia(postbox.mediaBox, media)
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = postbox.mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
}
|
||||
|> ignoreValues
|
||||
)
|
||||
|
@ -421,9 +421,13 @@ func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId: PeerI
|
||||
})
|
||||
|
||||
if let minAvailableMessageId = minAvailableMessageId, minAvailableMessageIdUpdated {
|
||||
var resourceIds: [WrappedMediaResourceId] = []
|
||||
transaction.deleteMessagesInRange(peerId: peerId, namespace: minAvailableMessageId.namespace, minId: 1, maxId: minAvailableMessageId.id, forEachMedia: { media in
|
||||
processRemovedMedia(postbox.mediaBox, media)
|
||||
addMessageMediaResourceIdsToRemove(media: media, resourceIds: &resourceIds)
|
||||
})
|
||||
if !resourceIds.isEmpty {
|
||||
let _ = postbox.mediaBox.removeCachedResources(Set(resourceIds)).start()
|
||||
}
|
||||
}
|
||||
case .chatFull:
|
||||
break
|
||||
|
Loading…
x
Reference in New Issue
Block a user