Skip to content

Commit

Permalink
added basic log event cursor and cleanup cursor switch in logFileManager
Browse files Browse the repository at this point in the history
  • Loading branch information
davemarco committed Sep 25, 2024
1 parent 0050180 commit a523d18
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 130 deletions.
6 changes: 3 additions & 3 deletions new-log-viewer/src/components/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const resetCachedPageSize = () => {
const Editor = () => {
const {mode, systemMode} = useColorScheme();

const {beginLineNumToLogEventNum, logData, loadPage} = useContext(StateContext);
const {beginLineNumToLogEventNum, logData, loadPageAction} = useContext(StateContext);
const {logEventNum} = useContext(UrlContext);

const [lineNum, setLineNum] = useState<number>(1);
Expand All @@ -82,7 +82,7 @@ const Editor = () => {
case ACTION_NAME.PREV_PAGE:
case ACTION_NAME.NEXT_PAGE:
case ACTION_NAME.LAST_PAGE:
loadPage(ACTION_NAME.LAST_PAGE);
loadPageAction(ACTION_NAME.LAST_PAGE);
break;
case ACTION_NAME.PAGE_TOP:
goToPositionAndCenter(editor, {lineNumber: 1, column: 1});
Expand All @@ -98,7 +98,7 @@ const Editor = () => {
default:
break;
}
}, [loadPage]);
}, [loadPageAction]);

/**
* Sets `editorRef` and configures callbacks for mouse down detection.
Expand Down
4 changes: 2 additions & 2 deletions new-log-viewer/src/components/MenuBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import SmallIconButton from "./SmallIconButton";
* @return
*/
const NavigationBar = () => {
const {loadPage} = useContext(StateContext);
const {loadPageAction} = useContext(StateContext);

const handleNavButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
const {actionName} = event.currentTarget.dataset as { actionName: ACTION_NAME };
if (Object.values(ACTION_NAME).includes(actionName)) {
loadPage(actionName);
loadPageAction(actionName);
}
};

Expand Down
4 changes: 2 additions & 2 deletions new-log-viewer/src/components/MenuBar/PageNumInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const PAGE_NUM_INPUT_FIT_EXTRA_WIDTH = 2;
* @return
*/
const PageNumInput = () => {
const {loadPage, numPages, pageNum} = useContext(StateContext);
const {loadPageAction, numPages, pageNum} = useContext(StateContext);

const [isEditing, setIsEditing] = useState<boolean>(false);
const inputRef = useRef<HTMLInputElement>(null);
Expand All @@ -36,7 +36,7 @@ const PageNumInput = () => {
return;
}

loadPage(ACTION_NAME.SPECIFIC_PAGE, Number(inputRef.current.value));
loadPageAction(ACTION_NAME.SPECIFIC_PAGE, Number(inputRef.current.value));
setIsEditing(false);
};

