public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Proxmox Backup Server development discussion
	<pbs-devel@lists.proxmox.com>,
	Dominik Csapak <d.csapak@proxmox.com>
Subject: Re: [pbs-devel] [PATCH proxmox-backup 5/6] api: admin: datastore: optimize `groups` api call
Date: Fri, 3 Oct 2025 12:18:38 +0200	[thread overview]
Message-ID: <5304f093-fb23-42ad-ab0c-bca839572d73@proxmox.com> (raw)
In-Reply-To: <20251003085045.1346864-7-d.csapak@proxmox.com>

Am 03.10.25 um 10:50 schrieb Dominik Csapak:
> Currently we always touch all files for each snapshot in a group when
> listing them, even though we don't need all that info.
> 
> We're only interested in getting either the last finished snapshot
> information, or the last unfinished one (which must the only one in
> normal use, we can't have multiple unfinished snapshots usually)
> 
> Instead of getting all the information upgfront, use the snapshot

s/upgfront/upfront/

> iterator of the group to get only the id, sort them by time, and
> use the first we're interested in, getting the snapshot specific info
> only for those we want to check.
> 
> In my (admittedly extreme) setup with ~600 groups with ~1000 snapshots
> each, this changes the time this api call needs from ~40s to <1s.
> (on a relatively fast disk).

nice! In the UI we mainly (only?) uses this for gathering the notes of
a group, FWICT?

> 
> While at it, lift the restriction of only returning groups with
> snapshots in them, now returning also empty ones.
> 
> To keep api compatibility, use a timestamp of 0 for those.
> (no valid backup could have been made at that time anyway)

lazy question: Is this dependent on the previous patches? From a quick
check, it looks like it might be rather independent and one could apply
this one already.

> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/api2/admin/datastore.rs | 45 +++++++++++++++++++++++--------------
>  1 file changed, 28 insertions(+), 17 deletions(-)
> 
> diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
> index 0b133d166..2252dcfa4 100644
> --- a/src/api2/admin/datastore.rs
> +++ b/src/api2/admin/datastore.rs
> @@ -166,36 +166,47 @@ fn backup_group_to_group_list_item(
>          return None;
>      }
>  
> -    let snapshots = match group.list_backups() {
> -        Ok(snapshots) => snapshots,
> +    let mut snapshots: Vec<_> = match group.iter_snapshots() {
> +        Ok(snapshots) => snapshots.collect::<Result<Vec<_>, Error>>().ok()?,
>          Err(_) => return None,
>      };
>  
>      let backup_count: u64 = snapshots.len() as u64;
> -    if backup_count == 0 {
> -        return None;
> -    }
> +    let last = if backup_count == 1 {
> +        // we may have only one unfinished snapshot
> +        snapshots.pop().and_then(|dir| BackupInfo::new(dir).ok())
> +    } else {
> +        // we either have no snapshots, or at least one finished one, since we cannot have
> +        // multiple unfinished ones
> +        snapshots.sort_by_key(|b| std::cmp::Reverse(b.backup_time()));
> +        snapshots
> +            .iter()
> +            .filter_map(|backup| match BackupInfo::new(backup.clone()) {
> +                Ok(info) => {
> +                    if info.is_finished() {
> +                        Some(info)
> +                    } else {
> +                        None
> +                    }
> +                }
> +                Err(_) => None,

nit: Could be written as a bit more concise way:

snapshots
    .iter()
    .filter_map(|backup| BackupInfo::new(backup.clone()).ok())
    .filter(|info| info.is_finished())
    .next()

With splitting the conversion to BackupInfo and filtering for finished
backups into two makes it a bit easier (or rather quicker) to follow to me.

> +            })
> +            .next()
> +    };
>  
> -    let last_backup = snapshots
> -        .iter()
> -        .fold(&snapshots[0], |a, b| {
> -            if a.is_finished() && a.backup_dir.backup_time() > b.backup_dir.backup_time() {
> -                a
> -            } else {
> -                b
> -            }
> -        })
> -        .to_owned();
> +    let (last_backup, files) = last
> +        .map(|info| (info.backup_dir.backup_time(), info.files))
> +        .unwrap_or((0, Vec::new()));
>  
>      let notes_path = datastore.group_notes_path(ns, group.as_ref());
>      let comment = file_read_firstline(notes_path).ok();
>  
>      let item = GroupListItem {
>          backup: group.into(),
> -        last_backup: last_backup.backup_dir.backup_time(),
> +        last_backup,
>          owner: Some(owner),
>          backup_count,
> -        files: last_backup.files,
> +        files,
>          comment,
>      };
>  



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


  reply	other threads:[~2025-10-03 10:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-03  8:50 [pbs-devel] [PATCH proxmox{, -backup} 0/7] introduce streaming content " Dominik Csapak
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox 1/1] pbs-api-types: add api types for " Dominik Csapak
2025-10-07  8:59   ` Wolfgang Bumiller
2025-10-08  6:41     ` Dominik Csapak
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 1/6] backup: hierarchy: add new can_access_any_namespace_in_range helper Dominik Csapak
2025-10-03  9:52   ` Thomas Lamprecht
2025-10-03 10:10     ` Dominik Csapak
2025-10-03 10:21       ` Thomas Lamprecht
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 2/6] backup: hierarchy: reuse 'NS_PRIVS_OK' for namespace helper Dominik Csapak
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 3/6] api: admin: datastore: refactor BackupGroup to GroupListItem conversion Dominik Csapak
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 4/6] api: admin: datastore: factor out 'get_group_owner' Dominik Csapak
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 5/6] api: admin: datastore: optimize `groups` api call Dominik Csapak
2025-10-03 10:18   ` Thomas Lamprecht [this message]
2025-10-03 10:51     ` Dominik Csapak
2025-10-03 12:37       ` Thomas Lamprecht
2025-10-03  8:50 ` [pbs-devel] [PATCH proxmox-backup 6/6] api: admin: datastore: implement streaming content " Dominik Csapak
2025-10-03 11:55   ` Thomas Lamprecht
2025-10-07 12:51   ` Wolfgang Bumiller
2025-10-07 14:22     ` Thomas Lamprecht
2025-10-07 14:31       ` Wolfgang Bumiller
2025-10-07 15:05         ` Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5304f093-fb23-42ad-ab0c-bca839572d73@proxmox.com \
    --to=t.lamprecht@proxmox.com \
    --cc=d.csapak@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal