Skip to content

Commit

Permalink
feat(database): sequence tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 6, 2024
1 parent 69ac82c commit 2abeded
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
21 changes: 11 additions & 10 deletions packages/database/src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,10 @@ export class SyncChannel {
}

async queue(session: Session) {
const message = Message.from(session.event.message!, session.platform)
const prev = this._hasLatest ? this._spans[0] : undefined
const message = Message.from(session.event.message!, session.platform, 'after', prev?.front[0])
const span = this.insert([message], 0)
if (this._hasLatest) {
span.prev = this._spans[1]
span.prev.next = span
}
span.link('prev', prev)
this._hasLatest = true
span.flush()
}
Expand All @@ -104,7 +102,7 @@ export class SyncChannel {
return [...before, message, ...after]
}

private async locate(id: string, direction: Universal.Direction, limit: number): Promise<[Span, MessageLike, boolean?]> {
private async locate(id: string, direction: Universal.Direction, limit?: number): Promise<[Span, MessageLike, boolean?]> {
// condition 1: message in memory
for (const span of this._spans) {
const message = span.data?.find(message => message.id === id)
Expand Down Expand Up @@ -145,14 +143,15 @@ export class SyncChannel {
for (let i = index - 1; i >= 0; i--) {
prev = this._spans.find(span => span.front[1] === result.data[i].id)
if (prev) break
data.unshift(Message.from(result.data[i], this.bot.platform))
// @ts-ignore
data.unshift(Message.from(result.data[i], this.bot.platform, 'before', data[0]?.sid))
}

let next: Span | undefined
for (let i = index + 1; i < result.data.length; i++) {
next = this._spans.find(span => span.back[1] === result.data[i].id)
if (next) break
data.push(Message.from(result.data[i], this.bot.platform))
data.push(Message.from(result.data[i], this.bot.platform, 'after', data[data.length - 1]?.sid))
}

if (data.length) {
Expand Down Expand Up @@ -230,13 +229,15 @@ export class SyncChannel {
span[dir.next] ??= await (span[`${dir.next}Task`] ??= (async (prev: Span) => {
const data: Message[] = []
const result = await this.bot.getMessageList(this.channelId, prev[dir.front][1], direction, limit - buffer.length, dir.asc)
let next: Span | undefined
let next: Span | undefined, last: Message | undefined
for (const item of result.data) {
next = this._spans.find(span => span[dir.back][1] === item.id)
if (next) break
data.push(Message.from(item, this.bot.platform))
last = Message.from(item, this.bot.platform, direction, last?.sid)
data[dir.push](last)
}
if (data.length) {
// TODO sync new span
const span = this.insert(data)
span.link(dir.prev, prev)
span.link(dir.next, next)
Expand Down
14 changes: 13 additions & 1 deletion packages/database/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,21 @@ export interface Message extends Universal.Message {
}

export namespace Message {
export const from = (message: Universal.Message, platform: string) => ({
export type Ref = ['before' | 'after', bigint]

function sequence(ts: bigint, dir?: 'before' | 'after', ref?: bigint) {
if (!dir || !ref) return (ts << 12n) + 0x800n
if (ts === ref >> 12n) {
return ref + (dir === 'before' ? -1n : 1n)
} else {
return (ts << 12n) + (dir === 'before' ? 0xfffn : 0n)
}
}

export const from = (message: Universal.Message, platform: string, dir?: 'before' | 'after', ref?: bigint) => ({
platform,
id: message.id,
sid: sequence(BigInt(message.timestamp!), dir, ref),
content: message.content,
timestamp: message.timestamp,
channel: { id: message.channel?.id },
Expand Down

0 comments on commit 2abeded

Please sign in to comment.