From c88801430eeffd9d1935ca1984481379219f18cb Mon Sep 17 00:00:00 2001 From: LightFLP Date: Mon, 25 Sep 2023 16:02:53 +0200 Subject: [PATCH] Implement maps instead of number arrays for logEntryRangess --- src/viewer/App.tsx | 28 +++++++------ src/viewer/hooks/useLogSearchManager.ts | 19 ++++----- .../useStructureRegularExpressionManager.ts | 42 +++++++++---------- src/viewer/types.d.ts | 5 +++ 4 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/viewer/App.tsx b/src/viewer/App.tsx index 531992f..991e588 100644 --- a/src/viewer/App.tsx +++ b/src/viewer/App.tsx @@ -3,7 +3,7 @@ import LogFile from "./LogFile"; import LogView from "./log/LogView"; import MinimapView from "./minimap/MinimapView"; import Tooltip from "@mui/material/Tooltip"; -import { LogViewState, StructureMatchId, RowProperty, Segment } from "./types"; +import { LogViewState, StructureMatchId, RowProperty, Segment, LogEntryCharRanges } from "./types"; import { LOG_HEADER_HEIGHT, MINIMAP_COLUMN_WIDTH, @@ -18,7 +18,7 @@ import { VSCodeOption, } from "@vscode/webview-ui-toolkit/react"; import { - useJsonObjectToTextRangesMap, + useGetCharIndicesForLogEntries, useStructureRegularExpressionSearch, } from "./hooks/useStructureRegularExpressionManager"; import { getRegularExpressionMatches, returnSearchIndices } from "./hooks/useLogSearchManager"; @@ -49,7 +49,7 @@ interface State { // Structure related logFileAsString: string; - logEntryRanges: number[][]; + logEntryCharRanges: LogEntryCharRanges; selectedLogRows: string[][]; // selectedRowsTypes: RowType[]; rowProperties: RowProperty[]; @@ -105,7 +105,7 @@ export default class App extends React.Component { caseSearch: false, selectedLogRows: [], rowProperties: [], - logEntryRanges: [], + logEntryCharRanges: {firstCharIndexMap: null, lastCharIndexMap: null}, showStructureDialog: false, structureMatches: [], structureMatchesLogRows: [], @@ -133,7 +133,7 @@ export default class App extends React.Component { const rules = message.rules.map((r) => Rule.fromJSON(r)).filter((r) => r); const lines = JSON.parse(message.text); const logFileText = JSON.stringify(lines, null, 2); - const textRanges = useJsonObjectToTextRangesMap(logFileText); + const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); const logFile = LogFile.create(lines, rules); const newRowsProps = logFile.rows.map(() => constructNewRowProperty(true, true, SelectedRowType.None), @@ -141,7 +141,7 @@ export default class App extends React.Component { this.setState({ logFile, logFileAsString: logFileText, - logEntryRanges: textRanges, + logEntryCharRanges: charRangesMaps, rules, rowProperties: newRowsProps, }); @@ -181,11 +181,11 @@ export default class App extends React.Component { return constructNewRowProperty(true, true, SelectedRowType.None); else return constructNewRowProperty(false, false, SelectedRowType.None); }); - const textRanges = useJsonObjectToTextRangesMap(logFileText); + const charRangesMaps = useGetCharIndicesForLogEntries(logFileText); this.setState({ logFile, logFileAsString: logFileText, - logEntryRanges: textRanges, + logEntryCharRanges: charRangesMaps, rules, rowProperties: newRowsProps, }); @@ -319,13 +319,13 @@ export default class App extends React.Component { handleStructureMatching(expression: string) { const rowProperties = this.clearSelectedRowsTypes(); - const { logFileAsString, logEntryRanges } = this.state; + const { logFileAsString, logEntryCharRanges } = this.state; let { currentStructureMatch, currentStructureMatchIndex } = this.state; const structureMatches = useStructureRegularExpressionSearch( expression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); let structureMatchesLogRows: number[] = []; @@ -378,18 +378,20 @@ export default class App extends React.Component { } handleSegmentation(entryExpression: string, exitExpression: string) { - const { logFileAsString, logEntryRanges } = this.state; + const { logFileAsString, logEntryCharRanges } = this.state; const { collapsibleRows } = this.state; + console.log(entryExpression); + console.log(exitExpression); const entryMatches = getRegularExpressionMatches( entryExpression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); const exitMatches = getRegularExpressionMatches( exitExpression, logFileAsString, - logEntryRanges, + logEntryCharRanges, ); const stack: number[] = []; diff --git a/src/viewer/hooks/useLogSearchManager.ts b/src/viewer/hooks/useLogSearchManager.ts index 287c91e..7affd39 100644 --- a/src/viewer/hooks/useLogSearchManager.ts +++ b/src/viewer/hooks/useLogSearchManager.ts @@ -1,3 +1,5 @@ +import { LogEntryCharRanges } from "../types"; + export const escapeSpecialChars = (text: string): string => { let safeText = ""; @@ -135,29 +137,24 @@ export const returnSearchIndices = ( export const getRegularExpressionMatches = ( expression: string, logFileAsString: string, - logEntryRanges: number[][], + logEntryCharRanges: LogEntryCharRanges, ): number[] => { const searchIndices: number[] = []; const resultingMatches: number[] = []; const flags = "gs"; const query = new RegExp(expression, flags); let result; - let currentIndex = 0; while ((result = query.exec(logFileAsString)) !== null) { searchIndices.push(result.index); } if (searchIndices.length > 0) { - for (let i = 0; i < logEntryRanges.length; i++) { - if (searchIndices[currentIndex] >= logEntryRanges[i][0]) { - if (searchIndices[currentIndex] <= logEntryRanges[i][1]) { - currentIndex += 1; - if (i != resultingMatches[-1]) resultingMatches.push(i); - if (currentIndex === searchIndices.length) break; - } - } - } + searchIndices.forEach((searchIndex) => { + const indexOfMatchedEntry = logEntryCharRanges.firstCharIndexMap.get(searchIndex); + resultingMatches.push(indexOfMatchedEntry); + }); } + return resultingMatches; }; diff --git a/src/viewer/hooks/useStructureRegularExpressionManager.ts b/src/viewer/hooks/useStructureRegularExpressionManager.ts index ad54fb8..9310597 100644 --- a/src/viewer/hooks/useStructureRegularExpressionManager.ts +++ b/src/viewer/hooks/useStructureRegularExpressionManager.ts @@ -1,4 +1,4 @@ -import { CellContents, Header, StructureEntry, Wildcard } from "../types"; +import { CellContents, Header, LogEntryCharRanges, StructureEntry, Wildcard } from "../types"; import { StructureHeaderColumnType, StructureLinkDistance } from "../constants"; import { isSubstitutionFirstForWildcard } from "./useWildcardManager"; @@ -182,29 +182,33 @@ export const useStructureQueryConstructor = ( return regularExp; }; -export const useJsonObjectToTextRangesMap = (logFileAsString: string): number[][] => { +export const useGetCharIndicesForLogEntries = (logFileAsString: string): LogEntryCharRanges => { const perfStart = performance.now(); - const textRanges: number[][] = []; const jsonObjectsRegExp = new RegExp(regExpjsonObject, flags); + const firstCharIndexMap = new Map(); + const lastCharIndexMap = new Map(); + let logEntryIndex = 0; let result = jsonObjectsRegExp.exec(logFileAsString); if (result !== null) { do { - textRanges.push([result.index, jsonObjectsRegExp.lastIndex]); + firstCharIndexMap.set(result.index, logEntryIndex); + lastCharIndexMap.set(jsonObjectsRegExp.lastIndex, logEntryIndex); + logEntryIndex++; } while ((result = jsonObjectsRegExp.exec(logFileAsString)) !== null); } const perfEnd = performance.now(); console.log(`Execution time (mapLogFileTextIndicesToObject()): ${perfEnd - perfStart} ms`); - return textRanges; + return { firstCharIndexMap: firstCharIndexMap, lastCharIndexMap: lastCharIndexMap }; }; export const useStructureRegularExpressionSearch = ( expression: string, logFileAsString: string, - logEntryRanges: number[][], + logEntryCharRanges: LogEntryCharRanges, ): number[][] => { console.log("Starting Structure Matching"); const perfStart = performance.now(); @@ -213,35 +217,31 @@ export const useStructureRegularExpressionSearch = ( const structureQuery = new RegExp(expression, flags); let result; + while ((result = structureQuery.exec(logFileAsString)) !== null) { textRanges.push([result.index, structureQuery.lastIndex]); } const perfEnd = performance.now(); - console.log(`Execution time (useStructureRegularExpressionSearch()): ${perfEnd - perfStart} ms`); + console.log(`Execution time (regular expression run): ${perfEnd - perfStart} ms`); + + const transStart = performance.now(); textRanges.forEach((matchRanges) => { const indexesOfEntriesInMatch: number[] = []; - let startingIndexOfMatch = 0; - let endingIndexOfMatch = -1; - - for (let i = 0; i < logEntryRanges.length; i++) { - if (matchRanges[0] === logEntryRanges[i][0]) { - startingIndexOfMatch = i; - } - if (matchRanges[1] === logEntryRanges[i][1]) { - endingIndexOfMatch = i; - break; - } - } + const indexOfFirstObjectInMatch = logEntryCharRanges.firstCharIndexMap.get(matchRanges[0]); + const indexOfLastObjectInMatch = logEntryCharRanges.lastCharIndexMap.get(matchRanges[1]); - for (let o = startingIndexOfMatch; o <= endingIndexOfMatch; o++) { - indexesOfEntriesInMatch.push(o); + for (let i = indexOfFirstObjectInMatch; i <= indexOfLastObjectInMatch; i++) { + indexesOfEntriesInMatch.push(i); } resultingMatches.push(indexesOfEntriesInMatch); }); + const transEnd = performance.now(); + console.log(`Execution time (translation from char indices to logFile.rows indices): ${transEnd - transStart} ms`); + return resultingMatches; }; diff --git a/src/viewer/types.d.ts b/src/viewer/types.d.ts index 5f72b30..75f956f 100644 --- a/src/viewer/types.d.ts +++ b/src/viewer/types.d.ts @@ -57,3 +57,8 @@ export interface Segment { end: number; level: number; } + +export interface LogEntryCharRanges { + firstCharIndexMap; + lastCharIndexMap; +}