feat: flatten file tree for better performance

This commit is contained in:
tdurieux
2024-04-26 10:31:57 +01:00
parent ccdc95e4a8
commit 710f7328e7
23 changed files with 516 additions and 514 deletions

View File

@@ -277,7 +277,6 @@ router.get("/conferences", async (req, res) => {
],
};
}
res.json({
query: query,
page,

View File

@@ -26,7 +26,6 @@ router.get(
const repo = await getRepo(req, res, {
nocheck: false,
includeFiles: false,
});
if (!repo) return;

View File

@@ -131,7 +131,6 @@ router.post(
try {
const repo = await getRepo(req, res, {
nocheck: true,
includeFiles: false,
});
if (!repo) return;
@@ -158,7 +157,6 @@ router.delete(
async (req: express.Request, res: express.Response) => {
const repo = await getRepo(req, res, {
nocheck: true,
includeFiles: false,
});
if (!repo) return;
// if (repo.status == "removing") return res.json({ status: repo.status });
@@ -271,7 +269,6 @@ router.get("/:repoId/", async (req: express.Request, res: express.Response) => {
try {
const repo = await getRepo(req, res, {
nocheck: true,
includeFiles: false,
});
if (!repo) return;
@@ -364,7 +361,6 @@ router.post(
try {
const repo = await getRepo(req, res, {
nocheck: true,
includeFiles: false,
});
if (!repo) return;
const user = await getUser(req);

View File

@@ -63,10 +63,16 @@ router.get(
"/:repoId/files",
async (req: express.Request, res: express.Response) => {
res.header("Cache-Control", "no-cache");
const repo = await getRepo(req, res, { includeFiles: true });
const repo = await getRepo(req, res);
if (!repo) return;
try {
res.json(await repo.anonymizedFiles({ includeSha: false }));
res.json(
await repo.anonymizedFiles({
includeSha: false,
recursive: false,
path: req.query.path as string,
})
);
} catch (error) {
handleError(error, res, req);
}
@@ -80,7 +86,6 @@ router.get(
res.header("Cache-Control", "no-cache");
const repo = await getRepo(req, res, {
nocheck: true,
includeFiles: false,
});
if (!repo) return;
let redirectURL = null;

View File

@@ -38,15 +38,12 @@ export async function getPullRequest(
export async function getRepo(
req: express.Request,
res: express.Response,
opt: { nocheck?: boolean; includeFiles?: boolean } = {
opt: { nocheck?: boolean } = {
nocheck: false,
includeFiles: false,
}
) {
try {
const repo = await db.getRepository(req.params.repoId, {
includeFiles: opt.includeFiles === true,
});
const repo = await db.getRepository(req.params.repoId);
if (opt.nocheck == true) {
} else {
// redirect if the repository is expired

View File

@@ -3,7 +3,6 @@ import { getRepo, handleError } from "./route-utils";
import * as path from "path";
import AnonymizedFile from "../../core/AnonymizedFile";
import AnonymousError from "../../core/AnonymousError";
import { Tree, TreeElement } from "../../core/types";
import * as marked from "marked";
import { streamToString } from "../../core/anonymize-utils";
@@ -35,55 +34,45 @@ async function webView(req: express.Request, res: express.Response) {
});
}
if (repo.options.pageSource?.branch != repo.model.source.branch) {
if (repo.options.pageSource.branch != repo.model.source.branch) {
throw new AnonymousError("page_not_supported_on_different_branch", {
httpStatus: 400,
object: repo,
});
}
let requestPath = path.join(
repo.options.pageSource?.path,
req.path.substring(
req.path.indexOf(req.params.repoId) + req.params.repoId.length
)
);
let wRoot = repo.options.pageSource.path;
if (wRoot.at(0) == "/") {
wRoot = wRoot.substring(1);
}
const filePath = req.path.split(req.params.repoId)[1];
let requestPath = path.join(wRoot, filePath);
let f = new AnonymizedFile({
repository: repo,
anonymizedPath: requestPath,
});
if (requestPath[requestPath.length - 1] == "/") {
// find index file
const paths = f.anonymizedPath.trim().split("/");
let currentAnonymized: TreeElement = await repo.anonymizedFiles({
includeSha: true,
if (
requestPath.at(-1) == "/" &&
req.headers.accept?.includes("text/html")
) {
// look for index file
const candidates = await repo.files({
recursive: false,
path: await f.originalPath(),
});
for (let i = 0; i < paths.length; i++) {
const fileName = paths[i];
if (fileName == "") {
continue;
}
if (!(currentAnonymized as Tree)[fileName]) {
throw new AnonymousError("file_not_found", {
object: repo,
httpStatus: 404,
});
}
currentAnonymized = (currentAnonymized as Tree)[fileName];
}
let best_match = null;
let bestMatch = null;
indexSelector: for (const p of indexPriority) {
for (let filename in currentAnonymized) {
if (filename.toLowerCase() == p) {
best_match = filename;
for (const file of candidates) {
if (file.name.toLowerCase() == p) {
bestMatch = file;
break indexSelector;
}
}
}
if (best_match) {
requestPath = path.join(requestPath, best_match);
if (bestMatch) {
requestPath = path.join(bestMatch.path, bestMatch.name);
f = new AnonymizedFile({
repository: repo,
anonymizedPath: requestPath,