Ensure that ordered item list keys are unique

This commit is contained in:
Ali 2021-06-19 13:38:39 +04:00
parent 1944d8214f
commit 719a749322
2 changed files with 46 additions and 4 deletions

View File

@ -29,17 +29,45 @@ final class OrderedItemListTable: Table {
let key = ValueBoxKey(length: 1 + 4 + 4)
key.setUInt8(0, value: OrderedItemListKeyNamespace.indexToId.rawValue)
key.setInt32(1, value: collectionId)
key.setUInt32(5, value: itemIndex)
key.setUInt32(1 + 4, value: itemIndex)
return key
}
private func keyIndexToIdLowerBound(collectionId: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 1 + 4 + 4)
key.setUInt8(0, value: OrderedItemListKeyNamespace.indexToId.rawValue)
key.setInt32(1, value: collectionId)
return key
}
private func keyIndexToIdUpperBound(collectionId: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 1 + 4 + 4)
key.setUInt8(0, value: OrderedItemListKeyNamespace.indexToId.rawValue)
key.setInt32(1, value: collectionId)
return key.successor
}
private func keyIdToIndex(collectionId: Int32, id: MemoryBuffer) -> ValueBoxKey {
let key = ValueBoxKey(length: 1 + 4 + id.length)
key.setUInt8(0, value: OrderedItemListKeyNamespace.idToIndex.rawValue)
key.setInt32(1, value: collectionId)
memcpy(key.memory.advanced(by: 5), id.memory, id.length)
memcpy(key.memory.advanced(by: 1 + 4), id.memory, id.length)
return key
}
private func keyIdToIndexLowerBound(collectionId: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 1 + 4)
key.setUInt8(0, value: OrderedItemListKeyNamespace.idToIndex.rawValue)
key.setInt32(1, value: collectionId)
return key
}
private func keyIdToIndexUpperBound(collectionId: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 1 + 4)
key.setUInt8(0, value: OrderedItemListKeyNamespace.idToIndex.rawValue)
key.setInt32(1, value: collectionId)
return key.successor
}
func getItemIds(collectionId: Int32) -> [MemoryBuffer] {
var itemIds: [MemoryBuffer] = []
@ -119,6 +147,8 @@ final class OrderedItemListTable: Table {
self.indexTable.remove(collectionId: collectionId, id: id)
}
assert(Set(items.map({ $0.id.makeData() })).count == items.count)
for i in 0 ..< items.count {
self.valueBox.set(self.table, key: self.keyIndexToId(collectionId: collectionId, itemIndex: UInt32(i)), value: items[i].id)
var indexValue: UInt32 = UInt32(i)

View File

@ -27,8 +27,20 @@ private func managedRecentMedia(postbox: Postbox, network: Network, collectionId
itemIds.reverse()
}
return fetch(forceFetch ? 0 : hashForIds(itemIds))
|> mapToSignal { items in
if let items = items {
|> mapToSignal { sourceItems in
var items: [OrderedItemListEntry] = []
if let sourceItems = sourceItems {
var existingIds = Set<MediaId>()
for item in sourceItems {
guard let id = (item.contents as? RecentMediaItem)?.media.id else {
continue
}
if !existingIds.contains(id) {
existingIds.insert(id)
items.append(item)
}
}
return postbox.transaction { transaction -> Void in
transaction.replaceOrderedItemListItems(collectionId: collectionId, items: items)
}