xbps_get_pkg_fulldeptree: switch to uthash.

There are still two users that can benefit from
uthash: transaction_files.c and xbps-fbulk.

cc @duncaen
This commit is contained in:
Juan RP 2020-02-12 09:14:25 +01:00
parent 6236d7ae41
commit 657a717855
3 changed files with 1275 additions and 43 deletions

View File

@ -19,3 +19,6 @@ internal use in the code:
- portableproplib-0.6.8 (lib/portableproplib) from - portableproplib-0.6.8 (lib/portableproplib) from
https://github.com/xtraeme/portableproplib https://github.com/xtraeme/portableproplib
- uthash-2.1.0 (include/uthash.h) from
http://troydhanson.github.com/uthash/

1227
include/uthash.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2014-2019 Juan Romero Pardines. * Copyright (c) 2014-2020 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -30,6 +30,7 @@
#include <errno.h> #include <errno.h>
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
#include "uthash.h"
struct item; struct item;
@ -39,63 +40,46 @@ struct depn {
}; };
struct item { struct item {
struct item *hnext; char *pkgn; /* hash key */
struct item *bnext;
struct depn *dbase;
char *pkgn;
const char *pkgver; const char *pkgver;
xbps_array_t rdeps; xbps_array_t rdeps;
struct depn *dbase;
UT_hash_handle hh;
}; };
#define ITHSIZE 1024 static struct item *items = NULL;
#define ITHMASK (ITHSIZE - 1)
static struct item *ItemHash[ITHSIZE];
static xbps_array_t result; static xbps_array_t result;
static int
itemhash(const char *pkgn)
{
int hv = 0xA1B5F342;
int i;
assert(pkgn);
for (i = 0; pkgn[i]; ++i)
hv = (hv << 5) ^ (hv >> 23) ^ pkgn[i];
return hv & ITHMASK;
}
static struct item * static struct item *
lookupItem(const char *pkgn) lookupItem(const char *pkgn)
{ {
struct item *item; struct item *item = NULL;
assert(pkgn); assert(pkgn);
for (item = ItemHash[itemhash(pkgn)]; item; item = item->hnext) { HASH_FIND_STR(items, pkgn, item);
if (strcmp(pkgn, item->pkgn) == 0)
return item; return item;
}
return NULL;
} }
static struct item * static struct item *
addItem(xbps_array_t rdeps, const char *pkgn) addItem(xbps_array_t rdeps, const char *pkgn, const char *pkgver)
{ {
struct item **itemp; struct item *item = NULL;
struct item *item = calloc(sizeof(*item), 1);
assert(pkgn); assert(pkgn);
assert(item); assert(pkgver);
itemp = &ItemHash[itemhash(pkgn)]; HASH_FIND_STR(items, pkgn, item);
item->hnext = *itemp; if (item)
return item;
item = malloc(sizeof(*item));
assert(item);
item->pkgn = strdup(pkgn); item->pkgn = strdup(pkgn);
assert(item->pkgn); item->pkgver = pkgver;
item->rdeps = xbps_array_copy(rdeps); item->rdeps = rdeps;
*itemp = item; item->dbase = NULL;
HASH_ADD_KEYPTR(hh, items, item->pkgn, strlen(pkgn), item);
return item; return item;
} }
@ -103,8 +87,9 @@ addItem(xbps_array_t rdeps, const char *pkgn)
static void static void
addDepn(struct item *item, struct item *xitem) addDepn(struct item *item, struct item *xitem)
{ {
struct depn *depn = calloc(sizeof(*depn), 1); struct depn *depn = calloc(1, sizeof(*depn));
assert(depn);
assert(item); assert(item);
assert(xitem); assert(xitem);
@ -134,6 +119,20 @@ add_deps_recursive(struct item *item, bool first)
xbps_object_release(str); xbps_object_release(str);
} }
static void
cleanup(void)
{
struct item *item, *itmp;
HASH_ITER(hh, items, item, itmp) {
HASH_DEL(items, item);
if (item->dbase)
free(item->dbase);
free(item->pkgn);
free(item);
}
}
/* /*
* Recursively calculate all dependencies. * Recursively calculate all dependencies.
*/ */
@ -143,7 +142,7 @@ ordered_depends(struct xbps_handle *xhp, xbps_dictionary_t pkgd, bool rpool,
{ {
xbps_array_t rdeps, provides; xbps_array_t rdeps, provides;
xbps_string_t str; xbps_string_t str;
struct item *item, *xitem; struct item *item = NULL, *xitem = NULL;
const char *pkgver = NULL, *pkgname = NULL; const char *pkgver = NULL, *pkgname = NULL;
assert(xhp); assert(xhp);
@ -151,7 +150,6 @@ ordered_depends(struct xbps_handle *xhp, xbps_dictionary_t pkgd, bool rpool,
rdeps = xbps_dictionary_get(pkgd, "run_depends"); rdeps = xbps_dictionary_get(pkgd, "run_depends");
provides = xbps_dictionary_get(pkgd, "provides"); provides = xbps_dictionary_get(pkgd, "provides");
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname); xbps_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname);
item = lookupItem(pkgname); item = lookupItem(pkgname);
@ -160,8 +158,11 @@ ordered_depends(struct xbps_handle *xhp, xbps_dictionary_t pkgd, bool rpool,
return item; return item;
} }
item = addItem(rdeps, pkgname); if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver)) {
item->pkgver = pkgver; abort();
}
item = addItem(rdeps, pkgname, pkgver);
assert(item); assert(item);
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
@ -241,5 +242,6 @@ xbps_get_pkg_fulldeptree(struct xbps_handle *xhp, const char *pkg, bool rpool)
if (ordered_depends(xhp, pkgd, rpool, 0) == NULL) if (ordered_depends(xhp, pkgd, rpool, 0) == NULL)
return NULL; return NULL;
cleanup();
return result; return result;
} }