querysub 0.395.0 → 0.397.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
1
  import { Querysub } from "../../../4-querysub/QuerysubController";
2
2
  import { getTimeRange } from "../TimeRangeSelector";
3
- import { URLParam } from "../../../library-components/URLParam";
4
3
  import { throttleFunction, sort } from "socket-function/src/misc";
5
4
  import { getLoggers2Async, LogDatum } from "../diskLogger";
6
5
  import { IndexedLogResults, createEmptyIndexedLogResults, mergeIndexedLogResults } from "../IndexedLogs/BufferIndexHelpers";
@@ -11,8 +10,7 @@ import { createMatchesPatternCached } from "../IndexedLogs/bufferSearchFindMatch
11
10
  import { getPathStr } from "../../../path";
12
11
  import { LifeCycle, LifeCycleEntry, LifeCyclesController } from "./lifeCycles";
13
12
 
14
- export let limitURL = new URLParam("lifecyclelimit", 100);
15
- export let additionalSearchURL = new URLParam("lifecyclesearch", "");
13
+ const PHASE_2_FACTOR = 100;
16
14
 
17
15
  type LifecycleInstance = {
18
16
  key: string;
@@ -23,8 +21,8 @@ type LifecycleInstance = {
23
21
  }[];
24
22
  isComplete?: boolean;
25
23
  isTruncated?: boolean;
26
- isWarning?: boolean;
27
- warningMessage?: string;
24
+ isMissingStart?: boolean;
25
+ isMissingEnd?: boolean;
28
26
  startTime: number;
29
27
  endTime?: number;
30
28
  };
@@ -41,12 +39,40 @@ export function createLifeCycleSearch(
41
39
  phase2Results: LogDatum[];
42
40
  phase2Stats: IndexedLogResults | undefined;
43
41
  phase2Searching: boolean;
42
+ phase2HitLimit: boolean;
44
43
  lifecycleInstances: LifecycleInstance[];
45
44
  };
46
45
  }
