From 71bef066c0a4bd4f1656298901ee10258e79415d Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 13 May 2026 10:02:31 +0300 Subject: [PATCH] optimize allocations --- gitly.v | 24 ++++++++++++++++++----- main.v | 19 ++++++------------ repo/file_template.v | 35 ++++++++++++++++++++++----------- repo/lang_stats.v | 7 +++++-- repo/repo_routes.v | 45 ++++++++++++++++++++----------------------- static/assets/version | 2 +- 6 files changed, 76 insertions(+), 56 deletions(-) diff --git a/gitly.v b/gitly.v index cfccb69..31afad4 100644 --- a/gitly.v +++ b/gitly.v @@ -92,6 +92,7 @@ fn new_app() !&App { app.version = version app.handle_static('static', true)! + app.serve_static('/favicon.ico', 'static/assets/favicon.svg')! if !os.exists('avatars') { os.mkdir('avatars')! } @@ -142,17 +143,28 @@ pub fn (mut app App) init_server() { } pub fn (mut app App) before_request(mut ctx Context) bool { - url := ctx.req.url + $if trace_prealloc ? { + unsafe { prealloc_scope_checkpoint(c'gitly before_request start') } + } ctx.logged_in = app.is_logged_in(mut ctx) - app.load_settings() // TODO no need in doing this for each request + $if trace_prealloc ? { + unsafe { prealloc_scope_checkpoint(c'gitly checked login') } + } if ctx.logged_in { ctx.user = app.get_user_from_cookies(ctx) or { ctx.logged_in = false User{} } } - dump(url) - ctx.lang = Lang.from_string(ctx.get_cookie('lang') or { 'en' }) or { Lang.en } + $if trace_prealloc ? { + unsafe { prealloc_scope_checkpoint(c'gitly loaded user') } + } + lang_cookie := ctx.get_cookie('lang') or { '' } + ctx.lang = if lang_cookie == 'ru' { .ru } else { .en } + + $if trace_prealloc ? { + unsafe { prealloc_scope_checkpoint(c'gitly loaded lang') } + } return true } @@ -292,8 +304,10 @@ fn (mut app App) send_file(filname string, content string) veb.Result { } fn (mut ctx Context) page_gen_time() string { + if ctx.page_gen_start == 0 { + return '<1ms' + } diff := int(time.ticks() - ctx.page_gen_start) - println('DIFF=${diff}') return if diff == 0 { '<1ms' } else { diff --git a/main.v b/main.v index c0fa890..477b717 100644 --- a/main.v +++ b/main.v @@ -7,6 +7,9 @@ enum Lang { ru } +const tr_menu_en = '' +const tr_menu_ru = '' + fn get_port(conf config.Config) int { // Priority: -p flag > GITLY_PORT env > config.json port > 8080 for i, arg in os.args { @@ -42,18 +45,8 @@ fn main() { } fn build_tr_menu(cur_lang Lang) string { - println('BUILD TR ${cur_lang}') - // mut sb := strings.new_builder() - // sb.write_string('' + - '' + - '' - /* - s := match cur_lang { - .ru { 'English' } - .en { 'Русский' } + return match cur_lang { + .ru { tr_menu_ru } + .en { tr_menu_en } } - */ - return s } diff --git a/repo/file_template.v b/repo/file_template.v index 5ddf6f0..27a07e1 100644 --- a/repo/file_template.v +++ b/repo/file_template.v @@ -1,17 +1,30 @@ module main import veb -import regex - -fn replace_issue_id(re regex.RE, in_txt string, _ int, _ int) string { - issue_id := re.get_group_by_id(in_txt, 0) - - return in_txt.replace(issue_id, '${issue_id}') -} +import strings fn (f File) format_commit_message() veb.RawHtml { - id_query := r'(#\d+)' - mut re := regex.regex_opt(id_query) or { panic(err) } - - return re.replace_by_fn(f.last_msg, replace_issue_id) + msg := f.last_msg + if msg.index_u8(`#`) == -1 { + return veb.RawHtml(msg) + } + mut b := strings.new_builder(msg.len + 32) + mut i := 0 + for i < msg.len { + if msg[i] == `#` && i + 1 < msg.len && msg[i + 1].is_digit() { + start := i + i += 2 + for i < msg.len && msg[i].is_digit() { + i++ + } + issue_id := msg[start..i] + b.write_string('') + b.write_string(issue_id) + b.write_string('') + continue + } + b.write_u8(msg[i]) + i++ + } + return veb.RawHtml(b.str()) } diff --git a/repo/lang_stats.v b/repo/lang_stats.v index fe0461e..28dd6bd 100644 --- a/repo/lang_stats.v +++ b/repo/lang_stats.v @@ -11,6 +11,8 @@ struct LangStat { color string } +const min_lang_summary_pct = 5 // pct is stored in tenths of a percent, so 5 is 0.5%. + const test_lang_stats = [ LangStat{ name: 'V' @@ -44,9 +46,10 @@ pub fn (l &LangStat) pct_html() veb.RawHtml { } pub fn (app App) find_repo_lang_stats(repo_id int) []LangStat { - return sql app.db { + stats := sql app.db { select from LangStat where repo_id == repo_id order by pct desc - } or { []LangStat{} } + } or { return []LangStat{} } + return stats.filter(it.pct >= min_lang_summary_pct) } fn (app App) remove_repo_lang_stats(repo_id int) ! { diff --git a/repo/repo_routes.v b/repo/repo_routes.v index 5fc2101..68aff4c 100644 --- a/repo/repo_routes.v +++ b/repo/repo_routes.v @@ -140,7 +140,6 @@ pub fn (mut app App) handle_repo_move(username string, repo_name string, dest st @['/:username/:repo_name'] pub fn (mut app App) handle_tree(mut ctx Context, username string, repo_name string) veb.Result { - println('handle tree()') match repo_name { 'repos' { return app.user_repos(mut ctx, username) @@ -354,7 +353,6 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br return ctx.not_found() } mut clone_url := '' - eprintln('!!! REPO STATUS = ${repo.status}') if repo.status == .cloning { clone_url = app.clone_urls[repo.id] or { '' } return $veb.html('templates/cloning_in_process.html') @@ -369,20 +367,19 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br } repo_id := repo.id - log_prefix := '${username}/${repo_name}' // XTODO // app.fetch_tags(repo) or { app.info(err.str()) } - ctx.current_path = '/${path}' - if ctx.current_path.contains('/favicon.svg') { + ctx.current_path = path + if path.contains('favicon.svg') { return ctx.not_found() } - path_parts := path.split('/') - ctx.path_split = [repo_name] - ctx.path_split << path_parts + if path != '' { + ctx.path_split << path.split('/') + } ctx.is_tree = true @@ -391,17 +388,13 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br mut up := '/' can_up := path != '' if can_up { - if path.split('/').len == 1 { + if !path.contains('/') { up = '../..' } else { up = ctx.req.url.all_before_last('/') } } - if ctx.current_path.starts_with('/') { - ctx.current_path = ctx.current_path[1..] - } - tree_mode := if 'mode' in ctx.query { ctx.query['mode'] } else { 'tree' } is_top_files_mode := tree_mode == 'top-files' top_files := if is_top_files_mode { @@ -419,15 +412,11 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br mut items := app.find_repository_items(repo_id, branch_name, ctx.current_path) branch := app.find_repo_branch_by_name(repo.id, branch_name) - app.info('${log_prefix}: ${items.len} items found in branch ${branch_name}') - show_folder_size := app.settings.tree_folder_size_enabled() if !is_top_files_mode { if items.len == 0 { // No files in the db, fetch them from git and cache in db - app.info('${log_prefix}: caching items in repository with ${repo_id}') - items = app.cache_repository_items(mut repo, branch_name, ctx.current_path) or { app.info(err.str()) []File{} @@ -462,12 +451,21 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br last_commit = app.find_repo_last_commit(repo.id, branch.id) } - dirs := items.filter(it.is_dir) - files := items.filter(!it.is_dir) - - items = [] - items << dirs - items << files + mut next_dir_idx := 0 + for scan_idx in 0 .. items.len { + if items[scan_idx].is_dir { + if scan_idx != next_dir_idx { + moving_dir := items[scan_idx] + mut move_idx := scan_idx + for move_idx > next_dir_idx { + items[move_idx] = items[move_idx - 1] + move_idx-- + } + items[next_dir_idx] = moving_dir + } + next_dir_idx++ + } + } commits_count := app.get_repo_commit_count(repo.id, branch.id) has_commits := commits_count > 0 @@ -482,7 +480,6 @@ pub fn (mut app App) tree(mut ctx Context, username string, repo_name string, br if license_file.id != 0 { license_file_path = '/${username}/${repo_name}/blob/${branch_name}/${license_file.name}' } - eprintln('license_file_path=${license_file_path}') watcher_count := app.get_count_repo_watchers(repo_id) is_repo_starred := app.check_repo_starred(repo_id, ctx.user.id) diff --git a/static/assets/version b/static/assets/version index 8522f42..effcfc9 100644 --- a/static/assets/version +++ b/static/assets/version @@ -1 +1 @@ -259c97a \ No newline at end of file +bed6428 \ No newline at end of file -- 2.39.5