Expand Down
118 changes: 41 additions & 77 deletions new-log-viewer/src/contexts/StateContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
CURSOR_CODE,
CursorType,
FileSrcType,
LOG_EVENT_ANCHOR,
MainWorkerRespMessage,
WORKER_REQ_CODE,
WORKER_RESP_CODE,
Expand All @@ -31,10 +30,7 @@ import {
EXPORT_LOGS_CHUNK_SIZE,
getConfig,
} from "../utils/config";
import {
clamp,
getChunkNum,
} from "../utils/math";
import {getChunkNum} from "../utils/math";
import {
updateWindowUrlHashParams,
updateWindowUrlSearchParams,
Expand All @@ -55,7 +51,7 @@ interface StateContextType {

exportLogs: () => void,
loadFile: (fileSrc: FileSrcType, cursor: CursorType) => void,
loadPage: (action: ACTION_NAME, specificPageNum?: Nullable<number>) => void,
loadPageAction: (action: ACTION_NAME, specificPageNum?: Nullable<number>) => void,
}
const StateContext = createContext<StateContextType>({} as StateContextType);

Expand All @@ -73,34 +69,13 @@ const STATE_DEFAULT: Readonly<StateContextType> = Object.freeze({

exportLogs: () => null,
loadFile: () => null,
loadPage: () => null,
loadPageAction: () => null,
});

interface StateContextProviderProps {
children: React.ReactNode
}

/**
* Updates the log event number in the current window's URL hash parameters.
*
* @param lastLogEventNum The last log event number value.
* @param inputLogEventNum The log event number to set. If `null`, the hash parameter log event
* number will be set to `lastLogEventNum`. If it's outside the range `[1, lastLogEventNum]`, the
* hash parameter log event number will be clamped to that range.
*/
const updateLogEventNumInUrl = (
lastLogEventNum: number,
inputLogEventNum: Nullable<number>
) => {
const newLogEventNum = (null === inputLogEventNum) ?
lastLogEventNum :
clamp(inputLogEventNum, 1, lastLogEventNum);

updateWindowUrlHashParams({
logEventNum: newLogEventNum,
});
};

/**
* Sends a post message to a worker with the given code and arguments. This wrapper around
* `worker.postMessage()` ensures type safety for both the request code and its corresponding
Expand All @@ -126,7 +101,7 @@ const workerPostReq = <T extends WORKER_REQ_CODE>(
* @param props.children
* @return
*/
// eslint-disable-next-line max-lines-per-function
// eslint-disable-next-line max-lines-per-function, max-statements
const StateContextProvider = ({children}: StateContextProviderProps) => {
const {filePath, logEventNum} = useContext(UrlContext);

Expand All @@ -146,6 +121,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
const logExportManagerRef = useRef<null|LogExportManager>(null);
const mainWorkerRef = useRef<null|Worker>(null);

// eslint-disable-next-line max-lines-per-function
const handleMainWorkerResp = useCallback((ev: MessageEvent<MainWorkerRespMessage>) => {
const {code, args} = ev.data;
console.log(`[MainWorker -> Renderer] code=${code}`);
Expand All @@ -171,9 +147,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
pageNumRef.current = args.pageNum;
beginLineNumToLogEventNumRef.current = args.beginLineNumToLogEventNum;

// eslint-disable-next-line no-warning-comments
// TODO: Without logEvent cursor, we cannot jump to logEvents.
// Will be fixed once logEvent cursor is merged.
// Assume page data always provides a valid log event num. i.e. non null or
// outside range.
updateWindowUrlHashParams({
logEventNum: args.logEventNum,
});
Expand Down Expand Up @@ -236,15 +211,24 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
]);

const loadPage = useCallback((
action: ACTION_NAME,
specificPageNum: Nullable<number> = null
cursor: CursorType,
) => {
if (null === mainWorkerRef.current) {
console.error("Unexpected null mainWorkerRef.current");

return;
}

workerPostReq(mainWorkerRef.current, WORKER_REQ_CODE.LOAD_PAGE, {
cursor: cursor,
decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS),
});
}, []);

const loadPageAction = useCallback((
action: ACTION_NAME,
specificPageNum: Nullable<number> = null
) => {
const [newPageNum, anchor] = getPageNumCursorArgs(
action,
specificPageNum,
Expand All @@ -258,12 +242,13 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
return;
}

workerPostReq(mainWorkerRef.current, WORKER_REQ_CODE.LOAD_PAGE, {
cursor: {code: CURSOR_CODE.PAGE_NUM,
args: {pageNum: newPageNum, logEventAnchor: anchor}},
decoderOptions: getConfig(CONFIG_KEY.DECODER_OPTIONS),
});
}, []);
const cursor: CursorType = {
code: CURSOR_CODE.PAGE_NUM,
args: {pageNum: newPageNum, logEventAnchor: anchor},
};

loadPage(cursor);
}, [loadPage]);

