Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(889)

Unified Diff: web/inc/logdog-stream-view/viewer.ts

Issue 2861583003: Enable sequential prefix index logs to be loaded. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: web/inc/logdog-stream-view/viewer.ts
diff --git a/web/inc/logdog-stream-view/viewer.ts b/web/inc/logdog-stream-view/viewer.ts
index a171e85c615a025e32f63824988aadb1b4916430..dbe4dab5072d129035dc3083091a600c4706d9d8 100644
--- a/web/inc/logdog-stream-view/viewer.ts
+++ b/web/inc/logdog-stream-view/viewer.ts
@@ -998,6 +998,54 @@ namespace LogDog {
}
/**
+ * LogSorter is used to extract sorted logs from a set of BufferedLogs.
hinoka 2017/05/03 17:16:58 LogSorter is an interface used to....
dnj 2017/05/03 19:09:27 Done.
+ *
+ * LogSorter will modify the BufferedLogs, consuming the logs that it
hinoka 2017/05/03 17:16:58 A LogSorter which implements implicitNext() will m
dnj 2017/05/03 19:09:27 Done.
+ * returns from the buffer.
+ */
+ type LogSorter = {
+ compare: (a: LogDog.LogEntry, b: LogDog.LogEntry) => number;
+ implicitNext?: (prev: LogDog.LogEntry, buffers: BufferedLogs[]) =>
+ LogDog.LogEntry | null;
+ };
+
+ const prefixIndexLogSorter: LogSorter = {
+ compare: (a: LogDog.LogEntry, b: LogDog.LogEntry) => {
+ return (a.prefixIndex - b.prefixIndex);
+ },
+
+ implicitNext: (prev: LogDog.LogEntry, buffers: BufferedLogs[]) => {
+ let nextPrefixIndex = (prev.prefixIndex + 1);
+ for (let buf of buffers) {
+ let le = buf.peek();
+ if (le && le.prefixIndex === nextPrefixIndex) {
+ return buf.next();
+ }
+ }
+ return null;
+ },
+ };
+
+ const timestampLogSorter: LogSorter = {
+ compare: (a: LogDog.LogEntry, b: LogDog.LogEntry) => {
+ if (a.timestamp) {
+ if (b.timestamp) {
+ return a.timestamp.getTime() - b.timestamp.getTime();
+ }
+ return 1;
+ }
+ if (b.timestamp) {
+ return -1;
+ }
+ return 0;
+ },
+
+ // No implicit "next" with timestamp-based logs, since the next log in
+ // an empty buffer may actually be the next contiguous log.
+ implicitNext: undefined,
+ };
+
+ /**
* An aggregate log stream. It presents a single-stream view, but is really
* composed of several log streams interleaved based on their prefix indices
* (if they share a prefix) or timestamps (if they don't).
@@ -1014,7 +1062,7 @@ namespace LogDog {
private streams: AggregateLogStream.Entry[];
private active: AggregateLogStream.Entry[];
private currentNextPromise: Promise<BufferedLogs[]>|null;
- private compareLogs: (a: LogDog.LogEntry, b: LogDog.LogEntry) => number;
+ private readonly logSorter: LogSorter;
private streamStatusCallback: StreamStatusCallback;
@@ -1049,20 +1097,11 @@ namespace LogDog {
return template.samePrefixAs(entry.ls.stream);
});
- this.compareLogs = ((sharedPrefix) ? (a, b) => {
- return (a.prefixIndex - b.prefixIndex);
- } : (a, b) => {
- if (a.timestamp) {
- if (b.timestamp) {
- return a.timestamp.getTime() - b.timestamp.getTime();
- }
- return 1;
- } else if (b.timestamp) {
- return -1;
- } else {
- return 0;
- }
- });
+ if (sharedPrefix) {
+ this.logSorter = prefixIndexLogSorter;
+ } else {
+ this.logSorter = timestampLogSorter;
+ }
}
split(): SplitLogProvider|null {
@@ -1185,7 +1224,6 @@ namespace LogDog {
// its entries are sorted, then that buffer is a return value.
return new BufferedLogs(buffers[0].getAll());
default:
- // Nothing to do.
break;
}
@@ -1203,11 +1241,12 @@ namespace LogDog {
// Assemble our aggregate buffer array.
let entries: LogDog.LogEntry[] = [];
+ let last: LogDog.LogEntry|null = null;
hinoka 2017/05/03 17:16:58 how about "current"? "last" often implies "final",
dnj 2017/05/03 19:09:27 Renamed to "latestAdded".
while (true) {
// Choose the next stream.
let earliest = 0;
for (let i = 1; i < buffers.length; i++) {
- if (this.compareLogs(peek[i], peek[earliest]) < 0) {
+ if (this.logSorter.compare(peek[i], peek[earliest]) < 0) {
earliest = i;
}
}
@@ -1215,17 +1254,31 @@ namespace LogDog {
// Get the next log from the earliest stream.
let next = buffers[earliest].next();
if (next) {
- entries.push(next);
+ last = next;
+ entries.push(last);
}
// Repopulate that buffer's "peek" value. If the buffer has no more
- // entries, then we're done.
+ // entries, then we're done this round.
next = buffers[earliest].peek();
if (!next) {
- return new BufferedLogs(entries);
+ break;
}
peek[earliest] = next;
}
+
+ // One or more of our buffers is exhausted. If we have the ability to load
+ // implicit next logs, try and extract more using that.
+ if (last && this.logSorter.implicitNext) {
+ while (true) {
+ last = this.logSorter.implicitNext(last, buffers);
+ if (!last) {
+ break;
+ }
+ entries.push(last);
+ }
+ }
+ return new BufferedLogs(entries);
}
}
@@ -1287,6 +1340,14 @@ namespace LogDog {
}
/**
+ * Returns a copy of the remaining logs in the buffer.
+ * If there are no logs, an empty array will be returned.
+ */
+ peekAll(): LogDog.LogEntry[] {
+ return (this.logs || []).slice(0);
+ }
+
+ /**
* GetAll returns all logs in the buffer. Afterwards, the buffer will be
* empty.
*/
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698