[Rpm-maint] Feature request: Improved speed for 'rpm -qa'

Axel Liljencrantz liljencrantz at gmail.com
Tue Dec 19 18:29:09 UTC 2006


On 12/19/06, Michael Schroeder <mls at suse.de> wrote:
> On Tue, Dec 19, 2006 at 02:17:34PM +0100, Axel Liljencrantz wrote:
> > Performing a readahead on /var/lib/rpm/Packages seems to help a bit.
> > Cold cache times (including readahead) stays around 6 seconds on my
> > fast system, but falls from 22 seconds to 13 seconds on my slow system
> > by calling 'cat /var/lib/rpm/Packages' before calling 'rpm -qa'.
>
> Here's my rpmqpack program that list all packages by iterating
> over the Name index (i.e. it's a dirty hack). It can also be used
> to do a fast query if a package is installed.
>
> #include <sys/types.h>
> #include <limits.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #include <db.h>
>
> DBT key;
> DBT data;
>
> int
> main(int argc, char **argv)
> {
>   DB *db = 0;
>   DBC *dbc = 0;
>   int ret = 0;
>
>   if (db_create(&db, 0, 0))
>     {
>       perror("db_create");
>       exit(1);
>     }
>   if (db->open(db, 0, "/var/lib/rpm/Name", 0, DB_HASH, DB_RDONLY, 0664))
>     {
>       perror("db->open");
>       exit(1);
>     }
>   if (argc == 1)
>     {
>       if (db->cursor(db, NULL, &dbc, 0))
>         {
>           perror("db->cursor");
>           exit(1);
>         }
>       while (dbc->c_get(dbc, &key, &data, DB_NEXT) == 0)
>         printf("%*.*s\n", (int)key.size, (int)key.size, (char *)key.data);
>       dbc->c_close(dbc);
>     }
>   else
>     {
>       argc--;
>       while (argc--)
>         {
>           argv++;
>           key.data = (void *)*argv;
>           key.size = strlen(*argv);
>           data.data = NULL;
>           data.size = 0;
>           if (db->get(db, 0, &key, &data, 0) == 0)
>             printf("%s\n", *argv);
>           else
>             ret = 1;
>         }
>     }
>   db->close(db, 0);
>   return ret;
> }
>
> Cheers,
>   Michael.

This thing is as fast as lightning!

Even on my 300 MHz system, it only takes about 0.02 seconds. Is there
any chance that regular rpm could be made this fast, or is this too
much of a hack to include there? I don't think that bundling a special
command for querying the rpm database together with a general purpose
OS agnostic commandline shell is the proper way to do this...

By the way, why is this a hack? Is the index not updated when an entry
is removed or something? If not, indexes are there to be used!

I did a comparison, and on my systems the only difference in output
between your command and 'rpm -qa' is that with your command, packages
that are installed in multiple versions are only printed once, and
that package version numbers are not printed.

>
> --
> Michael Schroeder                                   mls at suse.de
> main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);}
>

-- 
Axel



More information about the Rpm-maint mailing list