// Synchronize `logEventNumRef` with `logEventNum`.
useEffect(() => {
Expand All @@ -285,33 +270,22 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {
return;
}

// eslint-disable-next-line no-warning-comments
// TODO: Remove newPageNum calc once log Event cursor complete. Instead
// we can check if in beginLineNumToLogEventNum, and if not send page request
// with logEvent cursor.
const newPageNum = clamp(
getChunkNum(logEventNum, getConfig(CONFIG_KEY.PAGE_SIZE)),
1,
numPagesRef.current
);

// Request a page switch only if it's not the initial page load.
if (STATE_DEFAULT.pageNum !== pageNumRef.current) {
if (newPageNum === pageNumRef.current) {
// Don't need to switch pages so just update `logEventNum` in the URL.
updateLogEventNumInUrl(numEvents, logEventNumRef.current);
} else {
// NOTE: We don't need to call `updateLogEventNumInUrl()` since it's called when
// handling the `WORKER_RESP_CODE.PAGE_DATA` response (the response to
// `WORKER_REQ_CODE.LOAD_PAGE` requests).
const logEventNumsOnPage: number [] =
Array.from(beginLineNumToLogEventNumRef.current.values());

// eslint-disable-next-line no-warning-comments
// TODO: Replace with logEvent cursor once its complete.
loadPage(ACTION_NAME.SPECIFIC_PAGE, newPageNum);
}
// Do nothing if log event is on the current page. There is no need to update it, since
// it was the URL change that triggered this useEffect.
if (logEventNumsOnPage.includes(logEventNum)) {
return;
}

const cursor: CursorType = {
code: CURSOR_CODE.EVENT_NUM,
args: {logEventNum: logEventNum},
};

loadPage(cursor);
}, [
numEvents,
logEventNum,
loadPage,
]);
Expand All @@ -324,18 +298,8 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {

let cursor: CursorType = {code: CURSOR_CODE.LAST_EVENT, args: null};
if (URL_HASH_PARAMS_DEFAULT.logEventNum !== logEventNumRef.current) {
// Set which page to load since the user specified a specific `logEventNum`.
// NOTE: Since we don't know how many pages the log file contains, we only clamp the
// minimum of the page number.
const newPageNum = Math.max(
getChunkNum(logEventNumRef.current, getConfig(CONFIG_KEY.PAGE_SIZE)),
1
);

// eslint-disable-next-line no-warning-comments
// TODO: Replace with logEvent cursor once its complete.
cursor = {code: CURSOR_CODE.PAGE_NUM,
args: {pageNum: newPageNum, logEventAnchor: LOG_EVENT_ANCHOR.FIRST}};
cursor = {code: CURSOR_CODE.EVENT_NUM,
args: {logEventNum: logEventNumRef.current}};
}
loadFile(filePath, cursor);
}, [
Expand All @@ -356,7 +320,7 @@ const StateContextProvider = ({children}: StateContextProviderProps) => {

exportLogs: exportLogs,
loadFile: loadFile,
loadPage: loadPage,
loadPageAction: loadPageAction,
}}
>
{children}
Expand Down
76 changes: 32 additions & 44 deletions new-log-viewer/src/services/fileManager/LogFileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import {
CURSOR_CODE,
CursorType,
FileSrcType,
LOG_EVENT_ANCHOR,
} from "../../typings/worker";
import {EXPORT_LOGS_CHUNK_SIZE} from "../../utils/config";
import {getChunkNum} from "../../utils/math";
import {formatSizeInBytes} from "../../utils/units";
import ClpIrDecoder from "../decoders/ClpIrDecoder";
import JsonlDecoder from "../decoders/JsonlDecoder";
import {
getRange,
getEventNumCursorData,
getLastEventCursorData,
getPageNumCursorData,
loadFile,
} from "./utils";

Expand Down Expand Up @@ -221,50 +222,37 @@ class LogFileManager {
* @throws {Error} if the type of cursor is not supported.
*/
#getCursorData (cursor: CursorType): {
beginLogEventNum: number, endLogEventNum:
number,
newLogEventNum: number} {
let beginLogEventIdx: number = 0;
let beginLogEventNum: number = 1;
let endLogEventNum: number = 0;
let newLogEventNum: number = 1;

if (0 === this.#numEvents) {
return {
beginLogEventNum: beginLogEventNum,
endLogEventNum: endLogEventNum,
newLogEventNum: newLogEventNum,
};
}

beginLogEventNum: number,
endLogEventNum: number,
newLogEventNum: number
} {
const {code, args} = cursor;
if (CURSOR_CODE.PAGE_NUM === code) {
beginLogEventIdx = ((args.pageNum - 1) * this.#pageSize);
[beginLogEventNum, endLogEventNum] = getRange(
this.#numEvents,
beginLogEventIdx,
this.#pageSize,
);
if (LOG_EVENT_ANCHOR.FIRST === args.logEventAnchor) {
newLogEventNum = beginLogEventNum;
} else {
newLogEventNum = endLogEventNum;
}
}
if (CURSOR_CODE.LAST_EVENT === code || beginLogEventIdx > this.#numEvents) {
// Set to the first event of the last page
beginLogEventIdx = (getChunkNum(this.#numEvents, this.#pageSize) - 1) * this.#pageSize;
[beginLogEventNum, endLogEventNum] = getRange(
this.#numEvents,
beginLogEventIdx,
this.#pageSize,
);
newLogEventNum = endLogEventNum;
} else if (CURSOR_CODE.TIMESTAMP === code) {
throw new Error(`Unsupported cursor type: ${code}`);
}

return {beginLogEventNum, endLogEventNum, newLogEventNum};
switch (code) {
case CURSOR_CODE.PAGE_NUM:
return getPageNumCursorData(
args.pageNum,
args.logEventAnchor,
this.#numEvents,
this.#pageSize
);

case CURSOR_CODE.LAST_EVENT:
return getLastEventCursorData(
this.#numEvents,
this.#pageSize
);

case CURSOR_CODE.EVENT_NUM:
return getEventNumCursorData(
args.logEventNum,
this.#numEvents,
this.#pageSize
);

default:
throw new Error(`Unsupported cursor type: ${code}`);
}
}
}

Expand Down
Loading

0 comments on commit a523d18

Please sign in to comment.