mirror of
https://github.com/kotaindah55/extended-markdown-syntax.git
synced 2026-07-22 05:38:06 +00:00
perf: split token group virtually into smaller parts
In the case of finding certain token index, we split up the token groups into smaller parts to speed up the process.
This commit is contained in:
parent
83b1cd24a6
commit
fcce761c21
2 changed files with 49 additions and 39 deletions
|
|
@ -724,10 +724,10 @@ export class EditorParser {
|
|||
}
|
||||
|
||||
private _filterTokens(tokens: TokenGroup, reparsedRange: typeof this.reparsedRanges[TokenLevel]): TokenGroup {
|
||||
let index = 0,
|
||||
reparsedFrom: number | undefined,
|
||||
let reparsedFrom: number | undefined,
|
||||
reparsedTo: number | undefined,
|
||||
offset = this._state.globalOffset;
|
||||
offset = this._state.globalOffset,
|
||||
index = findTokenIndexAt(tokens, offset) ?? tokens.length;
|
||||
|
||||
for (let curToken = tokens[index]; index < tokens.length; curToken = tokens[++index]) {
|
||||
// Keep find token touched by the current offset
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { IndexCache, PlainRange, Token, TokenGroup } from "src/types";
|
||||
import { PlainRange, Token, TokenGroup } from "src/types";
|
||||
|
||||
type TokenPartsRanges = Record<"openRange" | "closeRange" | "tagRange" | "contentRange", PlainRange>;
|
||||
interface IterTokenGroupSpec {
|
||||
tokens: TokenGroup,
|
||||
ranges: PlainRange[] | readonly PlainRange[],
|
||||
indexCache: IndexCache
|
||||
ranges: PlainRange[] | readonly PlainRange[]
|
||||
callback: (token: Token) => unknown,
|
||||
}
|
||||
|
||||
|
|
@ -27,41 +26,52 @@ export function isToken(range: PlainRange): range is Token {
|
|||
return type !== undefined && openLen !== undefined && tagLen !== undefined && closeLen !== undefined;
|
||||
}
|
||||
|
||||
export function moveTokenIndexCache(tokens: TokenGroup, offset: number, indexCache: IndexCache): void {
|
||||
if (tokens.length == 0) {
|
||||
indexCache.number = 0;
|
||||
return;
|
||||
export function iterTokenGroup(spec: IterTokenGroupSpec): void {
|
||||
let { tokens, ranges, callback } = spec,
|
||||
tokenI = findTokenIndexAt(tokens, ranges[0]?.from ?? 0),
|
||||
rangeI = 0;
|
||||
|
||||
if (tokenI === null) return;
|
||||
|
||||
while (
|
||||
tokenI < tokens.length &&
|
||||
rangeI < ranges.length
|
||||
) {
|
||||
if (ranges[rangeI].to <= tokens[tokenI].from) { rangeI++; continue }
|
||||
if (
|
||||
tokens[tokenI].from < ranges[rangeI].to &&
|
||||
tokens[tokenI].to > ranges[rangeI].from
|
||||
) {
|
||||
callback(tokens[tokenI]);
|
||||
}
|
||||
tokenI++;
|
||||
}
|
||||
|
||||
if (indexCache.number >= tokens.length)
|
||||
indexCache.number = tokens.length - 1;
|
||||
|
||||
let curIndex = indexCache.number,
|
||||
curToken = tokens[curIndex];
|
||||
if (offset < curToken.from && curIndex != 0) {
|
||||
do {
|
||||
curToken = tokens[--curIndex];
|
||||
} while (offset < curToken.from && curIndex != 0)
|
||||
} else if (offset > curToken.to && curIndex != tokens.length - 1) {
|
||||
do {
|
||||
curToken = tokens[++curIndex];
|
||||
} while (offset > curToken.to && curIndex != tokens.length - 1)
|
||||
}
|
||||
|
||||
indexCache.number = curIndex;
|
||||
}
|
||||
|
||||
export function iterTokenGroup(spec: IterTokenGroupSpec): void {
|
||||
let { tokens, ranges, callback, indexCache } = spec;
|
||||
moveTokenIndexCache(tokens, ranges[0]?.from ?? 0, indexCache);
|
||||
for (
|
||||
let i = indexCache.number, j = 0;
|
||||
i < tokens.length && j < ranges.length;
|
||||
) {
|
||||
if (ranges[j].to <= tokens[i].from) { j++; continue }
|
||||
if (tokens[i].from < ranges[j].to && tokens[i].to > ranges[j].from) {
|
||||
callback(tokens[i]);
|
||||
}
|
||||
i++;
|
||||
export function findTokenIndexAt(tokens: TokenGroup, offset: number): number | null {
|
||||
if (!tokens.length) return null;
|
||||
|
||||
let base = 32768,
|
||||
factor = 2,
|
||||
index = 0;
|
||||
|
||||
while (base !== 32) {
|
||||
if (tokens.length > base)
|
||||
while (tokens[index].from <= offset) {
|
||||
let end = Math.min(index + base, tokens.length);
|
||||
if (tokens[end - 1].to < offset) index = end;
|
||||
else break;
|
||||
}
|
||||
|
||||
base /= factor;
|
||||
factor *= 2;
|
||||
}
|
||||
|
||||
for (
|
||||
let end = Math.min(index + base, tokens.length);
|
||||
index < end && tokens[index].to < offset;
|
||||
index++
|
||||
);
|
||||
|
||||
return index < tokens.length ? index : null;
|
||||
}
|
||||
Loading…
Reference in a new issue