Skip to content

Commit 11c58ab

Browse files
authored
Merge pull request #132 from tinode/fixes2
Logic to detect sequence id gaps in cached messages.
2 parents dd0c025 + 326f923 commit 11c58ab

File tree

5 files changed

+45
-6
lines changed

5 files changed

+45
-6
lines changed

TinodeSDK/Storage.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ public protocol Storage: class {
8282

8383
// Get seq IDs of the stored messages as a Range.
8484
func getCachedMessagesRange(topic: TopicProto) -> MsgRange?
85+
// Get the maximum seq ID range of the messages missing in cache,
86+
// inclusive-exclusive [low, hi).
87+
// Returns null if all messages are present or no messages are found.
88+
func getNextMissingRange(topic: TopicProto) -> MsgRange?
8589
// Local user reported messages as read.
8690
@discardableResult
8791
func setRead(topic: TopicProto, read: Int) -> Bool

TinodeSDK/Topic.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public protocol TopicProto: class {
3131
var lastSeen: LastSeen? { get set }
3232
var online: Bool { get set }
3333
var cachedMessageRange: MsgRange? { get }
34+
var missingMessageRange: MsgRange? { get }
3435
var isArchived: Bool { get }
3536
var isJoiner: Bool { get }
3637
var isReader: Bool { get }
@@ -131,8 +132,8 @@ open class Topic<DP: Codable & Mergeable, DR: Codable & Mergeable, SP: Codable,
131132
return self
132133
}
133134
public func withEarlierData(limit: Int?) -> MetaGetBuilder {
134-
if let r = topic.cachedMessageRange {
135-
return withData(since: nil, before: r.low != 0 ? r.low : nil, limit: limit)
135+
if let r = topic.missingMessageRange, r.low >= 1 {
136+
return withData(since: r.lower, before: r.upper, limit: limit)
136137
}
137138
return withData(since: nil, before: nil, limit: limit)
138139
}
@@ -366,9 +367,11 @@ open class Topic<DP: Codable & Mergeable, DR: Codable & Mergeable, SP: Codable,
366367
public var isPersisted: Bool { get { return payload != nil } }
367368

368369
public var cachedMessageRange: MsgRange? {
369-
get {
370-
return store?.getCachedMessagesRange(topic: self)
371-
}
370+
return store?.getCachedMessagesRange(topic: self)
371+
}
372+
373+
public var missingMessageRange: MsgRange? {
374+
return store?.getNextMissingRange(topic: self)
372375
}
373376

374377
// Tells how many topic subscribers have reported the message as read or received.

Tinodios/MessageViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class MessageViewController: UIViewController {
9494
// Insets around content inside the message bubble.
9595
static let kIncomingMessageContentInset = UIEdgeInsets(top: 4, left: 18, bottom: 13, right: 14)
9696
static let kOutgoingMessageContentInset = UIEdgeInsets(top: 4, left: 14, bottom: 13, right: 18)
97-
static let kDeletedMessageContentInset = UIEdgeInsets(top: 4, left: 14, bottom: 4, right: 14)
97+
static let kDeletedMessageContentInset = UIEdgeInsets(top: 4, left: 14, bottom: 0, right: 14)
9898

9999
// Carve out for timestamp and delivery marker in the bottom-right corner.
100100
static let kIncomingMetadataCarveout = " "

TinodiosDB/MessageDb.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,31 @@ public class MessageDb {
353353
return nil
354354
}
355355
}
356+
357+
func fetchNextMissingRange(topicId: Int64) -> MsgRange? {
358+
let messages2 = self.table.alias("m2")
359+
let hiQuery = self.table
360+
.join(.leftOuter, messages2,
361+
on: self.table[self.seq] == (messages2[self.high] ?? messages2[self.seq] + 1) && messages2[self.topicId] == topicId)
362+
.filter(self.table[self.topicId] == topicId &&
363+
self.table[self.seq] > 1 &&
364+
messages2[self.seq] == nil)
365+
366+
guard let hi = try? db.scalar(hiQuery.select(self.seq.max)) else {
367+
// No gap is found.
368+
return nil
369+
}
370+
// Find the first present message with ID less than the 'high'.
371+
let seqExpr = self.high ?? (self.seq + 1)
372+
let lowQuery = self.table
373+
.filter(self.topicId == topicId && self.seq < hi)
374+
let low: Int
375+
if let low2 = try? db.scalar(lowQuery.select(seqExpr.max)) {
376+
// Low is inclusive thus +1.
377+
low = low2 + 1
378+
} else {
379+
low = 1
380+
}
381+
return MsgRange(low: low, hi: hi)
382+
}
356383
}

TinodiosDB/SqlStore.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ public class SqlStore : Storage {
9696
return MsgRange(low: st.minLocalSeq ?? 0, hi: (st.maxLocalSeq ?? 0) + 1)
9797
}
9898

99+
public func getNextMissingRange(topic: TopicProto) -> MsgRange? {
100+
guard let st = topic.payload as? StoredTopic, let topicId = st.id, topicId > 0 else { return nil }
101+
return dbh?.messageDb?.fetchNextMissingRange(topicId: topicId)
102+
}
103+
99104
public func setRead(topic: TopicProto, read: Int) -> Bool {
100105
guard let st = topic.payload as? StoredTopic,
101106
let topicId = st.id, topicId > 0 else { return false }

0 commit comments

Comments
 (0)