no message

This commit is contained in:
Peter 2016-08-23 16:19:22 +03:00
parent 0eb6029dc9
commit efe9ee147d
32 changed files with 174 additions and 12273 deletions

View File

@ -12,11 +12,6 @@
D0079F631D5A242500A27A2C /* ContactPeerIdsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F621D5A242500A27A2C /* ContactPeerIdsView.swift */; };
D0079F651D5A457A00A27A2C /* ContactPeersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F641D5A457A00A27A2C /* ContactPeersView.swift */; };
D0079F6B1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0079F6A1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift */; };
D00E0FB81B85D192002E4EB5 /* lmdb.h in Headers */ = {isa = PBXBuildFile; fileRef = D00E0FB41B85D192002E4EB5 /* lmdb.h */; };
D00E0FB91B85D192002E4EB5 /* mdb.c in Sources */ = {isa = PBXBuildFile; fileRef = D00E0FB51B85D192002E4EB5 /* mdb.c */; settings = {COMPILER_FLAGS = "-Wno-conversion -Wno-unreachable-code -Wno-conditional-uninitialized -Wno-format-extra-args -Wno-macro-redefined"; }; };
D00E0FBA1B85D192002E4EB5 /* midl.c in Sources */ = {isa = PBXBuildFile; fileRef = D00E0FB61B85D192002E4EB5 /* midl.c */; settings = {COMPILER_FLAGS = "-Wno-conversion"; }; };
D00E0FBB1B85D192002E4EB5 /* midl.h in Headers */ = {isa = PBXBuildFile; fileRef = D00E0FB71B85D192002E4EB5 /* midl.h */; };
D00E0FBE1B85D1B5002E4EB5 /* LmdbValueBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00E0FBD1B85D1B5002E4EB5 /* LmdbValueBox.swift */; };
D00EED1E1C81F28D00341DFF /* MessageHistoryTagsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00EED1D1C81F28D00341DFF /* MessageHistoryTagsTable.swift */; };
D01F7D9B1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F7D9A1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift */; };
D01F7D9D1CBF8586008765C9 /* SynchronizePeerReadStatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F7D9C1CBF8586008765C9 /* SynchronizePeerReadStatesView.swift */; };
@ -109,11 +104,6 @@
D0079F621D5A242500A27A2C /* ContactPeerIdsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactPeerIdsView.swift; sourceTree = "<group>"; };
D0079F641D5A457A00A27A2C /* ContactPeersView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactPeersView.swift; sourceTree = "<group>"; };
D0079F6A1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerNameIndexRepresentation.swift; sourceTree = "<group>"; };
D00E0FB41B85D192002E4EB5 /* lmdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lmdb.h; path = submodules/lmdb/libraries/liblmdb/lmdb.h; sourceTree = SOURCE_ROOT; };
D00E0FB51B85D192002E4EB5 /* mdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mdb.c; path = submodules/lmdb/libraries/liblmdb/mdb.c; sourceTree = SOURCE_ROOT; };
D00E0FB61B85D192002E4EB5 /* midl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midl.c; path = submodules/lmdb/libraries/liblmdb/midl.c; sourceTree = SOURCE_ROOT; };
D00E0FB71B85D192002E4EB5 /* midl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = midl.h; path = submodules/lmdb/libraries/liblmdb/midl.h; sourceTree = SOURCE_ROOT; };
D00E0FBD1B85D1B5002E4EB5 /* LmdbValueBox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LmdbValueBox.swift; sourceTree = "<group>"; };
D00EED1D1C81F28D00341DFF /* MessageHistoryTagsTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryTagsTable.swift; sourceTree = "<group>"; };
D01F7D9A1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHistoryInvalidatedReadStateTable.swift; sourceTree = "<group>"; };
D01F7D9C1CBF8586008765C9 /* SynchronizePeerReadStatesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizePeerReadStatesView.swift; sourceTree = "<group>"; };
@ -214,17 +204,6 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
D00E0FBC1B85D194002E4EB5 /* lmdb */ = {
isa = PBXGroup;
children = (
D00E0FB41B85D192002E4EB5 /* lmdb.h */,
D00E0FB51B85D192002E4EB5 /* mdb.c */,
D00E0FB61B85D192002E4EB5 /* midl.c */,
D00E0FB71B85D192002E4EB5 /* midl.h */,
);
name = lmdb;
sourceTree = "<group>";
};
D05F09981C9CAC1100BB6F96 /* Media Box */ = {
isa = PBXGroup;
children = (
@ -240,7 +219,6 @@
D07515FC1B2C44A200AE42E0 /* thirdparty */ = {
isa = PBXGroup;
children = (
D00E0FBC1B85D194002E4EB5 /* lmdb */,
D07516731B2EC8C700AE42E0 /* sqlite.swift */,
);
name = thirdparty;
@ -337,7 +315,6 @@
D0977F9D1B8234DF009994B2 /* ValueBoxKey.swift */,
D0977F9B1B822DB4009994B2 /* ValueBox.swift */,
D0977F9F1B8244D7009994B2 /* SqliteValueBox.swift */,
D00E0FBD1B85D1B5002E4EB5 /* LmdbValueBox.swift */,
);
name = "Value Box";
sourceTree = "<group>";
@ -443,9 +420,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
D00E0FB81B85D192002E4EB5 /* lmdb.h in Headers */,
D07516771B2EC90400AE42E0 /* fts3_tokenizer.h in Headers */,
D00E0FBB1B85D192002E4EB5 /* midl.h in Headers */,
D07516451B2D9CEF00AE42E0 /* sqlite3.h in Headers */,
D0D511041D64D91C00A97B8A /* IpcNotifier.h in Headers */,
D07516781B2EC90400AE42E0 /* SQLite-Bridging.h in Headers */,
@ -565,7 +540,6 @@
D08CEFB41D2AD8BE0015D3BC /* RedBlackTree.swift in Sources */,
D044CA2E1C618373002160FF /* ChatListHole.swift in Sources */,
D044E1631B2AD677001EE087 /* MurMurHash32.m in Sources */,
D00E0FBE1B85D1B5002E4EB5 /* LmdbValueBox.swift in Sources */,
D0079F6B1D5B3AAB00A27A2C /* PeerNameIndexRepresentation.swift in Sources */,
D08C713A1C501F0700779C0F /* MessageHistoryHole.swift in Sources */,
D044CA2A1C617D39002160FF /* SeedConfiguration.swift in Sources */,
@ -583,7 +557,6 @@
D0C9DA391C65782500855278 /* SimpleSet.swift in Sources */,
D0977F9E1B8234DF009994B2 /* ValueBoxKey.swift in Sources */,
D033A6F91C73E440006A2EAB /* UnsentMessageHistoryView.swift in Sources */,
D00E0FB91B85D192002E4EB5 /* mdb.c in Sources */,
D09ADF0C1D2EB83500C8208D /* OrderStatisticTable.swift in Sources */,
D0CE63F61CA1CCB2002BC462 /* MediaResource.swift in Sources */,
D0D510F91D63BCC200A97B8A /* IntermediateMessage.swift in Sources */,
@ -593,7 +566,6 @@
D0AB0B8E1D65D49C002C78E7 /* ChatListHolesView.swift in Sources */,
D07516791B2EC90400AE42E0 /* SQLite-Bridging.m in Sources */,
D0977FA01B8244D7009994B2 /* SqliteValueBox.swift in Sources */,
D00E0FBA1B85D192002E4EB5 /* midl.c in Sources */,
D0F9E8651C58CB7F00037222 /* ChatListTable.swift in Sources */,
D0F9E8711C5A0E9B00037222 /* PeerTable.swift in Sources */,
D05F09A61C9E9F9300BB6F96 /* MediaResourceStatus.swift in Sources */,

View File

@ -12,7 +12,7 @@
<key>PostboxTests.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
<integer>4</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -1,7 +1,7 @@
import Foundation
final class MutableChatListHolesView {
private var entries = Set<ChatListHole>()
fileprivate var entries = Set<ChatListHole>()
func update(holes: Set<ChatListHole>) -> Bool {
if self.entries != holes {

View File

@ -83,7 +83,7 @@ final class ChatListTable: Table {
if let topMessage = messageHistoryTable.topMessage(peerId) {
let index = MessageIndex(id: topMessage.id, timestamp: topMessage.timestamp)
if let currentIndex = currentIndex where currentIndex != index {
if let currentIndex = currentIndex , currentIndex != index {
self.justRemoveMessage(currentIndex)
}
if let currentIndex = currentIndex {

View File

@ -101,9 +101,9 @@ final class MutableChatListViewReplayContext {
}
final class MutableChatListView {
private var earlier: MutableChatListEntry?
private var later: MutableChatListEntry?
private var entries: [MutableChatListEntry]
fileprivate var earlier: MutableChatListEntry?
fileprivate var later: MutableChatListEntry?
fileprivate var entries: [MutableChatListEntry]
private var count: Int
init(earlier: MutableChatListEntry?, entries: [MutableChatListEntry], later: MutableChatListEntry?, count: Int) {
@ -113,13 +113,13 @@ final class MutableChatListView {
self.count = count
}
func refreshDueToExternalTransaction(fetchAroundChatEntries: (index: MessageIndex, count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?)) -> Bool {
func refreshDueToExternalTransaction(fetchAroundChatEntries: (_ index: MessageIndex, _ count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?)) -> Bool {
var index = MessageIndex.absoluteUpperBound()
if !self.entries.isEmpty {
index = self.entries[self.entries.count / 2].index
}
var (entries, earlier, later) = fetchAroundChatEntries(index: index, count: self.entries.count)
var (entries, earlier, later) = fetchAroundChatEntries(index, self.entries.count)
if entries != self.entries || earlier != self.earlier || later != self.later {
self.entries = entries
@ -223,7 +223,7 @@ final class MutableChatListView {
func remove(_ indices: Set<MessageIndex>, holes: Bool, context: MutableChatListViewReplayContext) -> Bool {
var hasChanges = false
if let earlier = self.earlier where indices.contains(earlier.index) {
if let earlier = self.earlier , indices.contains(earlier.index) {
var match = false
switch earlier {
case .HoleEntry:
@ -237,7 +237,7 @@ final class MutableChatListView {
}
}
if let later = self.later where indices.contains(later.index) {
if let later = self.later , indices.contains(later.index) {
var match = false
switch later {
case .HoleEntry:

View File

@ -22,7 +22,7 @@ private let typeStore = { () -> EncodableTypeStore in
return _typeStore
}()
public func declareEncodable(_ type: Any.Type, f: (Decoder) -> Coding) {
public func declareEncodable(_ type: Any.Type, f: @escaping(Decoder) -> Coding) {
let string = "\(type)"
let hash = murMurHashString32(string)
if typeStore.dict[hash] != nil {
@ -34,7 +34,7 @@ public func declareEncodable(_ type: Any.Type, f: (Decoder) -> Coding) {
private let emptyMemory = malloc(1)!
public class MemoryBuffer: Equatable, CustomStringConvertible {
var memory: UnsafeMutablePointer<Void>
var memory: UnsafeMutableRawPointer
var capacity: Int
var length: Int
var freeWhenDone: Bool
@ -47,7 +47,7 @@ public class MemoryBuffer: Equatable, CustomStringConvertible {
self.freeWhenDone = true
}
public init(memory: UnsafeMutablePointer<Void>, capacity: Int, length: Int, freeWhenDone: Bool) {
public init(memory: UnsafeMutableRawPointer, capacity: Int, length: Int, freeWhenDone: Bool) {
self.memory = memory
self.capacity = capacity
self.length = length
@ -62,7 +62,7 @@ public class MemoryBuffer: Equatable, CustomStringConvertible {
self.freeWhenDone = false
} else {
self.memory = malloc(data.count)!
data.copyBytes(to: UnsafeMutablePointer<UInt8>(self.memory), count: data.count)
data.copyBytes(to: self.memory.assumingMemoryBound(to: UInt8.self), count: data.count)
self.capacity = data.count
self.length = data.count
self.freeWhenDone = false
@ -84,7 +84,7 @@ public class MemoryBuffer: Equatable, CustomStringConvertible {
public var description: String {
let hexString = NSMutableString()
let bytes = UnsafeMutablePointer<UInt8>(self.memory)
let bytes = self.memory.assumingMemoryBound(to: UInt8.self)
for i in 0 ..< self.length {
hexString.appendFormat("%02x", UInt(bytes[i]))
}
@ -117,14 +117,14 @@ public final class WriteBuffer: MemoryBuffer {
}
public func makeData() -> Data {
return Data(bytes: UnsafePointer<UInt8>(self.memory), count: self.offset)
return Data(bytes: self.memory.assumingMemoryBound(to: UInt8.self), count: self.offset)
}
public func reset() {
self.offset = 0
}
public func write(_ data: UnsafePointer<Void>, offset: Int, length: Int) {
public func write(_ data: UnsafeRawPointer, offset: Int, length: Int) {
if self.offset + length > self.capacity {
self.capacity = self.offset + length + 256
if self.length == 0 {
@ -148,7 +148,7 @@ public final class WriteBuffer: MemoryBuffer {
self.memory = realloc(self.memory, self.capacity)
}
}
data.copyBytes(to: UnsafeMutablePointer<UInt8>(self.memory + offset), count: length)
data.copyBytes(to: self.memory.advanced(by: offset).assumingMemoryBound(to: UInt8.self), count: length)
self.offset += length
self.length = self.offset
}
@ -157,7 +157,7 @@ public final class WriteBuffer: MemoryBuffer {
public final class ReadBuffer: MemoryBuffer {
public var offset = 0
public init(memory: UnsafeMutablePointer<Void>, length: Int, freeWhenDone: Bool) {
public init(memory: UnsafeMutableRawPointer, length: Int, freeWhenDone: Bool) {
super.init(memory: memory, capacity: length, length: length, freeWhenDone: freeWhenDone)
}
@ -166,11 +166,11 @@ public final class ReadBuffer: MemoryBuffer {
}
public func dataNoCopy() -> Data {
return Data(bytesNoCopy: UnsafeMutablePointer<UInt8>(self.memory), count: self.length, deallocator: .none)
return Data(bytesNoCopy: self.memory.assumingMemoryBound(to: UInt8.self), count: self.length, deallocator: .none)
}
public func read(_ data: UnsafeMutablePointer<Void>, offset: Int, length: Int) {
memcpy(data + offset, self.memory + self.offset, length)
memcpy(data + offset, self.memory.advanced(by: self.offset), length)
self.offset += length
}
@ -284,7 +284,7 @@ public final class Encoder {
var type: Int8 = ValueType.Object.rawValue
self.buffer.write(&type, offset: 0, length: 1)
let string = "\(value.dynamicType)"
let string = "\(type(of: value))"
var typeHash: Int32 = murMurHashString32(string)
self.buffer.write(&typeHash, offset: 0, length: 4)
@ -328,7 +328,7 @@ public final class Encoder {
self.buffer.write(&length, offset: 0, length: 4)
let innerEncoder = Encoder()
for object in value {
var typeHash: Int32 = murMurHashString32("\(object.dynamicType)")
var typeHash: Int32 = murMurHashString32("\(type(of: object))")
self.buffer.write(&typeHash, offset: 0, length: 4)
innerEncoder.reset()
@ -348,7 +348,7 @@ public final class Encoder {
self.buffer.write(&length, offset: 0, length: 4)
let innerEncoder = Encoder()
for object in value {
var typeHash: Int32 = murMurHashString32("\(object.dynamicType)")
var typeHash: Int32 = murMurHashString32("\(type(of: object))")
self.buffer.write(&typeHash, offset: 0, length: 4)
innerEncoder.reset()
@ -369,7 +369,7 @@ public final class Encoder {
let innerEncoder = Encoder()
for record in value {
var keyTypeHash: Int32 = murMurHashString32("\(record.0.dynamicType)")
var keyTypeHash: Int32 = murMurHashString32("\(type(of: record.0))")
self.buffer.write(&keyTypeHash, offset: 0, length: 4)
innerEncoder.reset()
record.0.encode(innerEncoder)
@ -377,7 +377,7 @@ public final class Encoder {
self.buffer.write(&keyLength, offset: 0, length: 4)
self.buffer.write(innerEncoder.buffer.memory, offset: 0, length: Int(keyLength))
var valueTypeHash: Int32 = murMurHashString32("\(record.1.dynamicType)")
var valueTypeHash: Int32 = murMurHashString32("\(type(of: record.1))")
self.buffer.write(&valueTypeHash, offset: 0, length: 4)
innerEncoder.reset()
record.1.encode(innerEncoder)
@ -484,8 +484,10 @@ public final class Decoder {
}
}
private class func positionOnKey(_ bytes: UnsafePointer<Int8>, offset: inout Int, maxOffset: Int, length: Int, key: StaticString, valueType: ValueType) -> Bool
private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: StaticString, valueType: ValueType) -> Bool
{
let bytes = rawBytes.assumingMemoryBound(to: Int8.self)
let startOffset = offset
let keyLength: Int = key.utf8CodeUnitCount
@ -546,7 +548,7 @@ public final class Decoder {
}
public func decodeInt32ForKey(_ key: StaticString) -> Int32 {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) {
var value: Int32 = 0
memcpy(&value, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -557,7 +559,7 @@ public final class Decoder {
}
public func decodeInt32ForKey(_ key: StaticString) -> Int32? {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) {
var value: Int32 = 0
memcpy(&value, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -568,7 +570,7 @@ public final class Decoder {
}
public func decodeInt64ForKey(_ key: StaticString) -> Int64 {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) {
var value: Int64 = 0
memcpy(&value, self.buffer.memory + self.offset, 8)
self.offset += 8
@ -579,7 +581,7 @@ public final class Decoder {
}
public func decodeInt64ForKey(_ key: StaticString) -> Int64? {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) {
var value: Int64 = 0
memcpy(&value, self.buffer.memory + self.offset, 8)
self.offset += 8
@ -590,7 +592,7 @@ public final class Decoder {
}
public func decodeBoolForKey(_ key: StaticString) -> Bool {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bool) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bool) {
var value: Int8 = 0
memcpy(&value, self.buffer.memory + self.offset, 1)
self.offset += 1
@ -601,7 +603,7 @@ public final class Decoder {
}
public func decodeDoubleForKey(_ key: StaticString) -> Double {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Double) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Double) {
var value: Double = 0
memcpy(&value, self.buffer.memory + self.offset, 8)
self.offset += 8
@ -612,10 +614,10 @@ public final class Decoder {
}
public func decodeStringForKey(_ key: StaticString) -> String {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
let data = Data(bytes: UnsafeMutablePointer<UInt8>(self.buffer.memory).advanced(by: self.offset + 4), count: Int(length))
let data = Data(bytes: self.buffer.memory.assumingMemoryBound(to: UInt8.self).advanced(by: self.offset + 4), count: Int(length))
self.offset += 4 + Int(length)
return String(data: data, encoding: .utf8) ?? ""
} else {
@ -624,10 +626,10 @@ public final class Decoder {
}
public func decodeStringForKey(_ key: StaticString) -> String? {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
let data = Data(bytes: UnsafeMutablePointer<UInt8>(self.buffer.memory).advanced(by: self.offset + 4), count: Int(length))
let data = Data(bytes: self.buffer.memory.assumingMemoryBound(to: UInt8.self).advanced(by: self.offset + 4), count: Int(length))
self.offset += 4 + Int(length)
return String(data: data, encoding: .utf8)
} else {
@ -640,7 +642,7 @@ public final class Decoder {
}
public func decodeObjectForKey(_ key: StaticString) -> Coding? {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
var typeHash: Int32 = 0
memcpy(&typeHash, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -658,7 +660,7 @@ public final class Decoder {
}
public func decodeObjectForKey(_ key: StaticString, decoder: (Decoder) -> Coding) -> Coding? {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) {
var typeHash: Int32 = 0
memcpy(&typeHash, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -676,7 +678,7 @@ public final class Decoder {
}
public func decodeInt32ArrayForKey(_ key: StaticString) -> [Int32] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32Array) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32Array) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
var array: [Int32] = []
@ -696,7 +698,7 @@ public final class Decoder {
}
public func decodeInt64ArrayForKey(_ key: StaticString) -> [Int64] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64Array) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64Array) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
var array: [Int64] = []
@ -716,7 +718,7 @@ public final class Decoder {
}
public func decodeObjectArrayWithDecoderForKey<T where T: Coding>(_ key: StaticString) -> [T] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -755,7 +757,7 @@ public final class Decoder {
}
public func decodeObjectArrayForKey<T where T: Coding>(_ key: StaticString) -> [T] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -798,7 +800,7 @@ public final class Decoder {
}
public func decodeObjectArrayForKey(_ key: StaticString) -> [Coding] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -841,7 +843,7 @@ public final class Decoder {
}
public func decodeObjectDictionaryForKey<K, V: Coding where K: Coding, K: Hashable>(_ key: StaticString) -> [K : V] {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectDictionary) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectDictionary) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4
@ -875,7 +877,7 @@ public final class Decoder {
let value = failed ? nil : (typeStore.decode(valueHash, decoder: innerDecoder) as? V)
if let key = key, value = value {
if let key = key, let value = value {
dictionary[key] = value
} else {
failed = true
@ -895,11 +897,11 @@ public final class Decoder {
}
public func decodeBytesForKeyNoCopy(_ key: StaticString) -> ReadBuffer! {
if Decoder.positionOnKey(UnsafePointer<Int8>(self.buffer.memory), offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) {
if Decoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) {
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4 + Int(length)
return ReadBuffer(memory: UnsafeMutablePointer<Int8>(self.buffer.memory + (self.offset - Int(length))), length: Int(length), freeWhenDone: false)
return ReadBuffer(memory: self.buffer.memory.advanced(by: self.offset - Int(length)), length: Int(length), freeWhenDone: false)
} else {
return nil
}

View File

@ -1,7 +1,7 @@
import Foundation
final class MutableContactPeerIdsView {
private var peerIds: Set<PeerId>
fileprivate var peerIds: Set<PeerId>
init(peerIds: Set<PeerId>) {
self.peerIds = peerIds

View File

@ -1,10 +1,10 @@
import Foundation
final class MutableContactPeersView {
private let index: PeerNameIndex
private var peers: [PeerId: Peer]
private var peerIds: Set<PeerId>
private var accountPeer: Peer?
fileprivate let index: PeerNameIndex
fileprivate var peers: [PeerId: Peer]
fileprivate var peerIds: Set<PeerId>
fileprivate var accountPeer: Peer?
init(peers: [PeerId: Peer], index: PeerNameIndex, accountPeer: Peer?) {
self.index = index

View File

@ -5,7 +5,7 @@
@interface RLMNotifier : NSObject
- (instancetype)initWithBasePath:(NSString *)basePath notify:(void (^)())notify;
- (instancetype _Nonnull)initWithBasePath:(NSString * _Nonnull)basePath notify:(void (^ _Nonnull)())notify;
- (void)listen;
- (void)notifyOtherRealms;

View File

@ -94,7 +94,7 @@ namespace {
FdHolder _shutdownWriteFd;
}
- (instancetype)initWithBasePath:(NSString *)basePath notify:(void (^)())notify {
- (instancetype)initWithBasePath:(NSString *)basePath notify:( void (^ _Nonnull)())notify {
self = [super init];
if (self) {
_notify = [notify copy];

View File

@ -11,7 +11,7 @@ final class KeychainTable: Table {
func get(_ key: String) -> Data? {
if let value = self.valueBox.get(self.tableId, key: self.key(key)) {
return Data(bytes: UnsafePointer<UInt8>(value.memory), count: value.length)
return Data(bytes: value.memory.assumingMemoryBound(to: UInt8.self), count: value.length)
}
return nil
}

View File

@ -1,451 +0,0 @@
import Foundation
import sqlcipher
private struct LmdbTable {
var dbi: MDB_dbi
}
private struct LmdbCursor {
var cursor: OpaquePointer!
func seekTo(_ key: ValueBoxKey, forward: Bool) -> (ValueBoxKey, ReadBuffer)? {
var mdbKey = MDB_val()
var mdbData = MDB_val()
mdbKey.mv_data = key.memory
mdbKey.mv_size = key.length
mdbData.mv_data = nil
mdbData.mv_size = 0
let result = mdb_cursor_get(self.cursor, &mdbKey, &mdbData, forward ? MDB_SET_RANGE : MDB_SET_KEY)
if result == MDB_SUCCESS {
let actualKey = ValueBoxKey(length: mdbKey.mv_size)
memcpy(actualKey.memory, mdbKey.mv_data, mdbKey.mv_size)
let value = malloc(mdbData.mv_size)!
memcpy(value, mdbData.mv_data, mdbData.mv_size)
return (actualKey, ReadBuffer(memory: value, length: mdbData.mv_size, freeWhenDone: true))
} else if result == MDB_NOTFOUND {
if !forward {
return self.previous()
} else {
return nil
}
} else {
print("(LmdbValueBox mdb_cursor_get failed with \(result))")
return nil
}
}
func previous() -> (ValueBoxKey, ReadBuffer)? {
var mdbKey = MDB_val()
var mdbData = MDB_val()
mdbKey.mv_data = nil
mdbKey.mv_size = 0
mdbData.mv_data = nil
mdbData.mv_size = 0
let result = mdb_cursor_get(self.cursor, &mdbKey, &mdbData, MDB_PREV)
if result == MDB_SUCCESS {
let actualKey = ValueBoxKey(length: mdbKey.mv_size)
memcpy(actualKey.memory, mdbKey.mv_data, mdbKey.mv_size)
let value = malloc(mdbData.mv_size)!
memcpy(value, mdbData.mv_data, mdbData.mv_size)
return (actualKey, ReadBuffer(memory: value, length: mdbData.mv_size, freeWhenDone: true))
} else if result == MDB_NOTFOUND {
return nil
} else {
print("(LmdbValueBox mdb_cursor_get failed with \(result))")
return nil
}
}
func next() -> (ValueBoxKey, ReadBuffer)? {
var mdbKey = MDB_val()
var mdbData = MDB_val()
mdbKey.mv_data = nil
mdbKey.mv_size = 0
mdbData.mv_data = nil
mdbData.mv_size = 0
let result = mdb_cursor_get(self.cursor, &mdbKey, &mdbData, MDB_NEXT)
if result == MDB_SUCCESS {
let actualKey = ValueBoxKey(length: mdbKey.mv_size)
memcpy(actualKey.memory, mdbKey.mv_data, mdbKey.mv_size)
let value = malloc(mdbData.mv_size)!
memcpy(value, mdbData.mv_data, mdbData.mv_size)
return (actualKey, ReadBuffer(memory: value, length: mdbData.mv_size, freeWhenDone: true))
} else if result == MDB_NOTFOUND {
return nil
} else {
print("(LmdbValueBox mdb_cursor_get failed with \(result))")
return nil
}
}
}
public final class LmdbValueBox: ValueBox {
private var env: OpaquePointer? = nil
private var tables: [Int32 : LmdbTable] = [:]
private var sharedTxn: OpaquePointer? = nil
private var readQueryTime: CFAbsoluteTime = 0.0
private var writeQueryTime: CFAbsoluteTime = 0.0
private var commitTime: CFAbsoluteTime = 0.0
public init?(basePath: String) {
var result = mdb_env_create(&self.env)
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_env_create failed with \(result))")
return nil
}
let path = basePath + "/lmdb"
var createDirectory = false
var isDirectory: ObjCBool = false as ObjCBool
if FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory) {
if !isDirectory.boolValue {
do {
try FileManager.default.removeItem(atPath: path)
} catch _ { }
createDirectory = true
}
}
else {
createDirectory = true
}
if createDirectory {
do {
try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
} catch _ { }
}
mdb_env_set_mapsize(self.env, 500 * 1024 * 1024);
mdb_env_set_maxdbs(self.env, 64)
path.withCString { string in
result = mdb_env_open(self.env, string, UInt32(MDB_NOSYNC), 0o664)
}
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_env_open failed with \(result))")
return nil
}
var removedReaders: Int32 = 0
result = mdb_reader_check(self.env, &removedReaders)
if removedReaders != 0 {
print("(LmdbValueBox removed \(removedReaders) stale readers)")
}
}
deinit {
mdb_env_close(self.env)
}
private func createTableWithName(_ name: Int32) -> LmdbTable? {
var dbi = MDB_dbi()
let result = mdb_dbi_open(self.sharedTxn, "\(name)", UInt32(MDB_CREATE), &dbi)
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_dbi_open failed with \(result))")
return nil
}
return LmdbTable(dbi: dbi)
}
public func beginStats() {
self.readQueryTime = 0.0
self.writeQueryTime = 0.0
self.commitTime = 0.0
}
public func endStats() {
print("(LmdbValueBox stats read: \(self.readQueryTime * 1000.0) ms, write: \(self.writeQueryTime * 1000.0) ms, commit: \(self.commitTime * 1000.0) ms")
}
public func begin() {
if self.sharedTxn != nil {
print("(LmdbValueBox already in transaction)")
} else {
let result = mdb_txn_begin(self.env, nil, 0, &sharedTxn)
if result != MDB_SUCCESS {
print("(LmdbValueBox txn_begin failed with \(result))")
return
}
}
}
public func commit() {
let startTime = CFAbsoluteTimeGetCurrent()
if self.sharedTxn == nil {
print("(LmdbValueBox already no current transaction)")
} else {
let result = mdb_txn_commit(self.sharedTxn)
self.sharedTxn = nil
self.commitTime += CFAbsoluteTimeGetCurrent() - startTime
if result != MDB_SUCCESS {
print("(LmdbValueBox txn_commit failed with \(result))")
return
}
}
}
public func range(_ table: Int32, start: ValueBoxKey, end: ValueBoxKey, values: @noescape(ValueBoxKey, ReadBuffer) -> Bool, limit: Int) {
if start == end || limit == 0 {
return
}
var commit = false
if self.sharedTxn == nil {
self.begin()
commit = true
}
var nativeTable: LmdbTable?
if let existingTable = self.tables[table] {
nativeTable = existingTable
} else if let createdTable = self.createTableWithName(table) {
nativeTable = createdTable
self.tables[table] = createdTable
}
if let nativeTable = nativeTable {
var startTime = CFAbsoluteTimeGetCurrent()
var cursorPtr: OpaquePointer? = nil
let result = mdb_cursor_open(self.sharedTxn, nativeTable.dbi, &cursorPtr)
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_cursor_open failed with \(result))")
} else {
let cursor = LmdbCursor(cursor: cursorPtr)
if start < end {
var value = cursor.seekTo(start, forward: true)
if value != nil {
if value!.0 == start {
value = cursor.next()
}
}
var currentTime = CFAbsoluteTimeGetCurrent()
readQueryTime += currentTime - startTime
startTime = currentTime
var count = 0
if value != nil && value!.0 < end {
count += 1
let _ = values(value!.0, value!.1)
}
while value != nil && value!.0 < end && count < limit {
startTime = CFAbsoluteTimeGetCurrent()
value = cursor.next()
currentTime = CFAbsoluteTimeGetCurrent()
readQueryTime += currentTime - startTime
startTime = currentTime
if value != nil && value!.0 < end {
count += 1
let _ = values(value!.0, value!.1)
}
}
} else {
var startTime = CFAbsoluteTimeGetCurrent()
var value = cursor.seekTo(start, forward: false)
if value != nil {
if value!.0 == start {
value = cursor.previous()
}
}
var currentTime = CFAbsoluteTimeGetCurrent()
readQueryTime += currentTime - startTime
startTime = currentTime
var count = 0
if value != nil && value!.0 > end {
count += 1
let _ = values(value!.0, value!.1)
}
while value != nil && value!.0 > end && count < limit {
startTime = CFAbsoluteTimeGetCurrent()
value = cursor.previous()
currentTime = CFAbsoluteTimeGetCurrent()
readQueryTime += currentTime - startTime
startTime = currentTime
if value != nil && value!.0 > end {
count += 1
let _ = values(value!.0, value!.1)
}
}
}
mdb_cursor_close(cursorPtr)
}
}
if commit {
let startTime = CFAbsoluteTimeGetCurrent()
self.commit()
readQueryTime += CFAbsoluteTimeGetCurrent() - startTime
}
}
public func range(_ table: Int32, start: ValueBoxKey, end: ValueBoxKey, keys: @noescape(ValueBoxKey) -> Bool, limit: Int) {
self.range(table, start: start, end: end, values: { key, _ in
return keys(key)
}, limit: limit)
}
public func get(_ table: Int32, key: ValueBoxKey) -> ReadBuffer? {
let startTime = CFAbsoluteTimeGetCurrent()
var commit = false
if self.sharedTxn == nil {
self.begin()
commit = true
}
var nativeTable: LmdbTable?
if let existingTable = self.tables[table] {
nativeTable = existingTable
} else if let createdTable = self.createTableWithName(table) {
nativeTable = createdTable
self.tables[table] = createdTable
}
var resultValue: ReadBuffer?
if let nativeTable = nativeTable {
var mdbKey = MDB_val()
var mdbData = MDB_val()
mdbKey.mv_data = key.memory
mdbKey.mv_size = key.length
let result = mdb_get(self.sharedTxn, nativeTable.dbi, &mdbKey, &mdbData)
if result == MDB_SUCCESS {
let value = malloc(mdbData.mv_size)!
memcpy(value, mdbData.mv_data, mdbData.mv_size)
resultValue = ReadBuffer(memory: value, length: mdbData.mv_size, freeWhenDone: true)
} else {
if result != MDB_NOTFOUND {
print("(LmdbValueBox mdb_get failed with \(result))")
}
}
}
if commit {
self.commit()
}
readQueryTime += CFAbsoluteTimeGetCurrent() - startTime
return resultValue
}
public func exists(_ table: Int32, key: ValueBoxKey) -> Bool {
return self.get(table, key: key) != nil
}
public func set(_ table: Int32, key: ValueBoxKey, value: MemoryBuffer) {
let startTime = CFAbsoluteTimeGetCurrent()
var commit = false
if self.sharedTxn == nil {
self.begin()
commit = true
}
var nativeTable: LmdbTable?
if let existingTable = self.tables[table] {
nativeTable = existingTable
} else if let createdTable = self.createTableWithName(table) {
nativeTable = createdTable
self.tables[table] = createdTable
}
if let nativeTable = nativeTable {
var mdbKey = MDB_val()
var mdbData = MDB_val()
mdbKey.mv_data = key.memory
mdbKey.mv_size = key.length
mdbData.mv_data = value.memory
mdbData.mv_size = value.length
let result = mdb_put(self.sharedTxn, nativeTable.dbi, &mdbKey, &mdbData, 0)
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_set failed with \(result))")
}
}
if commit {
self.commit()
}
writeQueryTime += CFAbsoluteTimeGetCurrent() - startTime
}
public func remove(_ table: Int32, key: ValueBoxKey) {
let startTime = CFAbsoluteTimeGetCurrent()
var commit = false
if self.sharedTxn == nil {
self.begin()
commit = true
}
var nativeTable: LmdbTable?
if let existingTable = self.tables[table] {
nativeTable = existingTable
} else if let createdTable = self.createTableWithName(table) {
nativeTable = createdTable
self.tables[table] = createdTable
}
if let nativeTable = nativeTable {
var mdbKey = MDB_val()
mdbKey.mv_data = key.memory
mdbKey.mv_size = key.length
let result = mdb_del(self.sharedTxn, nativeTable.dbi, &mdbKey, nil)
if result != MDB_SUCCESS {
print("(LmdbValueBox mdb_set failed with \(result))")
}
}
if commit {
self.commit()
}
writeQueryTime += CFAbsoluteTimeGetCurrent() - startTime
}
public func drop() {
}
}

View File

@ -3,7 +3,7 @@ import Foundation
public final class MappedFile {
private var handle: Int32
private var currentSize: Int
private var memory: UnsafeMutablePointer<Void>
private var memory: UnsafeMutableRawPointer
public init(path: String) {
self.handle = open(path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)

View File

@ -116,7 +116,7 @@ public final class MediaBox {
}
self.statusQueue.async {
if let statusContext = self.statusContexts[resource.id] where statusContext.status == nil {
if let statusContext = self.statusContexts[resource.id] , statusContext.status == nil {
statusContext.status = status
for subscriber in statusContext.subscribers.copyItems() {
@ -499,7 +499,7 @@ public final class MediaBox {
}
self.statusQueue.async {
if let statusContext = self.statusContexts[resource.id] where statusContext.status != status {
if let statusContext = self.statusContexts[resource.id] , statusContext.status != status {
statusContext.status = status
for subscriber in statusContext.subscribers.copyItems() {
subscriber(status)
@ -523,7 +523,7 @@ public final class MediaBox {
public func cancelInteractiveResourceFetch(_ resource: MediaResource) {
self.dataQueue.async {
if let dataContext = self.dataContexts[resource.id] where dataContext.fetchDisposable != nil {
if let dataContext = self.dataContexts[resource.id] , dataContext.fetchDisposable != nil {
dataContext.fetchDisposable?.dispose()
dataContext.fetchDisposable = nil
@ -536,7 +536,7 @@ public final class MediaBox {
}
self.statusQueue.async {
if let statusContext = self.statusContexts[resource.id] where statusContext.status != status {
if let statusContext = self.statusContexts[resource.id] , statusContext.status != status {
statusContext.status = status
for subscriber in statusContext.subscribers.copyItems() {
subscriber(status)

View File

@ -230,7 +230,7 @@ public func ==(lhs: MessageForwardInfo, rhs: MessageForwardInfo) -> Bool {
if !lhs.author.isEqual(rhs.author) {
return false
}
if let lhsSource = lhs.source, rhsSource = rhs.source {
if let lhsSource = lhs.source, let rhsSource = rhs.source {
if !lhsSource.isEqual(rhsSource) {
return false
}

View File

@ -19,7 +19,7 @@ public func <(lhs: MessageHistoryHolesViewEntry, rhs: MessageHistoryHolesViewEnt
}
final class MutableMessageHistoryHolesView {
private var entries: [PeerId: Set<MessageHistoryHolesViewEntry>] = [:]
fileprivate var entries: [PeerId: Set<MessageHistoryHolesViewEntry>] = [:]
init() {
}

View File

@ -289,7 +289,7 @@ final class MessageHistoryIndexTable: Table {
let adjacent = self.adjacentItems(id)
if let lowerItem = adjacent.lower, upperItem = adjacent.upper {
if let lowerItem = adjacent.lower, let upperItem = adjacent.upper {
switch lowerItem {
case let .Message(lowerMessage):
switch upperItem {
@ -471,7 +471,7 @@ final class MessageHistoryIndexTable: Table {
self.justRemove(upperHole.maxIndex, operations: &operations)
}
} else if fillType.direction == .LowerToUpper {
if let maxMessageInRange = maxMessageInRange where maxMessageInRange.id.id != Int32.max && maxMessageInRange.id.id + 1 <= upperHole.maxIndex.id.id {
if let maxMessageInRange = maxMessageInRange , maxMessageInRange.id.id != Int32.max && maxMessageInRange.id.id + 1 <= upperHole.maxIndex.id.id {
let stableId: UInt32
let tags: UInt32 = upperHole.tags
if removedHole {
@ -482,7 +482,7 @@ final class MessageHistoryIndexTable: Table {
self.justInsertHole(MessageHistoryHole(stableId: stableId, maxIndex: upperHole.maxIndex, min: maxMessageInRange.id.id + 1, tags: tags), operations: &operations)
}
} else if fillType.direction == .UpperToLower {
if let minMessageInRange = minMessageInRange where minMessageInRange.id.id - 1 >= upperHole.min {
if let minMessageInRange = minMessageInRange , minMessageInRange.id.id - 1 >= upperHole.min {
let stableId: UInt32
let tags: UInt32 = upperHole.tags
if removedHole {
@ -498,14 +498,14 @@ final class MessageHistoryIndexTable: Table {
removedHole = true
}
if let minMessageInRange = minMessageInRange where minMessageInRange.id.id - 1 >= upperHole.min {
if let minMessageInRange = minMessageInRange , minMessageInRange.id.id - 1 >= upperHole.min {
let stableId: UInt32 = upperHole.stableId
let tags: UInt32 = upperHole.tags
self.justInsertHole(MessageHistoryHole(stableId: stableId, maxIndex: MessageIndex(id: MessageId(peerId: id.peerId, namespace: id.namespace, id: minMessageInRange.id.id - 1), timestamp: minMessageInRange.timestamp), min: upperHole.min, tags: tags), operations: &operations)
}
if let maxMessageInRange = maxMessageInRange where maxMessageInRange.id.id != Int32.max && maxMessageInRange.id.id + 1 <= upperHole.maxIndex.id.id {
if let maxMessageInRange = maxMessageInRange , maxMessageInRange.id.id != Int32.max && maxMessageInRange.id.id + 1 <= upperHole.maxIndex.id.id {
let stableId: UInt32 = self.metadataTable.getNextStableMessageIndexId()
let tags: UInt32 = upperHole.tags
self.justInsertHole(MessageHistoryHole(stableId: stableId, maxIndex: upperHole.maxIndex, min: maxMessageInRange.id.id + 1, tags: tags), operations: &operations)
@ -648,7 +648,7 @@ final class MessageHistoryIndexTable: Table {
value.read(&flags, offset: 0, length: 1)
if (flags & HistoryEntryTypeMask) == HistoryEntryTypeHole {
value.reset()
if case let .Hole(hole) = readHistoryIndexEntry(peerId, namespace: namespace, key: key, value: value) where hole.min <= maxId && hole.maxIndex.id.id >= maxId {
if case let .Hole(hole) = readHistoryIndexEntry(peerId, namespace: namespace, key: key, value: value) , hole.min <= maxId && hole.maxIndex.id.id >= maxId {
holes = true
}
}

View File

@ -155,7 +155,7 @@ final class MessageHistoryMetadataTable: Table {
let sharedBuffer = WriteBuffer()
for (peerId, namespaces) in self.updatedPeerNextMessageIdByNamespace {
for namespace in namespaces {
if let messageIdByNamespace = self.peerNextMessageIdByNamespace[peerId], maxId = messageIdByNamespace[namespace] {
if let messageIdByNamespace = self.peerNextMessageIdByNamespace[peerId], let maxId = messageIdByNamespace[namespace] {
sharedBuffer.reset()
var mutableMaxId = maxId
sharedBuffer.write(&mutableMaxId, offset: 0, length: 4)

View File

@ -200,7 +200,7 @@ final class MessageHistoryReadStateTable: Table {
}
func applyIncomingMaxReadId(_ messageId: MessageId, incomingStatsInRange: (MessageId.Id, MessageId.Id) -> (count: Int, holes: Bool), topMessageId: MessageId.Id?) -> (CombinedPeerReadState?, Bool) {
if let states = self.get(messageId.peerId), state = states.namespaces[messageId.namespace] {
if let states = self.get(messageId.peerId), let state = states.namespaces[messageId.namespace] {
if traceReadStates {
print("[ReadStateTable] applyMaxReadId peerId: \(messageId.peerId), maxReadId: \(messageId.id) (before: \(states.namespaces))")
}
@ -231,7 +231,7 @@ final class MessageHistoryReadStateTable: Table {
}
func applyOutgoingMaxReadId(_ messageId: MessageId) -> (CombinedPeerReadState?, Bool) {
if let states = self.get(messageId.peerId), state = states.namespaces[messageId.namespace] {
if let states = self.get(messageId.peerId), let state = states.namespaces[messageId.namespace] {
if state.maxOutgoingReadId < messageId.id {
states.namespaces[messageId.namespace] = PeerReadState(maxIncomingReadId: state.maxIncomingReadId, maxOutgoingReadId: state.maxOutgoingReadId, maxKnownId: state.maxKnownId, count: state.count)
self.updatedPeerIds.insert(messageId.peerId)
@ -262,7 +262,7 @@ final class MessageHistoryReadStateTable: Table {
override func beforeCommit() {
let sharedBuffer = WriteBuffer()
for id in self.updatedPeerIds {
if let wrappedStates = self.cachedPeerReadStates[id], states = wrappedStates {
if let wrappedStates = self.cachedPeerReadStates[id], let states = wrappedStates {
sharedBuffer.reset()
var count: Int32 = Int32(states.namespaces.count)
sharedBuffer.write(&count, offset: 0, length: 4)

View File

@ -610,7 +610,7 @@ final class MessageHistoryTable: Table {
}
func embeddedMediaForIndex(_ index: MessageIndex, id: MediaId) -> Media? {
if let message = self.getMessage(index) where message.embeddedMediaData.length > 4 {
if let message = self.getMessage(index), message.embeddedMediaData.length > 4 {
var embeddedMediaCount: Int32 = 0
message.embeddedMediaData.read(&embeddedMediaCount, offset: 0, length: 4)
@ -619,7 +619,7 @@ final class MessageHistoryTable: Table {
message.embeddedMediaData.read(&mediaLength, offset: 0, length: 4)
if let readMedia = Decoder(buffer: MemoryBuffer(memory: message.embeddedMediaData.memory + message.embeddedMediaData.offset, capacity: Int(mediaLength), length: Int(mediaLength), freeWhenDone: false)).decodeRootObject() as? Media {
if let readMediaId = readMedia.id where readMediaId == id {
if let readMediaId = readMedia.id, readMediaId == id {
return readMedia
}
}
@ -880,7 +880,7 @@ final class MessageHistoryTable: Table {
}
func unembedMedia(_ index: MessageIndex, id: MediaId) -> Media? {
if let message = self.getMessage(index) where message.embeddedMediaData.length > 4 {
if let message = self.getMessage(index), message.embeddedMediaData.length > 4 {
var embeddedMediaCount: Int32 = 0
message.embeddedMediaData.read(&embeddedMediaCount, offset: 0, length: 4)
@ -897,14 +897,14 @@ final class MessageHistoryTable: Table {
message.embeddedMediaData.read(&mediaLength, offset: 0, length: 4)
if let media = Decoder(buffer: MemoryBuffer(memory: message.embeddedMediaData.memory + message.embeddedMediaData.offset, capacity: Int(mediaLength), length: Int(mediaLength), freeWhenDone: false)).decodeRootObject() as? Media {
if let mediaId = media.id where mediaId == id {
if let mediaId = media.id, mediaId == id {
copyMedia = false
extractedMedia = media
}
}
if copyMedia {
updatedEmbeddedMediaBuffer.write(message.embeddedMediaData.memory + mediaOffset, offset: 0, length: message.embeddedMediaData.offset - mediaOffset)
updatedEmbeddedMediaBuffer.write(message.embeddedMediaData.memory.advanced(by: mediaOffset), offset: 0, length: message.embeddedMediaData.offset - mediaOffset)
}
}
@ -1055,7 +1055,7 @@ final class MessageHistoryTable: Table {
var textLength: Int32 = 0
value.read(&textLength, offset: 0, length: 4)
let text = String(data: Data(bytes: UnsafeMutablePointer<UInt8>(value.memory).advanced(by: value.offset), count: Int(textLength)), encoding: .utf8) ?? ""
let text = String(data: Data(bytes: value.memory.assumingMemoryBound(to: UInt8.self).advanced(by: value.offset), count: Int(textLength)), encoding: .utf8) ?? ""
//let text = NSString(bytes: value.memory + value.offset, length: Int(textLength), encoding: NSUTF8StringEncoding) ?? ""
value.skip(Int(textLength))
@ -1151,7 +1151,7 @@ final class MessageHistoryTable: Table {
}
var forwardInfo: MessageForwardInfo?
if let internalForwardInfo = message.forwardInfo, forwardAuthor = peerTable.get(internalForwardInfo.authorId) {
if let internalForwardInfo = message.forwardInfo, let forwardAuthor = peerTable.get(internalForwardInfo.authorId) {
var source: Peer?
if let sourceId = internalForwardInfo.sourceId {
@ -1345,7 +1345,7 @@ final class MessageHistoryTable: Table {
}
func maxReadIndex(_ peerId: PeerId) -> MessageHistoryAnchorIndex? {
if let combinedState = self.readStateTable.getCombinedState(peerId), state = combinedState.states.first where state.1.count != 0 {
if let combinedState = self.readStateTable.getCombinedState(peerId), let state = combinedState.states.first , state.1.count != 0 {
return self.anchorIndex(MessageId(peerId: peerId, namespace: state.0, id: state.1.maxIncomingReadId))
}
return nil
@ -1353,10 +1353,10 @@ final class MessageHistoryTable: Table {
func anchorIndex(_ messageId: MessageId) -> MessageHistoryAnchorIndex? {
let (lower, upper) = self.messageHistoryIndexTable.adjacentItems(messageId, bindUpper: false)
if let lower = lower, case let .Hole(hole) = lower where messageId.id >= hole.min && messageId.id <= hole.maxIndex.id.id {
if let lower = lower, case let .Hole(hole) = lower, messageId.id >= hole.min && messageId.id <= hole.maxIndex.id.id {
return MessageHistoryAnchorIndex(index: MessageIndex(id: messageId, timestamp: lower.index.timestamp), exact: false)
}
if let upper = upper, case let .Hole(hole) = upper where messageId.id >= hole.min && messageId.id <= hole.maxIndex.id.id {
if let upper = upper, case let .Hole(hole) = upper, messageId.id >= hole.min && messageId.id <= hole.maxIndex.id.id {
return MessageHistoryAnchorIndex(index: MessageIndex(id: messageId, timestamp: upper.index.timestamp), exact: false)
}

View File

@ -126,12 +126,12 @@ final class MutableMessageHistoryViewReplayContext {
final class MutableMessageHistoryView {
private(set) var id: MessageHistoryViewId
let tagMask: MessageTags?
private var anchorIndex: MessageHistoryAnchorIndex
private let combinedReadState: CombinedPeerReadState?
private var earlier: MutableMessageHistoryEntry?
private var later: MutableMessageHistoryEntry?
private var entries: [MutableMessageHistoryEntry]
private let fillCount: Int
fileprivate var anchorIndex: MessageHistoryAnchorIndex
fileprivate let combinedReadState: CombinedPeerReadState?
fileprivate var earlier: MutableMessageHistoryEntry?
fileprivate var later: MutableMessageHistoryEntry?
fileprivate var entries: [MutableMessageHistoryEntry]
fileprivate let fillCount: Int
init(id: MessageHistoryViewId, anchorIndex: MessageHistoryAnchorIndex, combinedReadState: CombinedPeerReadState?, earlier: MutableMessageHistoryEntry?, entries: [MutableMessageHistoryEntry], later: MutableMessageHistoryEntry?, tagMask: MessageTags?, count: Int) {
self.id = id
@ -166,7 +166,7 @@ final class MutableMessageHistoryView {
}
}
if let minIndex = minIndex, maxIndex = maxIndex {
if let minIndex = minIndex, let maxIndex = maxIndex {
var minClipIndex = minIndex
var maxClipIndex = maxIndex
@ -222,13 +222,15 @@ final class MutableMessageHistoryView {
return false
}
func refreshDueToExternalTransaction(fetchAroundHistoryEntries: (index: MessageIndex, count: Int, tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?)) -> Bool {
var index = MessageIndex.absoluteUpperBound()
func refreshDueToExternalTransaction(fetchAroundHistoryEntries: (_ index: MessageIndex, _ count: Int, _ tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?)) -> Bool {
var index = MessageIndex.upperBound(peerId: self.anchorIndex.index.id.peerId)
if !self.entries.isEmpty {
if let _ = self.later {
index = self.entries[self.entries.count / 2].index
}
}
let (entries, earlier, later) = fetchAroundHistoryEntries(index: index, count: max(self.fillCount, self.entries.count), tagMask: self.tagMask)
let (entries, earlier, later) = fetchAroundHistoryEntries(index, max(self.fillCount, self.entries.count), self.tagMask)
self.entries = entries
self.earlier = earlier
@ -268,7 +270,7 @@ final class MutableMessageHistoryView {
//self.combinedReadState = combinedReadState
case let .UpdateEmbeddedMedia(index, embeddedMediaData):
for i in 0 ..< self.entries.count {
if case let .IntermediateMessageEntry(message, _) = self.entries[i] where MessageIndex(message) == index {
if case let .IntermediateMessageEntry(message, _) = self.entries[i] , MessageIndex(message) == index {
self.entries[i] = .IntermediateMessageEntry(IntermediateMessage(stableId: message.stableId, id: message.id, timestamp: message.timestamp, flags: message.flags, tags: message.tags, forwardInfo: message.forwardInfo, authorId: message.authorId, text: message.text, attributesData: message.attributesData, embeddedMediaData: embeddedMediaData, referencedMedia: message.referencedMedia), nil)
hasChanges = true
break
@ -283,7 +285,7 @@ final class MutableMessageHistoryView {
case let .MessageEntry(message, _):
var rebuild = false
for media in message.media {
if let mediaId = media.id, _ = updatedMedia[mediaId] {
if let mediaId = media.id, let _ = updatedMedia[mediaId] {
rebuild = true
break
}
@ -292,7 +294,7 @@ final class MutableMessageHistoryView {
if rebuild {
var messageMedia: [Media] = []
for media in message.media {
if let mediaId = media.id, updated = updatedMedia[mediaId] {
if let mediaId = media.id, let updated = updatedMedia[mediaId] {
if let updated = updated {
messageMedia.append(updated)
}
@ -307,7 +309,7 @@ final class MutableMessageHistoryView {
case let .IntermediateMessageEntry(message, _):
var rebuild = false
for mediaId in message.referencedMedia {
if let media = updatedMedia[mediaId] where media?.id != mediaId {
if let media = updatedMedia[mediaId] , media?.id != mediaId {
rebuild = true
break
}
@ -315,7 +317,7 @@ final class MutableMessageHistoryView {
if rebuild {
var referencedMedia: [MediaId] = []
for mediaId in message.referencedMedia {
if let media = updatedMedia[mediaId] where media?.id != mediaId {
if let media = updatedMedia[mediaId] , media?.id != mediaId {
if let id = media?.id {
referencedMedia.append(id)
}
@ -381,12 +383,12 @@ final class MutableMessageHistoryView {
private func remove(_ indices: Set<MessageIndex>, context: MutableMessageHistoryViewReplayContext) -> Bool {
var hasChanges = false
if let earlier = self.earlier where indices.contains(earlier.index) {
if let earlier = self.earlier , indices.contains(earlier.index) {
context.invalidEarlier = true
hasChanges = true
}
if let later = self.later where indices.contains(later.index) {
if let later = self.later , indices.contains(later.index) {
context.invalidLater = true
hasChanges = true
}
@ -571,7 +573,7 @@ public final class MessageHistoryView {
self.combinedReadState = mutableView.combinedReadState
if let combinedReadState = mutableView.combinedReadState where combinedReadState.count != 0 {
if let combinedReadState = mutableView.combinedReadState , combinedReadState.count != 0 {
var maxIndex: MessageIndex?
for (namespace, state) in combinedReadState.states {
var maxNamespaceIndex: MessageIndex?
@ -593,16 +595,16 @@ public final class MessageHistoryView {
index += 1
}
}
if let _ = maxNamespaceIndex where index + 1 < entries.count {
if let _ = maxNamespaceIndex , index + 1 < entries.count {
for i in index + 1 ..< entries.count {
if case let .MessageEntry(message, _) = entries[i] where !message.flags.contains(.Incoming) {
if case let .MessageEntry(message, _) = entries[i] , !message.flags.contains(.Incoming) {
maxNamespaceIndex = MessageIndex(message)
} else {
break
}
}
}
if let maxNamespaceIndex = maxNamespaceIndex where maxIndex == nil || maxIndex! < maxNamespaceIndex {
if let maxNamespaceIndex = maxNamespaceIndex , maxIndex == nil || maxIndex! < maxNamespaceIndex {
maxIndex = maxNamespaceIndex
}
}

View File

@ -15,7 +15,7 @@ final class PeerChatStateTable: Table {
if let state = self.cachedPeerChatStates[id] {
return state
} else {
if let value = self.valueBox.get(self.tableId, key: self.key(id)), state = Decoder(buffer: value).decodeRootObject() {
if let value = self.valueBox.get(self.tableId, key: self.key(id)), let state = Decoder(buffer: value).decodeRootObject() {
self.cachedPeerChatStates[id] = state
return state
} else {
@ -38,7 +38,7 @@ final class PeerChatStateTable: Table {
override func beforeCommit() {
let sharedEncoder = Encoder()
for id in self.updatedPeerIds {
if let wrappedState = self.cachedPeerChatStates[id], state = wrappedState {
if let wrappedState = self.cachedPeerChatStates[id], let state = wrappedState {
sharedEncoder.reset()
sharedEncoder.encodeRootObject(state)
self.valueBox.set(self.tableId, key: self.key(id), value: sharedEncoder.readBufferNoCopy())

View File

@ -14,7 +14,7 @@ public protocol PeerChatState: Coding {
public final class Modifier {
private weak var postbox: Postbox?
private init(postbox: Postbox) {
fileprivate init(postbox: Postbox) {
self.postbox = postbox
}
@ -130,11 +130,11 @@ public final class Modifier {
}
}
private class PipeNotifier: NSObject {
fileprivate class PipeNotifier: NSObject {
let notifier: RLMNotifier
let thread: Thread
private init(basePath: String, notify: () -> Void) {
fileprivate init(basePath: String, notify: @escaping () -> Void) {
self.notifier = RLMNotifier(basePath: basePath, notify: notify)
self.thread = Thread(target: PipeNotifier.self, selector: #selector(PipeNotifier.threadEntry(_:)), object: self.notifier)
self.thread.start()
@ -304,7 +304,7 @@ public final class Postbox {
self.metadataTable = MetadataTable(valueBox: self.valueBox, tableId: 0)
let userVersion: Int32? = self.metadataTable.userVersion()
let currentUserVersion: Int32 = 6
let currentUserVersion: Int32 = 7
if userVersion != currentUserVersion {
self.valueBox.drop()
@ -365,17 +365,15 @@ public final class Postbox {
private var cachedState: Coding?
private func setState(_ state: Coding) {
self.modify({ modifier -> Void in
fileprivate func setState(_ state: Coding) {
self.cachedState = state
self.metadataTable.setState(state)
self.statePipe.putNext(state)
}).start()
}
private func getState() -> Coding? {
fileprivate func getState() -> Coding? {
if let cachedState = self.cachedState {
return cachedState
} else {
@ -388,6 +386,7 @@ public final class Postbox {
}
}
@available(*, deprecated: 1.0)
public func state() -> Signal<Coding?, NoError> {
return self.modify { modifier -> Signal<Coding?, NoError> in
return Signal<Coding?, NoError>.single(self.getState())
@ -407,15 +406,15 @@ public final class Postbox {
self.keychainTable.remove(key)
}
private func addMessages(_ messages: [StoreMessage], location: AddMessagesLocation) {
fileprivate func addMessages(_ messages: [StoreMessage], location: AddMessagesLocation) {
self.messageHistoryTable.addMessages(messages, location: location, operationsByPeerId: &self.currentOperationsByPeerId, unsentMessageOperations: &currentUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func addHole(_ id: MessageId) {
fileprivate func addHole(_ id: MessageId) {
self.messageHistoryTable.addHoles([id], operationsByPeerId: &self.currentOperationsByPeerId, unsentMessageOperations: &currentUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func fillHole(_ hole: MessageHistoryHole, fillType: HoleFill, tagMask: MessageTags?, messages: [StoreMessage]) {
fileprivate func fillHole(_ hole: MessageHistoryHole, fillType: HoleFill, tagMask: MessageTags?, messages: [StoreMessage]) {
var operationsByPeerId: [PeerId: [MessageHistoryOperation]] = [:]
self.messageHistoryTable.fillHole(hole.id, fillType: fillType, tagMask: tagMask, messages: messages, operationsByPeerId: &operationsByPeerId, unsentMessageOperations: &currentUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
for (peerId, operations) in operationsByPeerId {
@ -455,31 +454,31 @@ public final class Postbox {
}
}
private func replaceChatListHole(_ index: MessageIndex, hole: ChatListHole?) {
fileprivate func replaceChatListHole(_ index: MessageIndex, hole: ChatListHole?) {
self.currentReplaceChatListHoles.append((index, hole))
}
private func deleteMessages(_ messageIds: [MessageId]) {
fileprivate func deleteMessages(_ messageIds: [MessageId]) {
self.messageHistoryTable.removeMessages(messageIds, operationsByPeerId: &self.currentOperationsByPeerId, unsentMessageOperations: &currentUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func resetIncomingReadStates(_ states: [PeerId: [MessageId.Namespace: PeerReadState]]) {
fileprivate func resetIncomingReadStates(_ states: [PeerId: [MessageId.Namespace: PeerReadState]]) {
self.messageHistoryTable.resetIncomingReadStates(states, operationsByPeerId: &self.currentOperationsByPeerId, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func confirmSynchronizedIncomingReadState(_ peerId: PeerId) {
fileprivate func confirmSynchronizedIncomingReadState(_ peerId: PeerId) {
self.synchronizeReadStateTable.set(peerId, operation: nil, operations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func applyIncomingReadMaxId(_ messageId: MessageId) {
fileprivate func applyIncomingReadMaxId(_ messageId: MessageId) {
self.messageHistoryTable.applyIncomingReadMaxId(messageId, operationsByPeerId: &self.currentOperationsByPeerId, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func applyOutgoingReadMaxId(_ messageId: MessageId) {
fileprivate func applyOutgoingReadMaxId(_ messageId: MessageId) {
self.messageHistoryTable.applyOutgoingReadMaxId(messageId, operationsByPeerId: &self.currentOperationsByPeerId, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
private func applyInteractiveReadMaxId(_ messageId: MessageId) {
fileprivate func applyInteractiveReadMaxId(_ messageId: MessageId) {
self.messageHistoryTable.applyInteractiveMaxReadId(messageId, operationsByPeerId: &self.currentOperationsByPeerId, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
@ -648,7 +647,7 @@ public final class Postbox {
return self.messageHistoryTable.anchorIndex(id)
}
private func renderIntermediateMessage(_ message: IntermediateMessage) -> Message {
fileprivate func renderIntermediateMessage(_ message: IntermediateMessage) -> Message {
return self.messageHistoryTable.renderMessage(message, peerTable: self.peerTable)
}
@ -708,7 +707,7 @@ public final class Postbox {
return (updatedTransactionState, updatedMasterClientId)
}
private func messageIdsForGlobalIds(_ ids: [Int32]) -> [MessageId] {
fileprivate func messageIdsForGlobalIds(_ ids: [Int32]) -> [MessageId] {
var result: [MessageId] = []
for globalId in ids {
if let id = self.globalMessageIdsTable.get(globalId) {
@ -718,7 +717,7 @@ public final class Postbox {
return result
}
private func updatePeers(_ peers: [Peer], update: (Peer, Peer) -> Peer?) {
fileprivate func updatePeers(_ peers: [Peer], update: (Peer, Peer) -> Peer?) {
for peer in peers {
if let currentPeer = self.peerTable.get(peer.id) {
if let updatedPeer = update(currentPeer, peer) {
@ -731,28 +730,28 @@ public final class Postbox {
}
}
private func replaceContactPeerIds(_ peerIds: Set<PeerId>) {
fileprivate func replaceContactPeerIds(_ peerIds: Set<PeerId>) {
self.contactsTable.replace(peerIds)
self.currentReplacedContactPeerIds = peerIds
}
private func replaceRecentPeerIds(_ peerIds: [PeerId]) {
fileprivate func replaceRecentPeerIds(_ peerIds: [PeerId]) {
self.peerRatingTable.replace(items: peerIds)
}
private func updateMessage(_ index: MessageIndex, update: (Message) -> StoreMessage) {
fileprivate func updateMessage(_ index: MessageIndex, update: (Message) -> StoreMessage) {
if let intermediateMessage = self.messageHistoryTable.getMessage(index) {
let message = self.renderIntermediateMessage(intermediateMessage)
self.messageHistoryTable.updateMessage(index.id, message: update(message), operationsByPeerId: &self.currentOperationsByPeerId, unsentMessageOperations: &self.currentUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations)
}
}
private func updateMedia(_ id: MediaId, update: Media?) {
fileprivate func updateMedia(_ id: MediaId, update: Media?) {
self.messageHistoryTable.updateMedia(id, media: update, operationsByPeerId: &self.currentOperationsByPeerId, updatedMedia: &self.currentUpdatedMedia)
}
private func filterStoredMessageIds(_ messageIds: Set<MessageId>) -> Set<MessageId> {
fileprivate func filterStoredMessageIds(_ messageIds: Set<MessageId>) -> Set<MessageId> {
var filteredIds = Set<MessageId>()
for id in messageIds {
@ -764,7 +763,7 @@ public final class Postbox {
return filteredIds
}
public func modify<T>(_ f: (Modifier) -> T) -> Signal<T, NoError> {
public func modify<T>(_ f: @escaping(Modifier) -> T) -> Signal<T, NoError> {
return Signal { subscriber in
self.queue.justDispatch {
self.valueBox.begin()

View File

@ -3,6 +3,5 @@ module sqlcipher {
header "sqlcipher/sqlite3ext.h"
header "sqlcipher/SQLite-Bridging.h"
header "sqlcipher/fts3_tokenizer.h"
header "../../submodules/lmdb/libraries/liblmdb/lmdb.h"
export *
}

View File

@ -2,8 +2,8 @@ import Foundation
import SwiftSignalKit
public struct RandomAccessResourceStoreRange {
private let offset: Int
private let data: Data
fileprivate let offset: Int
fileprivate let data: Data
public init(offset: Int, data: Data) {
self.offset = offset
@ -19,16 +19,16 @@ public enum RandomAccessResourceDataRangeMode {
}
private final class RandomAccessBlockRangeListener: Hashable {
private let id: Int32
fileprivate let id: Int32
private let range: Range<Int>
private let blockSize: Int
private let blocks: Range<Int>
private let mode: RandomAccessResourceDataRangeMode
private let updated: (Data) -> Void
private var missingBlocks: Set<Int>
fileprivate var missingBlocks: Set<Int>
init(id: Int32, range: Range<Int>, blockSize: Int, blocks: Range<Int>, missingBlocks: Set<Int>, mode: RandomAccessResourceDataRangeMode, updated: (Data) -> Void) {
init(id: Int32, range: Range<Int>, blockSize: Int, blocks: Range<Int>, missingBlocks: Set<Int>, mode: RandomAccessResourceDataRangeMode, updated: @escaping(Data) -> Void) {
self.id = id
self.range = range
self.blockSize = blockSize
@ -42,7 +42,7 @@ private final class RandomAccessBlockRangeListener: Hashable {
return Int(self.id)
}
func updateMissingBlocks(addedBlocks: Set<Int>, fetchData: @noescape(Range<Int>) -> Data) {
func updateMissingBlocks(addedBlocks: Set<Int>, fetchData: (Range<Int>) -> Data) {
if self.missingBlocks.isEmpty {
return
}
@ -133,7 +133,7 @@ public final class RandomAccessMediaResourceContext {
private var fetchRange: (Range<Int>) -> Disposable
public init(path: String, size: Int, fetchRange: (Range<Int>) -> Disposable) {
public init(path: String, size: Int, fetchRange: @escaping(Range<Int>) -> Disposable) {
self.path = path
self.size = size
self.fetchRange = fetchRange
@ -308,7 +308,7 @@ public final class RandomAccessMediaResourceContext {
return result
}
public func addListenerForData(in range: Range<Int>, mode: RandomAccessResourceDataRangeMode, updated: (Data) -> Void) -> Int32 {
public func addListenerForData(in range: Range<Int>, mode: RandomAccessResourceDataRangeMode, updated: @escaping (Data) -> Void) -> Int32 {
let firstBlock = range.lowerBound / self.blockSize
let lastBlock = range.upperBound / self.blockSize + (range.upperBound % self.blockSize == 0 ? 0 : 1)

View File

@ -5,7 +5,7 @@ import SwiftSignalKit
private struct SqlitePreparedStatement {
let statement: OpaquePointer?
func bind(_ index: Int, data: UnsafePointer<Void>, length: Int) {
func bind(_ index: Int, data: UnsafeRawPointer, length: Int) {
sqlite3_bind_blob(statement, Int32(index), data, Int32(length), nil)
}
@ -101,9 +101,7 @@ public final class SqliteValueBox: ValueBox {
checkpoints.set(nil)
lock.lock()
do {
try FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
} catch _ { }
let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
let path = basePath + "/db_sqlite"
let database = Database(path)
@ -115,6 +113,16 @@ public final class SqliteValueBox: ValueBox {
database.execute("PRAGMA temp_store=MEMORY")
database.execute("PRAGMA wal_autocheckpoint=200")
database.execute("PRAGMA journal_size_limit=1536")
/*var statement: OpaquePointer? = nil
sqlite3_prepare_v2(database.handle, "PRAGMA integrity_check", -1, &statement, nil)
let preparedStatement = SqlitePreparedStatement(statement: statement)
if preparedStatement.step() {
let value = preparedStatement.stringAt(0)
print("integrity_check: \(value)")
}
preparedStatement.destroy()*/
sqlite3_busy_timeout(database.handle, 10000000)
let result = self.getUserVersion(database)
@ -129,7 +137,7 @@ public final class SqliteValueBox: ValueBox {
lock.unlock()
checkpoints.set((Signal<Void, NoError>.single(Void()) |> delay(10.0, queue: Queue.concurrentDefaultQueue()) |> restart).start(next: { [weak self] _ in
if let strongSelf = self where strongSelf.database != nil {
if let strongSelf = self , strongSelf.database != nil {
strongSelf.lock.lock()
var nLog: Int32 = 0
var nFrames: Int32 = 0

View File

@ -1,9 +1,9 @@
import Foundation
private final class ValueBoxKeyImpl {
let memory: UnsafeMutablePointer<Void>
let memory: UnsafeMutableRawPointer
init(memory: UnsafeMutablePointer<Void>) {
init(memory: UnsafeMutableRawPointer) {
self.memory = memory
}
@ -13,12 +13,12 @@ private final class ValueBoxKeyImpl {
}
public struct ValueBoxKey: Comparable, CustomStringConvertible {
public let memory: UnsafeMutablePointer<Void>
public let memory: UnsafeMutableRawPointer
public let length: Int
private let impl: ValueBoxKeyImpl
public init(length: Int) {
self.memory = malloc(length)
self.memory = malloc(length)!
self.length = length
self.impl = ValueBoxKeyImpl(memory: self.memory)
}
@ -28,7 +28,7 @@ public struct ValueBoxKey: Comparable, CustomStringConvertible {
self.memory = malloc(data.count)
self.length = data.count
self.impl = ValueBoxKeyImpl(memory: self.memory)
data.copyBytes(to: UnsafeMutablePointer<UInt8>(self.memory), count: data.count)
data.copyBytes(to: self.memory.assumingMemoryBound(to: UInt8.self), count: data.count)
}
public init(_ buffer: MemoryBuffer) {
@ -92,7 +92,7 @@ public struct ValueBoxKey: Comparable, CustomStringConvertible {
public var successor: ValueBoxKey {
let key = ValueBoxKey(length: self.length)
memcpy(key.memory, self.memory, self.length)
let memory = UnsafeMutablePointer<UInt8>(key.memory)
let memory = key.memory.assumingMemoryBound(to: UInt8.self)
var i = self.length - 1
while i >= 0 {
var byte = memory[i]
@ -112,7 +112,7 @@ public struct ValueBoxKey: Comparable, CustomStringConvertible {
public var predecessor: ValueBoxKey {
let key = ValueBoxKey(length: self.length)
memcpy(key.memory, self.memory, self.length)
let memory = UnsafeMutablePointer<UInt8>(key.memory)
let memory = key.memory.assumingMemoryBound(to: UInt8.self)
var i = self.length - 1
while i >= 0 {
var byte = memory[i]
@ -131,7 +131,7 @@ public struct ValueBoxKey: Comparable, CustomStringConvertible {
public var description: String {
let string = NSMutableString()
let memory = UnsafeMutablePointer<UInt8>(self.memory)
let memory = self.memory.assumingMemoryBound(to: UInt8.self)
for i in 0 ..< self.length {
let byte: Int = Int(memory[i])
string.appendFormat("%02x", byte)
@ -144,7 +144,7 @@ public func ==(lhs: ValueBoxKey, rhs: ValueBoxKey) -> Bool {
return lhs.length == rhs.length && memcmp(lhs.memory, rhs.memory, lhs.length) == 0
}
private func mdb_cmp_memn(_ a_memory: UnsafeMutablePointer<Void>, _ a_length: Int, _ b_memory: UnsafeMutablePointer<Void>, _ b_length: Int) -> Int
private func mdb_cmp_memn(_ a_memory: UnsafeMutableRawPointer, _ a_length: Int, _ b_memory: UnsafeMutableRawPointer, _ b_length: Int) -> Int
{
var diff: Int = 0
var len_diff: Int = 0

View File

@ -35,7 +35,7 @@ final class ViewTracker {
private var synchronizeReadStatesView: MutableSynchronizePeerReadStatesView
private let synchronizePeerReadStatesViewSubscribers = Bag<ValuePipe<SynchronizePeerReadStatesView>>()
init(queue: Queue, fetchEarlierHistoryEntries: (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchLaterHistoryEntries: (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchEarlierChatEntries: (MessageIndex?, Int) -> [MutableChatListEntry], fetchLaterChatEntries: (MessageIndex?, Int) -> [MutableChatListEntry], fetchAnchorIndex: (MessageId) -> MessageHistoryAnchorIndex?, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, unsentMessageIndices: [MessageIndex], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
init(queue: Queue, fetchEarlierHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchLaterHistoryEntries: @escaping (PeerId, MessageIndex?, Int, MessageTags?) -> [MutableMessageHistoryEntry], fetchEarlierChatEntries: @escaping (MessageIndex?, Int) -> [MutableChatListEntry], fetchLaterChatEntries: @escaping (MessageIndex?, Int) -> [MutableChatListEntry], fetchAnchorIndex: @escaping (MessageId) -> MessageHistoryAnchorIndex?, renderMessage: @escaping (IntermediateMessage) -> Message, getPeer: @escaping (PeerId) -> Peer?, unsentMessageIndices: [MessageIndex], synchronizePeerReadStateOperations: [PeerId: PeerReadStateSynchronizationOperation]) {
self.queue = queue
self.fetchEarlierHistoryEntries = fetchEarlierHistoryEntries
self.fetchLaterHistoryEntries = fetchLaterHistoryEntries
@ -142,7 +142,7 @@ final class ViewTracker {
}
}
func refreshViewsDueToExternalTransaction(fetchAroundChatEntries: (index: MessageIndex, count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?), fetchAroundHistoryEntries: (index: MessageIndex, count: Int, tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?), fetchUnsendMessageIndices: () -> [MessageIndex], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
func refreshViewsDueToExternalTransaction(fetchAroundChatEntries: (_ index: MessageIndex, _ count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?), fetchAroundHistoryEntries: (_ index: MessageIndex, _ count: Int, _ tagMask: MessageTags?) -> (entries: [MutableMessageHistoryEntry], lower: MutableMessageHistoryEntry?, upper: MutableMessageHistoryEntry?), fetchUnsendMessageIndices: () -> [MessageIndex], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
var updateTrackedHolesPeerIds: [PeerId] = []
for (peerId, bag) in self.messageHistoryViews {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,360 +0,0 @@
/** @file midl.c
* @brief ldap bdb back-end ID List functions */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2000-2014 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include "midl.h"
/** @defgroup internal LMDB Internals
* @{
*/
/** @defgroup idls ID List Management
* @{
*/
#define CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) )
unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id )
{
/*
* binary search of id in ids
* if found, returns position of id
* if not found, returns first position greater than id
*/
unsigned base = 0;
unsigned cursor = 1;
int val = 0;
unsigned n = ids[0];
while( 0 < n ) {
unsigned pivot = n >> 1;
cursor = base + pivot + 1;
val = CMP( ids[cursor], id );
if( val < 0 ) {
n = pivot;
} else if ( val > 0 ) {
base = cursor;
n -= pivot + 1;
} else {
return cursor;
}
}
if( val > 0 ) {
++cursor;
}
return cursor;
}
#if 0 /* superseded by append/sort */
int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
{
unsigned x, i;
x = mdb_midl_search( ids, id );
assert( x > 0 );
if( x < 1 ) {
/* internal error */
return -2;
}
if ( x <= ids[0] && ids[x] == id ) {
/* duplicate */
assert(0);
return -1;
}
if ( ++ids[0] >= MDB_IDL_DB_MAX ) {
/* no room */
--ids[0];
return -2;
} else {
/* insert id */
for (i=ids[0]; i>x; i--)
ids[i] = ids[i-1];
ids[x] = id;
}
return 0;
}
#endif
MDB_IDL mdb_midl_alloc(int num)
{
MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
if (ids) {
*ids++ = num;
*ids = 0;
}
return ids;
}
void mdb_midl_free(MDB_IDL ids)
{
if (ids)
free(ids-1);
}
int mdb_midl_shrink( MDB_IDL *idp )
{
MDB_IDL ids = *idp;
if (*(--ids) > MDB_IDL_UM_MAX &&
(ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(MDB_ID))))
{
*ids++ = MDB_IDL_UM_MAX;
*idp = ids;
return 1;
}
return 0;
}
static int mdb_midl_grow( MDB_IDL *idp, int num )
{
MDB_IDL idn = *idp-1;
/* grow it */
idn = realloc(idn, (*idn + num + 2) * sizeof(MDB_ID));
if (!idn)
return ENOMEM;
*idn++ += num;
*idp = idn;
return 0;
}
int mdb_midl_need( MDB_IDL *idp, unsigned num )
{
MDB_IDL ids = *idp;
num += ids[0];
if (num > ids[-1]) {
num = (num + num/4 + (256 + 2)) & -256;
if (!(ids = realloc(ids-1, num * sizeof(MDB_ID))))
return ENOMEM;
*ids++ = num - 2;
*idp = ids;
}
return 0;
}
int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
{
MDB_IDL ids = *idp;
/* Too big? */
if (ids[0] >= ids[-1]) {
if (mdb_midl_grow(idp, MDB_IDL_UM_MAX))
return ENOMEM;
ids = *idp;
}
ids[0]++;
ids[ids[0]] = id;
return 0;
}
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app )
{
MDB_IDL ids = *idp;
/* Too big? */
if (ids[0] + app[0] >= ids[-1]) {
if (mdb_midl_grow(idp, app[0]))
return ENOMEM;
ids = *idp;
}
memcpy(&ids[ids[0]+1], &app[1], app[0] * sizeof(MDB_ID));
ids[0] += app[0];
return 0;
}
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n )
{
MDB_ID *ids = *idp, len = ids[0];
/* Too big? */
if (len + n > ids[-1]) {
if (mdb_midl_grow(idp, n | MDB_IDL_UM_MAX))
return ENOMEM;
ids = *idp;
}
ids[0] = len + n;
ids += len;
while (n)
ids[n--] = id++;
return 0;
}
void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge )
{
MDB_ID old_id, merge_id, i = merge[0], j = idl[0], k = i+j, total = k;
idl[0] = (MDB_ID)-1; /* delimiter for idl scan below */
old_id = idl[j];
while (i) {
merge_id = merge[i--];
for (; old_id < merge_id; old_id = idl[--j])
idl[k--] = old_id;
idl[k--] = merge_id;
}
idl[0] = total;
}
/* Quicksort + Insertion sort for small arrays */
#define SMALL 8
#define MIDL_SWAP(a,b) { itmp=(a); (a)=(b); (b)=itmp; }
void
mdb_midl_sort( MDB_IDL ids )
{
/* Max possible depth of int-indexed tree * 2 items/level */
int istack[sizeof(int)*CHAR_BIT * 2];
int i,j,k,l,ir,jstack;
MDB_ID a, itmp;
ir = (int)ids[0];
l = 1;
jstack = 0;
for(;;) {
if (ir - l < SMALL) { /* Insertion sort */
for (j=l+1;j<=ir;j++) {
a = ids[j];
for (i=j-1;i>=1;i--) {
if (ids[i] >= a) break;
ids[i+1] = ids[i];
}
ids[i+1] = a;
}
if (jstack == 0) break;
ir = istack[jstack--];
l = istack[jstack--];
} else {
k = (l + ir) >> 1; /* Choose median of left, center, right */
MIDL_SWAP(ids[k], ids[l+1]);
if (ids[l] < ids[ir]) {
MIDL_SWAP(ids[l], ids[ir]);
}
if (ids[l+1] < ids[ir]) {
MIDL_SWAP(ids[l+1], ids[ir]);
}
if (ids[l] < ids[l+1]) {
MIDL_SWAP(ids[l], ids[l+1]);
}
i = l+1;
j = ir;
a = ids[l+1];
for(;;) {
do i++; while(ids[i] > a);
do j--; while(ids[j] < a);
if (j < i) break;
MIDL_SWAP(ids[i],ids[j]);
}
ids[l+1] = ids[j];
ids[j] = a;
jstack += 2;
if (ir-i+1 >= j-l) {
istack[jstack] = ir;
istack[jstack-1] = i;
ir = j-1;
} else {
istack[jstack] = j-1;
istack[jstack-1] = l;
l = i;
}
}
}
}
unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id )
{
/*
* binary search of id in ids
* if found, returns position of id
* if not found, returns first position greater than id
*/
unsigned base = 0;
unsigned cursor = 1;
int val = 0;
unsigned n = (unsigned)ids[0].mid;
while( 0 < n ) {
unsigned pivot = n >> 1;
cursor = base + pivot + 1;
val = CMP( id, ids[cursor].mid );
if( val < 0 ) {
n = pivot;
} else if ( val > 0 ) {
base = cursor;
n -= pivot + 1;
} else {
return cursor;
}
}
if( val > 0 ) {
++cursor;
}
return cursor;
}
int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id )
{
unsigned x, i;
x = mdb_mid2l_search( ids, id->mid );
if( x < 1 ) {
/* internal error */
return -2;
}
if ( x <= ids[0].mid && ids[x].mid == id->mid ) {
/* duplicate */
return -1;
}
if ( ids[0].mid >= MDB_IDL_UM_MAX ) {
/* too big */
return -2;
} else {
/* insert id */
ids[0].mid++;
for (i=(unsigned)ids[0].mid; i>x; i--)
ids[i] = ids[i-1];
ids[x] = *id;
}
return 0;
}
int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id )
{
/* Too big? */
if (ids[0].mid >= MDB_IDL_UM_MAX) {
return -2;
}
ids[0].mid++;
ids[ids[0].mid] = *id;
return 0;
}
/** @} */
/** @} */

View File

@ -1,186 +0,0 @@
/** @file midl.h
* @brief LMDB ID List header file.
*
* This file was originally part of back-bdb but has been
* modified for use in libmdb. Most of the macros defined
* in this file are unused, just left over from the original.
*
* This file is only used internally in libmdb and its definitions
* are not exposed publicly.
*/
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2000-2014 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#ifndef _MDB_MIDL_H_
#define _MDB_MIDL_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup internal LMDB Internals
* @{
*/
/** @defgroup idls ID List Management
* @{
*/
/** A generic unsigned ID number. These were entryIDs in back-bdb.
* Preferably it should have the same size as a pointer.
*/
typedef size_t MDB_ID;
/** An IDL is an ID List, a sorted array of IDs. The first
* element of the array is a counter for how many actual
* IDs are in the list. In the original back-bdb code, IDLs are
* sorted in ascending order. For libmdb IDLs are sorted in
* descending order.
*/
typedef MDB_ID *MDB_IDL;
/* IDL sizes - likely should be even bigger
* limiting factors: sizeof(ID), thread stack size
*/
#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)
#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))
#define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1)
#define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1)
#define MDB_IDL_SIZEOF(ids) (((ids)[0]+1) * sizeof(MDB_ID))
#define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 )
#define MDB_IDL_CPY( dst, src ) (memcpy( dst, src, MDB_IDL_SIZEOF( src ) ))
#define MDB_IDL_FIRST( ids ) ( (ids)[1] )
#define MDB_IDL_LAST( ids ) ( (ids)[(ids)[0]] )
/** Current max length of an #mdb_midl_alloc()ed IDL */
#define MDB_IDL_ALLOCLEN( ids ) ( (ids)[-1] )
/** Append ID to IDL. The IDL must be big enough. */
#define mdb_midl_xappend(idl, id) do { \
MDB_ID *xidl = (idl), xlen = ++(xidl[0]); \
xidl[xlen] = (id); \
} while (0)
/** Search for an ID in an IDL.
* @param[in] ids The IDL to search.
* @param[in] id The ID to search for.
* @return The index of the first ID greater than or equal to \b id.
*/
unsigned mdb_midl_search( MDB_IDL ids, MDB_ID id );
/** Allocate an IDL.
* Allocates memory for an IDL of the given size.
* @return IDL on success, NULL on failure.
*/
MDB_IDL mdb_midl_alloc(int num);
/** Free an IDL.
* @param[in] ids The IDL to free.
*/
void mdb_midl_free(MDB_IDL ids);
/** Shrink an IDL.
* Return the IDL to the default size if it has grown larger.
* @param[in,out] idp Address of the IDL to shrink.
* @return 0 on no change, non-zero if shrunk.
*/
int mdb_midl_shrink(MDB_IDL *idp);
/** Make room for num additional elements in an IDL.
* @param[in,out] idp Address of the IDL.
* @param[in] num Number of elements to make room for.
* @return 0 on success, ENOMEM on failure.
*/
int mdb_midl_need(MDB_IDL *idp, unsigned num);
/** Append an ID onto an IDL.
* @param[in,out] idp Address of the IDL to append to.
* @param[in] id The ID to append.
* @return 0 on success, ENOMEM if the IDL is too large.
*/
int mdb_midl_append( MDB_IDL *idp, MDB_ID id );
/** Append an IDL onto an IDL.
* @param[in,out] idp Address of the IDL to append to.
* @param[in] app The IDL to append.
* @return 0 on success, ENOMEM if the IDL is too large.
*/
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app );
/** Append an ID range onto an IDL.
* @param[in,out] idp Address of the IDL to append to.
* @param[in] id The lowest ID to append.
* @param[in] n Number of IDs to append.
* @return 0 on success, ENOMEM if the IDL is too large.
*/
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n );
/** Merge an IDL onto an IDL. The destination IDL must be big enough.
* @param[in] idl The IDL to merge into.
* @param[in] merge The IDL to merge.
*/
void mdb_midl_xmerge( MDB_IDL idl, MDB_IDL merge );
/** Sort an IDL.
* @param[in,out] ids The IDL to sort.
*/
void mdb_midl_sort( MDB_IDL ids );
/** An ID2 is an ID/pointer pair.
*/
typedef struct MDB_ID2 {
MDB_ID mid; /**< The ID */
void *mptr; /**< The pointer */
} MDB_ID2;
/** An ID2L is an ID2 List, a sorted array of ID2s.
* The first element's \b mid member is a count of how many actual
* elements are in the array. The \b mptr member of the first element is unused.
* The array is sorted in ascending order by \b mid.
*/
typedef MDB_ID2 *MDB_ID2L;
/** Search for an ID in an ID2L.
* @param[in] ids The ID2L to search.
* @param[in] id The ID to search for.
* @return The index of the first ID2 whose \b mid member is greater than or equal to \b id.
*/
unsigned mdb_mid2l_search( MDB_ID2L ids, MDB_ID id );
/** Insert an ID2 into a ID2L.
* @param[in,out] ids The ID2L to insert into.
* @param[in] id The ID2 to insert.
* @return 0 on success, -1 if the ID was already present in the ID2L.
*/
int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id );
/** Append an ID2 into a ID2L.
* @param[in,out] ids The ID2L to append into.
* @param[in] id The ID2 to append.
* @return 0 on success, -2 if the ID2L is too big.
*/
int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id );
/** @} */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* _MDB_MIDL_H_ */