Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added documentation #198

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions TimeTrace/src/components/Collapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ interface Collapsibleprop {
children?: ReactNode;
isOpen: boolean; // Add open prop
}
/**
*
* @returns A component that can encompass other react components and show them based on whether it is collapsed or not.
*/
function Collapsible({ label, children, isOpen }: Collapsibleprop) {
const [open, setIsOpen] = useState(isOpen || false);

Expand Down
4 changes: 4 additions & 0 deletions TimeTrace/src/components/MappedItemsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import Button from "./button/Button";
import { ButtonStyle } from "./button/IButtonProps";
import Tooltip from "./tooltip/ToolTip";

/**
* @returns The mappings list/table on the MappingsPage
*/
function MappedItemsList() {
const { mappings, setMappings } = useContext(AppdataContext);

function removeMapping(eventText: string): void {
mappings.remove(eventText)
// new reference to alert the frontend that it should reload HTML that relies on the mappings.
const newMappings = new CustomMap(mappings);
if (setMappings) {
setMappings(newMappings);
Expand Down
13 changes: 13 additions & 0 deletions TimeTrace/src/components/SearchForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ interface SearchFormProps {
tooltip?: string;
}

/**
*
* @returns A searchform which allows the user to type in a TRE and perform a search
*/
export default function SearchForm({ tooltip }: SearchFormProps) {
const { tre, setTre } = useContext(AppdataContext);
const { mappings } = useContext(AppdataContext);
Expand All @@ -28,11 +32,17 @@ export default function SearchForm({ tooltip }: SearchFormProps) {
const { linesPerPage } = useContext(LogTableContext);
const { currentPageSpan, setCurrentPageSpan } = useContext(LogTableContext);

/**
* we preventDefault on the event to stop a request from being sent in the browser - this would cause a 'page refresh'
*/
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
callMonaa(tre);
};

/**
* Finds the first match in the match set.
*/
function findFirstMatch(matches: MonaaZone[]) {
if (matches.length === 0) {
setShownLines(filteredFileLines.slice(0, linesPerPage));
Expand All @@ -56,6 +66,9 @@ export default function SearchForm({ tooltip }: SearchFormProps) {
setMonaaMatchIndex(-1); //set to -1 to trigger a scroll to the first match (when use effect on LogTable sets it to 0 after this)
}

/**
* Gets the results from Monaa using a tre.
*/
async function callMonaa(tre: string) {
setLoading(true);
if (!uploadedFile) return; //should never happen
Expand Down
4 changes: 4 additions & 0 deletions TimeTrace/src/components/Warning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { useContext } from "react";
import Button from "./button/Button";
import { ButtonStyle } from "./button/IButtonProps";

/**
*
* @returns A pop-up that exclaims that there was some sort of error
*/
export default function Warning() {
const { errorObj, setError } = useContext(AppdataContext);

Expand Down
7 changes: 7 additions & 0 deletions TimeTrace/src/components/logtable/LogTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function LogTable({ mappingsAreEditable }: LogTableProps) {
scrollToMonaaMatch();
}, [monaaMatchIndex]);

//Ensures that whenever the currentPageSpan changes we still listen to the scroll event on the logtable.
useEffect(() => {
const logTable = document.querySelector("#log-table");
if (!logTable) return;
Expand All @@ -61,6 +62,9 @@ function LogTable({ mappingsAreEditable }: LogTableProps) {
setFilteredFileLines(filterAllMappedUnmappedLines(mapEventsToFileLine(events), shownLinesMode, mappings))
}, [shownLinesMode])

/**
* Searches the logfile using either {@link searchUsingRegex} or {@link searchStandard} based on the boolean {@link advancedSearchMode}
*/
function searchLog(query: string) {
if (query === "") {
setFilteredFileLines(filterAllMappedUnmappedLines(mapEventsToFileLine(events), shownLinesMode, mappings));
Expand Down Expand Up @@ -145,6 +149,9 @@ function LogTable({ mappingsAreEditable }: LogTableProps) {
}
};

/**
* @returns A boolean that indicates whether a line is highlighted (that is when it is included in a currently shown match)
*/
function lineIsHighlighted(line: number): boolean {
if (mappingsAreEditable || !matches[monaaMatchIndex]) return false;
let highlightLine = false;
Expand Down
4 changes: 4 additions & 0 deletions TimeTrace/src/components/modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { useContext } from 'react';
import Button from "../button/Button";
import { ButtonStyle } from "../button/IButtonProps";

/**
*
* @returns A pop up used for non errors that display some sort of information.
*/
export default function Modal() {
const { modalObj, setModal } = useContext(AppdataContext);

Expand Down
1 change: 0 additions & 1 deletion TimeTrace/src/components/predefined-res/Interval.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {FormEvent, useState } from "react";
import ModalInput from "../modal/ModalInput";
import { IntervalClass } from "./PredefinedREs";
import FormButtonGroup from "../button/FormButtonGroup";
import { validateNumberInput } from "./numbersOnlyInput";

interface IntervalProps {
reObject: IntervalClass;
Expand Down
1 change: 0 additions & 1 deletion TimeTrace/src/components/predefined-res/Over.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {FormEvent, useState } from "react";
import ModalInput from "../modal/ModalInput";
import { OverClass } from "./PredefinedREs";
import FormButtonGroup from "../button/FormButtonGroup";
import { validateNumberInput } from "./numbersOnlyInput";

interface InclusiveOverProps {
reObject: OverClass;
Expand Down
18 changes: 18 additions & 0 deletions TimeTrace/src/components/predefined-res/PredefinedREs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ export enum PredefinedREType {
InclusiveUnder,
}

/**
* Every predefinedRE must have a title for its modal and a method to insert the RE.
* {@link PredefinedRE.title}
* {@link PredefinedRE.insertRE}
*/
export interface PredefinedRE {
title: string;
insertRE: () => string;
}


/**
* These interfaces are just to make the predefinedRE classes more compact
*/
export interface IntervalInput {
prependedText: string;
lowerBound: string;
Expand Down Expand Up @@ -44,19 +52,29 @@ export interface OverInput {
lowerBound: string;
}

/**
* This class is used for the predefinedREs: "Greater or Equal", "Greater", "Smaller", "Smaller or Equal"
*/
export class OverClass implements PredefinedRE {
public input: OverInput;
public title: string = '';
public includesLowerBound: boolean;
/**
* {@link negateRe} is used to turn the over into an under predefined RE.
*/
public negateRe: boolean;
public label: string = '';

public insertRE(): string {
let re = '';
//We want to include the lowerbound, this is done using inclusiveOver.
if(this.includesLowerBound) {
//If the RE should be negated that is turned into under we prepend (?!(
re = `${this.input.prependedText}${this.negateRe ? '(?!(': ''}${generateInclusiveOverRegex(this.input.lowerBound)}${this.negateRe ? '))': ''}`;
}
//We want to exclude the lowerbound, this is done using strictOver.
else {
//If the RE should be negated that is turned into under we prepend (?!(
re = `${this.input.prependedText}${this.negateRe ? '(?!(': ''}${generateStrictOverRegex(this.input.lowerBound)}${this.negateRe ? '))': ''}`;
}

Expand Down
7 changes: 0 additions & 7 deletions TimeTrace/src/components/predefined-res/numbersOnlyInput.ts

This file was deleted.

8 changes: 7 additions & 1 deletion TimeTrace/src/components/predefined-tres/PredefinedTREs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ export enum PredefinedTre {
TimedSequential,
}

/**
* Every predefinedTRE must have a title ({@link IPredefinedTRE.title}) used for the title of the modal
* Every predefiendTRE must have a method ({@link IPredefinedTRE.insertTRE}) that returns the predefinedTRE as a string
*/
export interface IPredefinedTRE {
title: string;
insertTRE: () => string;
}


/**
* To make the {@link WithinTREClass} a bit more compact
*/
export interface WithinTREInput {
firstGroup: string;
secondGroup: string;
Expand Down
5 changes: 5 additions & 0 deletions TimeTrace/src/models/LogHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ export abstract class LogHandler {

for (let i = 0; i < MonaaOutput.length; i++) {
const line = MonaaOutput[i];

//Indicates that a new match begins
if (line.includes("=======") && foundStart !== -1 && foundEnd !== -1) { //RESET interval
let SearchInterval: SearchInterval = { start: foundStart, end: foundEnd };
foundIntervals.push(SearchInterval);

foundStart = -1;
foundEnd = -1;
}
//Lower bound of Monaazone
else if (MonaaOutput[i].includes("<= t <") || MonaaOutput[i].includes("< t <") || MonaaOutput[i].includes("< t <=") || MonaaOutput[i].includes("<= t <=")) { //FIND Start

foundStart = parseFloat(MonaaOutput[i].split(/\s+/).filter(part => !isNaN(parseFloat(part))).pop() || '');
}

//Upper bound of Monaazone
else if (MonaaOutput[i].includes("<= t' <") || MonaaOutput[i].includes("< t' <") || MonaaOutput[i].includes("< t' <=") || MonaaOutput[i].includes("<= t' <=")) { //FIND End

foundEnd = parseFloat(MonaaOutput[i].split(/\s+/).filter(part => !isNaN(parseFloat(part))).shift() || '');
Expand Down
24 changes: 20 additions & 4 deletions TimeTrace/src/models/LogSearcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,29 @@ export abstract class LogSearcher {
return this._hashMap;
}

/**
* Finds the indices in the logfile where there is a match
*/
public static findZones(searchIntervals: SearchInterval[]): MonaaZone[] {
console.time("findZones");
let binaryTime = 0, binaryCount = 0
let hashTime = 0, hashCount = 0
let startOfLastFoundMatch = 0;
const MonaaZoneMatches: MonaaZone[] = [];

for (let i = 0; i < searchIntervals.length; i++) {
let match = new MonaaZone();
let hashTimeStart = performance.now()
let start: number | null = this.hashMap.get(Math.round(searchIntervals[i].start).toString());
let end: number | null = this.hashMap.get(Math.round(searchIntervals[i].end).toString());

// Start and end could be looked up in the hashmap.
if (start !== null && end !== null) {
match.lineMatches = Array.from({ length: end - start + 1 }, (_, index) => start! + index); //array containing numbers from start to end
hashTime += performance.now() - hashTimeStart;
hashCount++;
}
// Start or end may be null. We will use binary search
else {
let binaryTimeStart = performance.now()
match = this.findNearestZone(searchIntervals[i], start != null ? start : startOfLastFoundMatch);
Expand All @@ -50,6 +57,9 @@ export abstract class LogSearcher {
return MonaaZoneMatches
}

/**
* Finds an individual match in the case where the start or end could not be found via the hashmap.
*/
public static findNearestZone(searchInterval: SearchInterval, startOfLastMatch: number): MonaaZone {
let foundmatch = new MonaaZone();
let startingIndex = this.findNearestIndex(startOfLastMatch, searchInterval);
Expand All @@ -63,14 +73,16 @@ export abstract class LogSearcher {
return foundmatch;
}

/**
*
* Converts the timestamps to ms when a file is uploaded
*/
public static updateTimestampInfo(logFile: string[]) {
let prevLineTime: number = 0;
const timestamps: number[] = [];

logFile.forEach((line: string) => {
const eventTimeStamp = parseInt(LogFormatter.convertDateToMs(extractTimeStamp(line)));
timestamps.push(eventTimeStamp);
prevLineTime = eventTimeStamp;
});

let averageTimegrowth: number = (timestamps[timestamps.length - 1] - timestamps[0]) / timestamps.length
Expand All @@ -79,15 +91,19 @@ export abstract class LogSearcher {
this.averageGrowth = averageTimegrowth;
}

/** Used to find the starting index. */
private static findNearestIndex(lastFoundIndex: number, searchInterval: SearchInterval): number {
const firstTimestamp = this.timestamps[0];
const difference = searchInterval.start - firstTimestamp;
const multiplum = difference / this.averageGrowth;
let startingIndex = Math.floor(multiplum);

if (searchInterval.start < this.timestamps[startingIndex]) { // search in left side if we overshot estimation
// search in left side if we overshot estimation
if (searchInterval.start < this.timestamps[startingIndex]) {
startingIndex = this.binarySearch(searchInterval.start, lastFoundIndex, startingIndex);
} else if (searchInterval.start > this.timestamps[startingIndex]) {//search in right side of array if we undershot estimation
}
// search in right side of array if we undershot estimation
else if (searchInterval.start > this.timestamps[startingIndex]) {
startingIndex = startingIndex < lastFoundIndex ? lastFoundIndex : startingIndex;
startingIndex = this.binarySearch(searchInterval.start, startingIndex, this.timestamps.length - 1);
}else {
Expand Down
Loading
Loading