Skip to content

Commit

Permalink
perf: use bytes for pos comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
Yash-Singh1 committed Apr 11, 2024
1 parent 8894f83 commit 2b2ffd3
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 66 deletions.
43 changes: 14 additions & 29 deletions server/src/capabilities/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ async function onCompletion({
const stateManager = new StateManager();
let moduleStart = 0;

// Precalculate the byte offset of the parameter
const paramByte = byteRepresentation.charIndexToByteOffset(
textDocument.offsetAt(params.position),
);

await walk<{
propertyName: string | undefined;
callInside: string | null | undefined;
Expand All @@ -80,24 +85,13 @@ async function onCompletion({
},

"*"(node) {
if ("span" in node && node.type !== "VariableDeclaration") {
const startSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.span.start - moduleStart,
),
);
const endSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.span.end - moduleStart,
),
);

if (
params.position.line > endSpanRelative.line ||
params.position.line < startSpanRelative.line
) {
return false;
}
if (
"span" in node &&
node.type !== "VariableDeclaration" &&
paramByte < node.span.start - moduleStart &&
paramByte > node.span.end - moduleStart
) {
return false;
}
},

Expand Down Expand Up @@ -199,19 +193,10 @@ async function onCompletion({
node.span.start - moduleStart,
),
);
const endSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.span.end - moduleStart,
),
);

if (
params.position.line > endSpanRelative.line ||
params.position.line < startSpanRelative.line ||
(params.position.line === endSpanRelative.line &&
params.position.character > endSpanRelative.character) ||
(params.position.line === startSpanRelative.line &&
params.position.character < startSpanRelative.character)
paramByte < node.span.start - moduleStart ||
paramByte > node.span.end - moduleStart
) {
return false;
}
Expand Down
50 changes: 13 additions & 37 deletions server/src/capabilities/hover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ async function onHover({
// Resulting hover
let hover: Hover | null = null;

const paramByte = byteRepresentation.charIndexToByteOffset(
textDocument.offsetAt(params.position),
);

await walk<{
parentClass: string[];
callInside: string | null | undefined;
Expand All @@ -78,24 +82,13 @@ async function onHover({
},

"*"(node) {
if ("span" in node && node.type !== "VariableDeclaration") {
const startSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.span.start - moduleStart,
),
);
const endSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.span.end - moduleStart,
),
);

if (
params.position.line > endSpanRelative.line ||
params.position.line < startSpanRelative.line
) {
return false;
}
if (
"span" in node &&
node.type !== "VariableDeclaration" &&
paramByte < node.span.start &&
paramByte > node.span.end
) {
return false;
}
},

Expand Down Expand Up @@ -247,27 +240,10 @@ async function onHover({
};
}

const startSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.key.span.start - moduleStart,
),
);
const endSpanRelative = textDocument.positionAt(
byteRepresentation.byteOffsetToCharIndex(
node.key.span.end - moduleStart,
),
);

// Don't use out of range nodes
if (
!(
params.position.line >= startSpanRelative.line &&
params.position.line <= endSpanRelative.line &&
(params.position.line !== startSpanRelative.line ||
params.position.character >= startSpanRelative.character) &&
(params.position.line !== endSpanRelative.line ||
params.position.character <= endSpanRelative.character)
)
paramByte > node.key.span.end - moduleStart ||
paramByte < node.key.span.start - moduleStart
) {
return state;
}
Expand Down
7 changes: 7 additions & 0 deletions server/src/lib/string-bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class StringAsBytes {
private prefixArray: Uint32Array;
private stringSegments: string[];
private preStringLength: Uint32Array;
private stringVal: string;

constructor(string: string) {
this.encoder = new TextEncoder();
Expand All @@ -34,6 +35,7 @@ export class StringAsBytes {
this.stringSegments = [
...new Intl.Segmenter("en", { granularity: "grapheme" }).segment(string),
].map((segment) => segment.segment);
this.stringVal = string;

this.calculatePrefixArray();
}
Expand Down Expand Up @@ -74,6 +76,11 @@ export class StringAsBytes {
this.stringLength = prefixArray[prefixArray.length - 1];
}

// We can make this O(n) time because it is called only once per request
public charIndexToByteOffset(charIndex: number) {
return this.encoder.encode(this.stringVal.slice(0, charIndex)).length;
}

/**
* Binary searches the prefix sum array to find the character index for a given byte offset.
* @param byteOffset Byte offset to convert to char index
Expand Down

0 comments on commit 2b2ffd3

Please sign in to comment.