🏡 index : ~doyle/rgit.git

author Jordan Doyle <jordan@doyle.la> 2024-10-17 18:49:14.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2024-10-17 18:49:14.0 +01:00:00
commit
8ecc2c5a51717c83614410c9c67cb1346e238d22 [patch]
tree
7750889bb6c13fb6a6c09c2f795ffdc23273a21a
parent
9bd568f3e1fda3ff8afd75edbbcbbc63440354e9
download
8ecc2c5a51717c83614410c9c67cb1346e238d22.tar.gz

Avoid allocating tag names in a loop



Diff

 src/git.rs                      |  3 +--
 src/database/schema/commit.rs   |  2 +-
 src/database/schema/tag.rs      | 17 +++++++++++++++--
 src/methods/repo/mod.rs         |  3 ++-
 src/methods/repo/refs.rs        | 23 ++++++++++++++++++-----
 templates/repo/macros/refs.html |  4 ++--
 6 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/src/git.rs b/src/git.rs
index d5dd2b4..aa26a9b 100644
--- a/src/git.rs
+++ a/src/git.rs
@@ -216,8 +216,7 @@
                                while let Ok(Some(Ok(item))) = object
                                    .try_into_tree()
                                    .iter()
                                    .map(gix::Tree::iter)
                                    .flatten()
                                    .flat_map(gix::Tree::iter)
                                    .at_most_one()
                                {
                                    let nested_object = item.object().context(
diff --git a/src/database/schema/commit.rs b/src/database/schema/commit.rs
index 567568b..4cd97af 100644
--- a/src/database/schema/commit.rs
+++ a/src/database/schema/commit.rs
@@ -166,7 +166,7 @@
        };

        Yoke::try_attach_to_cart(Box::from(value), |value| {
            rkyv::access::<_, rkyv::rancor::Error>(&value)
            rkyv::access::<_, rkyv::rancor::Error>(value)
        })
        .context("Failed to deserialize commit")
        .map(Some)
diff --git a/src/database/schema/tag.rs b/src/database/schema/tag.rs
index 60cf53c..e57dfa9 100644
--- a/src/database/schema/tag.rs
+++ a/src/database/schema/tag.rs
@@ -34,6 +34,7 @@
    prefix: RepositoryId,
}

pub type YokedString = Yoked<&'static str>;
pub type YokedTag = Yoked<&'static <Tag as Archive>::Archived>;

impl TagTree {
@@ -88,7 +89,7 @@
            .collect())
    }

    pub fn fetch_all(&self) -> anyhow::Result<Vec<(String, YokedTag)>> {
    pub fn fetch_all(&self) -> anyhow::Result<Vec<(YokedString, YokedTag)>> {
        let cf = self
            .db
            .cf_handle(TAG_FAMILY)
@@ -99,9 +100,15 @@
            .prefix_iterator_cf(cf, self.prefix.to_be_bytes())
            .filter_map(Result::ok)
            .filter_map(|(name, value)| {
                let name = String::from_utf8_lossy(name.strip_prefix(&self.prefix.to_be_bytes())?)
                    .strip_prefix("refs/tags/")?
                    .to_string();
                let name = Yoke::try_attach_to_cart(name, |data| {
                    let data = data
                        .strip_prefix(&self.prefix.to_be_bytes())
                        .ok_or(())?
                        .strip_prefix(b"refs/tags/")
                        .ok_or(())?;
                    simdutf8::basic::from_utf8(data).map_err(|_| ())
                })
                .ok()?;

                Some((name, value))
            })
@@ -111,7 +118,7 @@
                })?;
                Ok((name, value))
            })
            .collect::<anyhow::Result<Vec<(String, YokedTag)>>>()?;
            .collect::<anyhow::Result<Vec<(YokedString, YokedTag)>>>()?;

        res.sort_unstable_by(|a, b| {
            let a_tagger = a.1.get().tagger.as_ref().map(ArchivedAuthor::time);
diff --git a/src/methods/repo/mod.rs b/src/methods/repo/mod.rs
index 6ed5cdb..43ac306 100644
--- a/src/methods/repo/mod.rs
+++ a/src/methods/repo/mod.rs
@@ -37,6 +37,7 @@
    tag::handle as handle_tag,
    tree::handle as handle_tree,
};
use crate::database::schema::tag::YokedString;
use crate::{
    database::schema::{commit::YokedCommit, tag::YokedTag},
    layers::UnwrapInfallible,
@@ -192,5 +193,5 @@

pub struct Refs {
    heads: BTreeMap<String, YokedCommit>,
    tags: Vec<(String, YokedTag)>,
    tags: Vec<(YokedString, YokedTag)>,
}
diff --git a/src/methods/repo/refs.rs b/src/methods/repo/refs.rs
index 8af9651..f81b062 100644
--- a/src/methods/repo/refs.rs
+++ a/src/methods/repo/refs.rs
@@ -1,10 +1,5 @@
use std::{collections::BTreeMap, sync::Arc};

use anyhow::Context;
use askama::Template;
use axum::{response::IntoResponse, Extension};
use rkyv::string::ArchivedString;

use crate::{
    into_response,
    methods::{
@@ -12,6 +7,11 @@
        repo::{Refs, Repository, Result},
    },
};
use anyhow::Context;
use askama::Template;
use axum::{response::IntoResponse, Extension};
use rkyv::string::ArchivedString;
use yoke::Yoke;

#[derive(Template)]
#[template(path = "repo/refs.html")]
@@ -28,17 +28,20 @@
    tokio::task::spawn_blocking(move || {
        let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
            .context("Repository does not exist")?;
        let repository = repository.get();

        let heads_db = repository.heads(&db)?;
        let heads_db = heads_db.as_ref().map(Yoke::get);

        let mut heads = BTreeMap::new();
        if let Some(heads_db) = repository.get().heads(&db)? {
            for head in heads_db
                .get()
        if let Some(archived_heads) = heads_db {
            for head in archived_heads
                .0
                .as_slice()
                .iter()
                .map(ArchivedString::as_str)
            {
                let commit_tree = repository.get().commit_tree(db.clone(), head);
                let commit_tree = repository.commit_tree(db.clone(), head);
                let name = head.strip_prefix("refs/heads/");

                if let (Some(name), Some(commit)) = (name, commit_tree.fetch_latest_one()?) {
@@ -47,7 +50,7 @@
            }
        }

        let tags = repository.get().tag_tree(db).fetch_all()?;
        let tags = repository.tag_tree(db).fetch_all()?;

        Ok(into_response(View {
            repo,
diff --git a/templates/repo/macros/refs.html b/templates/repo/macros/refs.html
index d054429..bcaeee2 100644
--- a/templates/repo/macros/refs.html
+++ a/templates/repo/macros/refs.html
@@ -40,8 +40,8 @@
    <tbody>
    {% for (name, tag) in tags -%}
    <tr>
        <td><a href="/{{ repo.display() }}/tag/?h={{ name }}">{{- name -}}</a></td>
        <td><a href="/{{ repo.display() }}/snapshot?h={{ name }}">{{- name -}}.tar.gz</a></td>
        <td><a href="/{{ repo.display() }}/tag/?h={{ name.get() }}">{{- name.get() -}}</a></td>
        <td><a href="/{{ repo.display() }}/snapshot?h={{ name.get() }}">{{- name.get() -}}.tar.gz</a></td>
        <td>
            {% if let Some(tagger) = tag.get().tagger.as_ref() -%}
            <img src="{{ tagger.email|gravatar }}" width="13" height="13">