47
46
  ) {
48
47
  let searchSequenceNumber = 0;
49
48
 
49
+ let clearSearchingFlags = () => {
50
+ context.state.phase1Searching = false;
51
+ context.state.phase2Searching = false;
52
+ context.state.phase2HitLimit = false;
53
+ };
54
+
55
+ let resetAllSearchState = (lifeCycleId?: string) => {
56
+ context.state.searchingLifeCycleId = lifeCycleId;
57
+ context.state.lifecycleInstances = [];
58
+ resetPhase1State();
59
+ resetPhase2State();
60
+ };
61
+
62
+ let resetPhase1State = () => {
63
+ context.state.phase1Searching = true;
64
+ context.state.phase1Results = [];
65
+ context.state.phase1InvalidResults = [];
66
+ context.state.phase1Stats = undefined;
67
+ };
68
+
69
+ let resetPhase2State = () => {
70
+ context.state.phase2Searching = true;
71
+ context.state.phase2Results = [];
72
+ context.state.phase2Stats = undefined;
73
+ context.state.phase2HitLimit = false;
74
+ };
75
+
50
76
  let cancel = async () => {
51
77
  searchSequenceNumber++;
52
78
  let loggers = await getLoggers2Async();
@@ -54,14 +80,18 @@ export function createLifeCycleSearch(
54
80
  logger.clientCancelAllCallbacks();
55
81
  }
56
82
  Querysub.commitLocal(() => {
57
- context.state.phase1Searching = false;
58
- context.state.phase2Searching = false;
83
+ clearSearchingFlags();
59
84
  });
60
85
  };
61
86
 
62
87
  // Entry point for lifecycle search. Currently only supports "find all" mode by passing empty seedDatums.
63
88
  // Future: Will be parameterized to accept specific log datums from other pages.
64
- let searchLifeCycle = async (lifeCycleId: string) => {
89
+ let searchLifeCycle = async (params: {
90
+ lifeCycleId: string;
91
+ additionalSearch: string;
92
+ limit: number;
93
+ }) => {
94
+ let { lifeCycleId, additionalSearch, limit } = params;
65
95
  let lifeCycles = await context.controller.getLifeCycles.promise();
66
96
  if (!lifeCycles) return;
67
97
 
@@ -75,13 +105,7 @@ export function createLifeCycleSearch(
75
105
  await cancel();
76
106
 
77
107
  Querysub.commitLocal(() => {
78
- context.state.searchingLifeCycleId = lifeCycleId;
79
- context.state.phase1Results = [];
80
- context.state.phase1InvalidResults = [];
81
- context.state.phase1Stats = undefined;
82
- context.state.phase2Results = [];
83
- context.state.phase2Stats = undefined;
84
- context.state.lifecycleInstances = [];
108
+ resetAllSearchState(lifeCycleId);
85
109
  });
86
110
 
87
111
  searchSequenceNumber++;
@@ -90,6 +114,8 @@ export function createLifeCycleSearch(
90
114
  let phase1Results = await searchPhase1({
91
115
  lifeCycle,
92
116
  currentSequenceNumber,
117
+ additionalSearch,
118
+ limit,
93
119
  });
94
120
 
95
121
  if (searchSequenceNumber !== currentSequenceNumber) return;
@@ -102,6 +128,7 @@ export function createLifeCycleSearch(
102
128
  lifeCycle,
103
129
  phase1Results,
104
130
  currentSequenceNumber,
131
+ limit,
105
132
  });
106
133
 
107
134
  if (searchSequenceNumber !== currentSequenceNumber) return;
@@ -123,8 +150,10 @@ export function createLifeCycleSearch(
123
150
  let searchPhase1 = async (params: {
124
151
  lifeCycle: LifeCycle;
125
152
  currentSequenceNumber: number;
153
+ additionalSearch: string;
154
+ limit: number;
126
155
  }) => {
127
- let { lifeCycle, currentSequenceNumber } = params;
156
+ let { lifeCycle, currentSequenceNumber, additionalSearch, limit } = params;
128
157
  let startEntries = lifeCycle.entries.filter(e => e.isStart);
129
158
 
130
159
  if (startEntries.length === 0) {
@@ -132,14 +161,10 @@ export function createLifeCycleSearch(
132
161
  }
133
162
 
134
163
  Querysub.commitLocal(() => {
135
- context.state.phase1Searching = true;
136
- context.state.phase1Results = [];
137
- context.state.phase1InvalidResults = [];
138
- context.state.phase1Stats = undefined;
164
+ resetPhase1State();
139
165
  });
140
166
 
141
167
  let searchQuery = startEntries.map(entry => entry.matchPattern).join("|");
142
- let additionalSearch = additionalSearchURL.value.trim();
143
168
  if (additionalSearch) {
144
169
  searchQuery = searchQuery + "&" + additionalSearch;
145
170
  }
@@ -201,7 +226,7 @@ export function createLifeCycleSearch(
201
226
  params: {
202
227
  startTime: range.startTime,
203
228
  endTime: range.endTime,
204
- limit: limitURL.value,
229
+ limit: limit,
205
230
  findBuffer: searchBuffer,
206
231
  searchFromStart: range.searchFromStart,
207
232
  },
@@ -272,17 +297,16 @@ export function createLifeCycleSearch(
272
297
  lifeCycle: LifeCycle;
273
298
  phase1Results: LogDatum[];
274
299
  currentSequenceNumber: number;
300
+ limit: number;
275
301
  }): Promise<{ results: LogDatum[]; hitLimit: boolean }> => {
276
- let { lifeCycle, phase1Results, currentSequenceNumber } = params;
302
+ let { lifeCycle, phase1Results, currentSequenceNumber, limit } = params;
277
303
 
278
304
  if (phase1Results.length === 0) {
279
305
  return { results: [], hitLimit: false };
280
306
  }
281
307
 
282
308
  Querysub.commitLocal(() => {
283
- context.state.phase2Searching = true;
284
- context.state.phase2Results = [];
285
- context.state.phase2Stats = undefined;
309
+ resetPhase2State();
286
310
  });
287
311
 
288
312
  let allResults: LogDatum[] = [];
@@ -391,7 +415,7 @@ export function createLifeCycleSearch(
391
415
 
392
416
  let results: LogDatum[] = [];
393
417
  let done = false;
394
- let searchLimit = limitURL.value * lifeCycle.entries.length * queries.size * 3;
418
+ let searchLimit = Math.ceil(limit * lifeCycle.entries.length * PHASE_2_FACTOR);
395
419
  let result = await errorToUndefined(logger.clientFind({
396
420
  params: {
397
421
  startTime: range.startTime,
@@ -426,6 +450,7 @@ export function createLifeCycleSearch(
426
450
  Querysub.commitLocal(() => {
427
451
  context.state.phase2Results = allResults;
428
452
  context.state.phase2Searching = false;
453
+ context.state.phase2HitLimit = anyHitLimit;
429
454
  });
430
455
 
431
456
  return { results: allResults, hitLimit: anyHitLimit };
@@ -463,7 +488,7 @@ export function createLifeCycleSearch(
463
488
  keyValuePairs.push({ key: keyConfig.ourKey, value });
464
489
  }
465
490
  if (!hasAllKeys) continue;
466
- let compositeKey = getPathStr(keyValuePairs.flatMap(kv => [kv.key, String(kv.value)]));
491
+ let keyHash = getPathStr(keyValuePairs.flatMap(kv => [kv.key, String(kv.value)]));
467
492
 
468
493
  let matchStr = String(datum.param0);
469
494
  let matchBuffer = Buffer.from(matchStr, "utf8");
@@ -472,10 +497,10 @@ export function createLifeCycleSearch(
472
497
  let matcher = createMatchesPatternCached(entry.matchPattern);
473
498
  if (!matcher(matchBuffer)) continue;
474
499
 
475
- let instanceList = instancesByKey.get(compositeKey);
500
+ let instanceList = instancesByKey.get(keyHash);
476
501
  if (!instanceList) {
477
502
  instanceList = [];
478
- instancesByKey.set(compositeKey, instanceList);
503
+ instancesByKey.set(keyHash, instanceList);
479
504
  }
480
505
 
481
506
  let currentInstance = maybeUndefined(instanceList[instanceList.length - 1]);
@@ -506,8 +531,7 @@ export function createLifeCycleSearch(
506
531
  key: keyFields.map(k => k.ourKey).join(","),
507
532
  keys: keyValuePairs,
508
533
  entries: [{ datum, matchPattern: entry.matchPattern }],
509
- isWarning: true,
510
- warningMessage: "End entry without matching start",
534
+ isMissingStart: true,
511
535
  startTime: 0,
512
536
  });
513
537
  }
@@ -519,8 +543,7 @@ export function createLifeCycleSearch(
519
543
  key: keyFields.map(k => k.ourKey).join(","),
520
544
  keys: keyValuePairs,
521
545
  entries: [{ datum, matchPattern: entry.matchPattern }],
522
- isWarning: true,
523
- warningMessage: "Entry without matching start",
546
+ isMissingStart: true,
524
547
  startTime: 0,
525
548
  });
526
549
  }
@@ -534,6 +557,9 @@ export function createLifeCycleSearch(
534
557
  if (instance.entries.length > 0) {
535
558
  instance.startTime = instance.entries[0].datum.time;
536
559
  }
560
+ if (!instance.isComplete && !instance.isTruncated && !instance.isMissingStart) {
561
+ instance.isMissingEnd = true;
562
+ }
537
563
  }
538
564
 
539
565
  sort(allInstances, x => x.startTime);
@@ -547,6 +573,7 @@ export function createLifeCycleSearch(
547
573
  searchPhase2,
548
574
  groupLifecycleResults,
549
575
  cancel,
576
+ resetAllSearchState,
550
577
  };
551
578
  }
552
579
 
@@ -30,12 +30,15 @@ export type LifeCycleEntry = {
30
30
  ourKey: string;
31
31
  // Defaults to the same key, which is usually the case
32
32
  startKey?: string;
33
+
34
+ aliases?: string[];
33
35
  }[];
34
36
 
35
37
  // All of the special variables, which are marked. The title defaults to the key, but can be overriden for the purposes of adding notes.
36
38
  variables: {
37
39
  [key: string]: {
38
40
  title?: string;
41
+ aliases?: string[];
39
42
  };
40
43
  };
41
44
  };
@@ -190,7 +190,8 @@ export class ArchiveViewer extends qreact.Component {
190
190
  this.state.parsedValues = atomicObjectWrite({});
191
191
  });
192
192
 
193
- const MAX_FILES = 1000;
193
+ // NOTE: I don't understand why we were grouping this. Doing a thousand calls is not that slow, there's not that much overhead. And we want to have small groups, that way, we get more progress.
194
+ const MAX_FILES = 1;
194
195
  const MAX_SIZE = 500 * 1024 * 1024;
195
196
  let bufferObjs: { path: string; buffer: Buffer }[] = [];
196
197
  let newParsedValues: { [path: string]: PathValue[] } = {};
@@ -248,7 +249,7 @@ export class ArchiveViewer extends qreact.Component {
248
249
  this.state.progress.filesParsed.max = remainingFiles.size + bufferObjs.length;
249
250
  });
250
251
 
251
- for (let group of fileGroups) {
252
+ await Promise.all(fileGroups.map(async group => {
252
253
  //let time = Date.now();
253
254
  let newBuffers = await controller.getRawValueFiles(group.file, {
254
255
  // 1) Allows viewing old archives
@@ -276,7 +277,7 @@ export class ArchiveViewer extends qreact.Component {
276
277
  this.state.progress.filesDownloaded.value += group.file.length;
277
278
  this.state.progress.bytesDownloaded += newBuffers.reduce((sum, buffer) => sum + (buffer?.buffer.byteLength || 0), 0);
278
279
  });
279
- }
280
+ }));
280
281
  Querysub.commitLocal(() => {
281
282
  this.state.progress.filesDownloaded.endTime = Date.now();
282
283
  });
@@ -82,6 +82,9 @@ export class ArchiveViewerTree extends qreact.Component<{
82
82
  if (scaleType === "size") {
83
83
  total = node.totalSizeEstimate;
84
84
  }
85
+ if (node.values.length === 1 && total > 1000 * 1000 * 1000) {
86
+ debugger;
87
+ }
85
88
  countInfo += `(${formatNumber(node.values.length)} /// ${sumFormatter(total)}) `;
86
89
  } else {
87
90
  countInfo += `(${formatNumber(node.values.length)}) `;
@@ -395,7 +398,7 @@ export class ArchiveViewerTree extends qreact.Component<{
395
398
  <div class={css.hbox(20)}>
396
399
  <ButtonSelector<typeof archiveTreeScale.value>
397
400
  options={[
398
- { title: this.props.valueLabel || "Sum", value: "size" },
401
+ { title: this.props.valueLabel || "Size", value: "size" },
399
402
  { title: "Datum Count", value: "count" },
400
403
  { title: "Equal", value: "equal" },
401
404
  ]}
@@ -516,11 +519,11 @@ function treeifyValues(values: PathValue[], config: {
516
519
  return node;
517
520
  }
518
521
  function estimateSize(value: PathValue) {
519
- return Number(value.value) || 1;
522
+ //return 1;
520
523
  // if (config.sizeValueEstimateHack) {
521
524
  // return Number(value.value) || 1;
522
525
  // }
523
- // return getSingleSizeEstimate(value);
526
+ return getSingleSizeEstimate(value);
524
527
  }
525
528
 
526
529
  for (let value of values) {
@@ -6,7 +6,7 @@ export class StartEllipsis extends qreact.Component<{
6
6
  }> {
7
7
  render() {
8
8
  return <div className={css.relative.maxWidth(this.props.maxWidth).overflowHidden.whiteSpace("nowrap").direction("rtl")}>
9
- <span className={css.relative.direction("ltr")}>{this.props.children}</span>
9
+ <span className={css.relative.direction("ltr").unicodeBidi("isolate")}>{this.props.children}</span>
10
10
  <span className={css.absolute.left(`calc((100% - ${this.props.maxWidth}px) * -10000)`).top(0).height("100%").width(30).background("linear-gradient(to right, white, transparent)").pointerEvents("none")}></span>
11
11
  </div>;
12
12
  }
package/tempnotes.txt ADDED
File without changes