From f42b3f58e80d843c244cdd7b0510a5799ecb2592 Mon Sep 17 00:00:00 2001 From: NicholasCowie Date: Tue, 5 Mar 2024 09:54:19 +0100 Subject: [PATCH 1/5] updating metropolis hastings --- docs/index.html | 73 ++++++++++++++++----- docs/metropolis-hastings.html | 72 +++++++++++++------- materials/img/dimension_plot.png | Bin 0 -> 10940 bytes materials/img/dimension_sphere_diagram.png | Bin 0 -> 39548 bytes materials/metropolis-hastings.qmd | 42 +++++++++++- 5 files changed, 144 insertions(+), 43 deletions(-) create mode 100644 materials/img/dimension_plot.png create mode 100644 materials/img/dimension_sphere_diagram.png diff --git a/docs/index.html b/docs/index.html index fccce19..1f9dee8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,7 @@ - + @@ -1036,6 +1036,18 @@ // create the index var fuseIndex = undefined; var shownWarning = false; + +// fuse index options +const kFuseIndexOptions = { + keys: [ + { name: "title", weight: 20 }, + { name: "section", weight: 20 }, + { name: "text", weight: 10 }, + ], + ignoreLocation: true, + threshold: 0.1, +}; + async function readSearchData() { // Initialize the search index on demand if (fuseIndex === undefined) { @@ -1046,17 +1058,7 @@ shownWarning = true; return; } - // create fuse index - const options = { - keys: [ - { name: "title", weight: 20 }, - { name: "section", weight: 20 }, - { name: "text", weight: 10 }, - ], - ignoreLocation: true, - threshold: 0.1, - }; - const fuse = new window.Fuse([], options); + const fuse = new window.Fuse([], kFuseIndexOptions); // fetch the main search.json const response = await fetch(offsetURL("search.json")); @@ -1587,8 +1589,34 @@ }); } -function fuseSearch(query, fuse, fuseOptions) { - return fuse.search(query, fuseOptions).map((result) => { +let subSearchTerm = undefined; +let subSearchFuse = undefined; +const kFuseMaxWait = 125; + +async function fuseSearch(query, fuse, fuseOptions) { + let index = fuse; + // Fuse.js using the Bitap algorithm for text matching which runs in + // O(nm) time (no matter the structure of the text). In our case this + // means that long search terms mixed with large index gets very slow + // + // This injects a subIndex that will be used once the terms get long enough + // Usually making this subindex is cheap since there will typically be + // a subset of results matching the existing query + if (subSearchFuse !== undefined && query.startsWith(subSearchTerm)) { + // Use the existing subSearchFuse + index = subSearchFuse; + } else if (subSearchFuse !== undefined) { + // The term changed, discard the existing fuse + subSearchFuse = undefined; + subSearchTerm = undefined; + } + + // Search using the active fuse + const then = performance.now(); + const resultsRaw = await index.search(query, fuseOptions); + const now = performance.now(); + + const results = resultsRaw.map((result) => { const addParam = (url, name, value) => { const anchorParts = url.split("#"); const baseUrl = anchorParts[0]; @@ -1605,6 +1633,17 @@ crumbs: result.item.crumbs, }; }); + + // If we don't have a subfuse and the query is long enough, go ahead + // and create a subfuse to use for subsequent queries + if (now - then > kFuseMaxWait && subSearchFuse === undefined) { + subSearchTerm = query; + subSearchFuse = new window.Fuse([], kFuseIndexOptions); + resultsRaw.forEach((rr) => { + subSearchFuse.add(rr.item); + }); + } + return results; } @@ -4607,7 +4646,7 @@ .bi-suitcase2::before { content: "\f902"; } .bi-vignette::before { content: "\f903"; } - +