Skip to content

Commit

Permalink
retrieve parent messages once and pass them around
Browse files Browse the repository at this point in the history
  • Loading branch information
rjwebb committed Jun 21, 2024
1 parent fe3feaf commit a2b470c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 32 deletions.
46 changes: 36 additions & 10 deletions packages/gossiplog/src/AbstractGossipLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ export type GossipLogEvents<Payload = unknown> = {
error: CustomEvent<{ error: Error }>
}

type MessageEntry<Payload> = {
id: string
signature: Signature
message: Message<Payload>
hash: string
branch: number
clock: number
}

export abstract class AbstractGossipLog<Payload = unknown> extends TypedEventEmitter<GossipLogEvents<Payload>> {
public static schema = {
$messages: {
Expand Down Expand Up @@ -246,9 +255,30 @@ export abstract class AbstractGossipLog<Payload = unknown> extends TypedEventEmi

const hash = toString(hashEntry(key, value), "hex")

const branch = await this.getBranch(id, message)
const parentMessageEntries: MessageEntry<Payload>[] = []
for (const parentId of message.parents) {
const parentMessageEntry = await this.db.get<MessageEntry<Payload>>("$messages", parentId)
if (parentMessageEntry === null) {
throw new Error(`missing parent ${parentId} of message ${id}`)
}
parentMessageEntries.push(parentMessageEntry)
}

await new BranchMergeIndex(this.db).insertBranchMerges(id, branch, message)
const branch = await this.getBranch(id, parentMessageEntries)

const branchMergeIndex = new BranchMergeIndex(this.db)
for (const parentMessageEntry of parentMessageEntries) {
if (parentMessageEntry.branch !== branch) {
await branchMergeIndex.insertBranchMerge({
source_branch: parentMessageEntry.branch,
source_clock: parentMessageEntry.clock,
source_message_id: parentMessageEntry.id,
target_branch: branch,
target_clock: message.clock,
target_message_id: id,
})
}
}

await this.db.set("$messages", { id, signature, message, hash, branch, clock: message.clock })

Expand All @@ -268,26 +298,22 @@ export abstract class AbstractGossipLog<Payload = unknown> extends TypedEventEmi
this.dispatchEvent(new CustomEvent("message", { detail: { id, signature, message } }))
}

private async getBranch(messageId: string, message: Message<any>) {
if (message.parents.length == 0) {
private async getBranch(messageId: string, parentMessages: MessageEntry<Payload>[]) {
if (parentMessages.length == 0) {
return await new BranchIndex(this.db).createNewBranch()
}

let maxBranch = -1
let parentMessageWithMaxClock: any = null
for (const parentId of message.parents) {
const parentMessage = await this.db.get("$messages", parentId)
if (parentMessage == null) {
throw new Error(`Parent message ${parentId} not found`)
}
for (const parentMessage of parentMessages) {
if (parentMessage.branch > maxBranch) {
parentMessageWithMaxClock = parentMessage
maxBranch = parentMessage.branch
}
}
const branch = maxBranch

const messagesAtBranchClockPosition = await this.db.query("$messages", {
const messagesAtBranchClockPosition = await this.db.query<MessageEntry<Payload>>("$messages", {
where: {
branch,
clock: {
Expand Down
22 changes: 0 additions & 22 deletions packages/gossiplog/src/BranchMergeIndex.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Message } from "@canvas-js/interfaces"
import type { AbstractModelDB, ModelsInit } from "@canvas-js/modeldb"

export type BranchMergeEntry = {
Expand All @@ -25,27 +24,6 @@ export class BranchMergeIndex {

constructor(private readonly db: AbstractModelDB) {}

public async insertBranchMerges(id: string, branch: number, message: Message<any>) {
for (const parentId of message.parents) {
const parentMessageResult = await this.db.get("$messages", parentId)
if (!parentMessageResult) {
throw new Error(`missing parent ${parentId} of message ${id}`)
}
const parentBranch = parentMessageResult.branch
const parentClock = parentMessageResult.message.clock
if (parentBranch !== branch) {
await this.insertBranchMerge({
source_branch: parentBranch,
source_clock: parentClock,
source_message_id: parentId,
target_branch: branch,
target_clock: message.clock,
target_message_id: id,
})
}
}
}

public async insertBranchMerge(entry: BranchMergeEntry) {
const id = `${entry.source_branch}:${entry.source_message_id}:${entry.target_branch}:${entry.target_message_id}`
await this.db.set("$branch_merges", { id, ...entry })
Expand Down

0 comments on commit a2b470c

Please sign in to comment.