Add comments, fixes for 0 sentinel

This commit is contained in:
Michael Howell 2022-06-27 14:13:13 -07:00
parent b54e3e6c98
commit 33cf9ea4a2
3 changed files with 36 additions and 5 deletions

View File

@ -234,7 +234,33 @@ pub(crate) fn build_index<'tcx>(
)?;
crate_data.serialize_field(
"f",
&self.items.iter().map(|item| &item.search_type).collect::<Vec<_>>(),
&self
.items
.iter()
.map(|item| {
// Fake option to get `0` out as a sentinel instead of `null`.
// We want to use `0` because it's three less bytes.
enum FunctionOption<'a> {
Function(&'a IndexItemFunctionType),
None,
}
impl<'a> Serialize for FunctionOption<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
FunctionOption::None => 0.serialize(serializer),
FunctionOption::Function(ty) => ty.serialize(serializer),
}
}
}
match &item.search_type {
Some(ty) => FunctionOption::Function(ty),
None => FunctionOption::None,
}
})
.collect::<Vec<_>>(),
)?;
crate_data.serialize_field(
"p",

View File

@ -86,6 +86,9 @@ let Results;
* A pair of [inputs, outputs], or 0 for null. This is stored in the search index.
* The JavaScript deserializes this into FunctionSearchType.
*
* Numeric IDs are *ONE-indexed* into the paths array (`p`). Zero is used as a sentinel for `null`
* because `null` is four bytes while `0` is one byte.
*
* An input or output can be encoded as just a number if there is only one of them, AND
* it has no generics. The no generics rule exists to avoid ambiguity: imagine if you had
* a function with a single output, and that output had a single generic:
@ -114,6 +117,9 @@ let RawFunctionSearchType;
* A single function input or output type. This is either a single path ID, or a pair of
* [path ID, generics].
*
* Numeric IDs are *ONE-indexed* into the paths array (`p`). Zero is used as a sentinel for `null`
* because `null` is four bytes while `0` is one byte.
*
* @typedef {number | [number, Array<RawFunctionType>]}
*/
let RawFunctionType;

View File

@ -1846,9 +1846,6 @@ function initSearch(rawSearchIndex) {
function buildItemSearchTypeAll(types, lowercasePaths) {
const PATH_INDEX_DATA = 0;
const GENERICS_DATA = 1;
if (types === null) {
return [];
}
return types.map(type => {
let pathIndex, generics;
if (typeof type === "number") {
@ -1859,6 +1856,7 @@ function initSearch(rawSearchIndex) {
generics = buildItemSearchTypeAll(type[GENERICS_DATA], lowercasePaths);
}
return {
// `0` is used as a sentinel because it's fewer bytes than `null`
name: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].name,
ty: pathIndex === 0 ? null : lowercasePaths[pathIndex - 1].ty,
generics: generics,
@ -1884,7 +1882,8 @@ function initSearch(rawSearchIndex) {
function buildFunctionSearchType(functionSearchType, lowercasePaths) {
const INPUTS_DATA = 0;
const OUTPUT_DATA = 1;
if (functionSearchType === 0 || functionSearchType === null) {
// `0` is used as a sentinel because it's fewer bytes than `null`
if (functionSearchType === 0) {
return null;
}
let inputs, output;