use SortedArray in Timeline, adjust loadAtTop to use TimelineReader

This commit is contained in:
Bruno Windels 2019-06-01 17:39:23 +02:00
parent 843c94b750
commit 2a128ed32c

View file

@ -1,5 +1,6 @@
import { ObservableArray } from "../../../observable/index.js"; import { SortedArray } from "../../../observable/index.js";
import sortedIndex from "../../../utils/sortedIndex.js"; import EventKey from "./EventKey.js";
import Direction from "./Direction.js";
import GapWriter from "./persistence/GapWriter.js"; import GapWriter from "./persistence/GapWriter.js";
import TimelineReader from "./persistence/TimelineReader.js"; import TimelineReader from "./persistence/TimelineReader.js";
@ -8,8 +9,8 @@ export default class Timeline {
this._roomId = roomId; this._roomId = roomId;
this._storage = storage; this._storage = storage;
this._closeCallback = closeCallback; this._closeCallback = closeCallback;
this._entriesList = new ObservableArray();
this._fragmentIdComparer = fragmentIdComparer; this._fragmentIdComparer = fragmentIdComparer;
this._entriesList = new SortedArray((a, b) => a.compare(b));
this._timelineReader = new TimelineReader({ this._timelineReader = new TimelineReader({
roomId: this._roomId, roomId: this._roomId,
storage: this._storage, storage: this._storage,
@ -20,16 +21,12 @@ export default class Timeline {
/** @package */ /** @package */
async load() { async load() {
const entries = this._timelineReader.readFromEnd(100); const entries = this._timelineReader.readFromEnd(100);
for (const entry of entries) { this._entriesList.setManySorted(entries);
this._entriesList.append(entry);
}
} }
/** @package */ /** @package */
appendLiveEntries(newEntries) { appendLiveEntries(newEntries) {
for (const entry of newEntries) { this._entriesList.setManySorted(newEntries);
this._entriesList.append(entry);
}
} }
/** @public */ /** @public */
@ -46,26 +43,18 @@ export default class Timeline {
fragmentIdComparer: this._fragmentIdComparer fragmentIdComparer: this._fragmentIdComparer
}); });
const newEntries = await gapWriter.writerFragmentFill(fragmentEntry, response); const newEntries = await gapWriter.writerFragmentFill(fragmentEntry, response);
// find where to replace existing gap with newEntries by doing binary search this._entriesList.setManySorted(newEntries);
const gapIdx = sortedIndex(this._entriesList.array, fragmentEntry, (fragmentEntry, entry) => {
return fragmentEntry.compare(entry);
});
// only replace the gap if it's currently in the timeline
if (this._entriesList.at(gapIdx) === fragmentEntry) {
this._entriesList.removeAt(gapIdx);
this._entriesList.insertMany(gapIdx, newEntries);
}
} }
// tries to prepend `amount` entries to the `entries` list.
async loadAtTop(amount) { async loadAtTop(amount) {
// TODO: use TimelineReader::readFrom here, and insert returned array at location for first and last entry. if (this._entriesList.length() === 0) {
const firstEntry = this._entriesList.at(0); return;
if (firstEntry) {
const txn = await this._storage.readTxn([this._storage.storeNames.timelineEvents]);
const topEntries = await txn.roomTimeline.eventsBefore(this._roomId, firstEntry.sortKey, amount);
this._entriesList.insertMany(0, topEntries);
return topEntries.length;
} }
const firstEntry = this._entriesList.array()[0];
const firstKey = new EventKey(firstEntry.fragmentId, firstEntry.eventIndex);
const entries = await this._timelineReader.readFrom(firstKey, Direction.Backward, amount);
this._entriesList.setManySorted(entries);
} }
/** @public */ /** @public */