Testing out timeline merging

This commit is contained in:
tezlm 2023-12-28 06:10:46 -08:00
parent c292609a6d
commit 5966e2cd9d
Signed by: tezlm
GPG key ID: 649733FCD94AFBBA
5 changed files with 72 additions and 162 deletions

108
dist/src/timeline.js vendored
View file

@ -171,9 +171,12 @@ export class ThreadTimeline extends Timeline {
for (const event of events) {
const existing = this.timelineSet.timelineMap.get(event.id);
if (existing) {
const otherIdx = existing.getEvents().indexOf(event);
if (otherIdx === -1)
continue;
// TODO
// const merged = merge(this.timelineSet, this);
// if (merged !== this) {
// this.emit("timelineReplace", merged);
// return 0;
// }
}
else {
this.timelineSet.timelineMap.set(event.id, this);
@ -196,7 +199,7 @@ class TimelineSet {
return null;
}
}
function merge2(timelines, tl) {
function merge(timelines, tl) {
// [_, _, 2, 3, 4, 5, _, _, _] (current)
// [_, _, _, 3, 4, 5, 6, 7, 8] (other1)
// [0, 1, 2, 3, 4, _, _, _, _] (other2)
@ -206,83 +209,43 @@ function merge2(timelines, tl) {
// event = 2, thisIdx = 0, otherIdx2 = 2
// event = 2, thisIdx = 0, otherIdx3 = 2
// event = 2, thisIdx = 0, otherIdx4 = 0
// [1, 2] + [4, 5] (events = [2, 3, 4])
const events = tl._eventList;
// let otherTl;
for (const event of events) {
for (let idx = 0; idx < events.length; idx++) {
const event = events[idx];
const other = timelines.timelineMap.get(event.id);
if (!other)
continue;
if (tl === other)
continue;
// console.log("merge ", tl, other);
const idx = other._eventList.indexOf(event);
other._eventList.unshift(...events.slice(0, idx));
other.isAtBeginning = tl.isAtBeginning;
for (const event of events.slice(0, idx)) {
timelines.timelineMap.set(event.id, other);
}
timelines.timelines.delete(tl);
tl.emit("timelineReplace", other);
tl = other;
}
// do it again because a thread can overlap 2 threads (before and after)
// maybe this works?
for (let idx = 0; idx < events.length; idx++) {
const event = events[idx];
const other = timelines.timelineMap.get(event.id);
if (!other)
continue;
if (tl === other)
continue;
other._eventList.unshift(...events.slice(0, idx));
other.isAtBeginning = tl.isAtBeginning;
for (const event of events.slice(0, idx)) {
timelines.timelineMap.set(event.id, other);
}
timelines.timelines.delete(tl);
tl.emit("timelineReplace", other);
tl = other;
}
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// console.log("merge ", tl, other);
// // const idx = other._eventList.indexOf(event);
// // other._eventList.splice(idx, other._eventList.length - idx);
// // other._eventList.push(...events.slice(idx));
// other.isAtEnd = tl.isAtEnd;
// tl = other;
// }
// for (let i = events.length - 1; i >= 0; i--) {
// const event = events[i];
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// const idx = other._eventList.lastIndexOf(event);
// other._eventList.push(...events.slice(idx));
// for (const event of events.slice(0, idx)) {
// timelines.timelineMap.set(event.id, other);
// }
// timelines.timelines.delete(tl);
// tl = other;
// }
return tl;
}
// function merge(timelines: ThreadTimelineSet, events: Array<Event>): ThreadTimeline | null {
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// console.log("merge earliest with ", other);
// const idx = other._eventList.indexOf(event);
// other._eventList.unshift(...events.slice(0, idx));
// other.isAtBeginning = true;
// return other;
// }
// return null;
// }
// const realTimeline = merge(this, tl._eventList) ?? tl;
// function merge(timelines: ThreadTimelineSet, events: Array<Event>): ThreadTimeline | null {
// // [_, _, _, _, (4), 5, 6, 7]
// // [0, 1, 2, 3, 4 , 5]
// // ^
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// console.log("merge live with ", other);
// const idx = other._eventList.indexOf(event);
// other._eventList.splice(idx, other._eventList.length - idx); // delete 4, 5
// other._eventList.push(...events.slice(idx)); // push 4, 5, 6, 7
// other.isAtEnd = true;
// return other;
// }
// return null;
// }
// const realTimeline = merge(this, tl._eventList);
export class ThreadTimelineSet extends TimelineSet {
constructor(thread) {
super();
@ -322,14 +285,14 @@ export class ThreadTimelineSet extends TimelineSet {
this.timelines.add(this.live);
}
async fetch(at, limit = 50) {
console.log("FETCH");
if (at === "end") {
const fetchCount = limit - this.live.getEvents().length;
if (fetchCount > 0)
await this.live.paginate("b", fetchCount);
return this.live;
const tl = this.live;
const realTimeline = merge2(this, tl);
if (realTimeline) {
const realTimeline = merge(this, tl);
if (realTimeline !== tl) {
this.timelines.delete(tl);
this.live = realTimeline;
}
@ -345,15 +308,16 @@ export class ThreadTimelineSet extends TimelineSet {
}
else {
const tl = new ThreadTimeline(this, this.thread);
await tl.paginate("b", limit);
this.timelines.add(tl);
return tl;
const realTimeline = merge2(this, tl) ?? tl;
await tl.paginate("f", limit);
const realTimeline = merge(this, tl);
if (realTimeline !== tl)
this.timelines.add(realTimeline);
return realTimeline;
}
}
else {
// TODO: respect limit?
// TODO: merge threads
const existing = this.timelineMap.get(at);
if (existing) {
const fetchCount = limit - existing.getEvents().length;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -143,8 +143,12 @@ export class ThreadTimeline extends Timeline implements TypedEmitter<TimelineEve
for (const event of events) {
const existing = this.timelineSet.timelineMap.get(event.id);
if (existing) {
const otherIdx = existing.getEvents().indexOf(event);
if (otherIdx === -1) continue;
// TODO
// const merged = merge(this.timelineSet, this);
// if (merged !== this) {
// this.emit("timelineReplace", merged);
// return 0;
// }
} else {
this.timelineSet.timelineMap.set(event.id, this);
room.events.set(event.id, event);
@ -170,7 +174,7 @@ abstract class TimelineSet {
}
}
function merge2(timelines: ThreadTimelineSet, tl: ThreadTimeline): ThreadTimeline {
function merge(timelines: ThreadTimelineSet, tl: ThreadTimeline): ThreadTimeline {
// [_, _, 2, 3, 4, 5, _, _, _] (current)
// [_, _, _, 3, 4, 5, 6, 7, 8] (other1)
// [0, 1, 2, 3, 4, _, _, _, _] (other2)
@ -181,18 +185,14 @@ function merge2(timelines: ThreadTimelineSet, tl: ThreadTimeline): ThreadTimelin
// event = 2, thisIdx = 0, otherIdx3 = 2
// event = 2, thisIdx = 0, otherIdx4 = 0
// [1, 2] + [4, 5] (events = [2, 3, 4])
const events = tl._eventList;
// let otherTl;
for (const event of events) {
for (let idx = 0; idx < events.length; idx++) {
const event = events[idx];
const other = timelines.timelineMap.get(event.id);
if (!other) continue;
if (tl === other) continue;
// console.log("merge ", tl, other);
const idx = other._eventList.indexOf(event);
other._eventList.unshift(...events.slice(0, idx));
other.isAtBeginning = tl.isAtBeginning;
@ -200,82 +200,32 @@ function merge2(timelines: ThreadTimelineSet, tl: ThreadTimeline): ThreadTimelin
timelines.timelineMap.set(event.id, other);
}
timelines.timelines.delete(tl);
tl.emit("timelineReplace", other);
tl = other;
}
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// do it again because a thread can overlap 2 threads (before and after)
// maybe this works?
for (let idx = 0; idx < events.length; idx++) {
const event = events[idx];
const other = timelines.timelineMap.get(event.id);
if (!other) continue;
if (tl === other) continue;
// console.log("merge ", tl, other);
// // const idx = other._eventList.indexOf(event);
// // other._eventList.splice(idx, other._eventList.length - idx);
// // other._eventList.push(...events.slice(idx));
// other.isAtEnd = tl.isAtEnd;
other._eventList.unshift(...events.slice(0, idx));
other.isAtBeginning = tl.isAtBeginning;
// tl = other;
// }
// for (let i = events.length - 1; i >= 0; i--) {
// const event = events[i];
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// const idx = other._eventList.lastIndexOf(event);
// other._eventList.push(...events.slice(idx));
// for (const event of events.slice(0, idx)) {
// timelines.timelineMap.set(event.id, other);
// }
// timelines.timelines.delete(tl);
// tl = other;
// }
for (const event of events.slice(0, idx)) {
timelines.timelineMap.set(event.id, other);
}
timelines.timelines.delete(tl);
tl.emit("timelineReplace", other);
tl = other;
}
return tl;
}
// function merge(timelines: ThreadTimelineSet, events: Array<Event>): ThreadTimeline | null {
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// console.log("merge earliest with ", other);
// const idx = other._eventList.indexOf(event);
// other._eventList.unshift(...events.slice(0, idx));
// other.isAtBeginning = true;
// return other;
// }
// return null;
// }
// const realTimeline = merge(this, tl._eventList) ?? tl;
// function merge(timelines: ThreadTimelineSet, events: Array<Event>): ThreadTimeline | null {
// // [_, _, _, _, (4), 5, 6, 7]
// // [0, 1, 2, 3, 4 , 5]
// // ^
// for (const event of events) {
// const other = timelines.timelineMap.get(event.id);
// if (!other) continue;
// if (tl === other) continue;
// console.log("merge live with ", other);
// const idx = other._eventList.indexOf(event);
// other._eventList.splice(idx, other._eventList.length - idx); // delete 4, 5
// other._eventList.push(...events.slice(idx)); // push 4, 5, 6, 7
// other.isAtEnd = true;
// return other;
// }
// return null;
// }
// const realTimeline = merge(this, tl._eventList);
export class ThreadTimelineSet extends TimelineSet {
// This is the one live timeline
public client = this.thread.room.client;
@ -291,15 +241,13 @@ export class ThreadTimelineSet extends TimelineSet {
}
public async fetch(at: EventId | "start" | "end", limit = 50): Promise<ThreadTimeline> {
console.log("FETCH");
if (at === "end") {
const fetchCount = limit - this.live.getEvents().length;
if (fetchCount > 0) await this.live.paginate("b", fetchCount);
return this.live;
const tl = this.live;
const realTimeline = merge2(this, tl);
if (realTimeline) {
const realTimeline = merge(this, tl);
if (realTimeline !== tl) {
this.timelines.delete(tl);
this.live = realTimeline;
}
@ -312,14 +260,14 @@ export class ThreadTimelineSet extends TimelineSet {
return existing;
} else {
const tl = new ThreadTimeline(this, this.thread);
await tl.paginate("b", limit);
this.timelines.add(tl);
return tl;
const realTimeline = merge2(this, tl) ?? tl;
await tl.paginate("f", limit);
const realTimeline = merge(this, tl);
if (realTimeline !== tl) this.timelines.add(realTimeline);
return realTimeline;
}
} else {
// TODO: respect limit?
// TODO: merge threads
const existing = this.timelineMap.get(at);
if (existing) {
const fetchCount = limit - existing.getEvents().length;

View file

@ -17,8 +17,6 @@
/* Linting */
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
},
"include": ["src"],