al.c: reimplemented alProvIndex, removed alMakeIndex()

This commit is contained in:
Alexey Tourbin 2009-10-04 06:58:58 +04:00
parent aee6223979
commit 216526577b
4 changed files with 55 additions and 124 deletions

164
lib/al.c
View File

@ -104,81 +104,54 @@ void *axGrow(void *index, int esize, int more)
/** \ingroup rpmdep
* A single available item (e.g. a Provides: dependency).
*/
struct availableIndexEntry {
/*@dependent@*/ struct availablePackage * package; /*!< Containing package. */
/*@dependent@*/ const char * entry; /*!< Available item name. */
int entryLen; /*!< No. of bytes in name. */
int entryIx; /*!< Item index. */
enum indexEntryType {
IET_PROVIDES=1 /*!< A Provides: dependency. */
} type; /*!< Type of available item. */
struct alProvEntry {
/*@dependent@*/ const char * name; /*!< Provides name. */
int len; /*!< No. of bytes in name. */
int pkgIx; /*!< Containing package index. */
int provIx; /*!< Provides index in package. */
} ;
/** \ingroup rpmdep
* Index of all available items.
*/
struct availableIndex {
struct alProvIndex {
int sorted;
int size; /*!< No. of available items. */
struct availableIndexEntry index[1]; /*!< Array of available items. */
struct alProvEntry prov[1]; /*!< Array of available items. */
} ;
/**
* Compare two available index entries by name (qsort/bsearch).
* @param one 1st available index entry
* @param two 2nd available index entry
* @return result of comparison
*/
static int indexcmp(const void * one, const void * two) /*@*/
static
void alIndexPkgProvides(availableList al, int pkgIx)
{
const struct availableIndexEntry * a = one;
const struct availableIndexEntry * b = two;
int lenchk = a->entryLen - b->entryLen;
if (lenchk)
return lenchk;
return strcmp(a->entry, b->entry);
}
void alMakeIndex(availableList al)
{
if (al->index) // got an index
const struct availablePackage *alp = &al->list[pkgIx];
if (alp->providesCount == 0)
return;
int i, j, k;
int ai_size = 0;
for (i = 0; i < al->size; i++)
ai_size += al->list[i].providesCount;
if (ai_size == 0)
return;
struct alProvIndex *px = al->provIndex =
axGrow(al->provIndex, sizeof(*px->prov), alp->providesCount);
struct availableIndex *ai = al->index =
xmalloc(sizeof(*ai) + sizeof(*ai->index) * (ai_size - 1));
ai->size = ai_size;
k = 0;
for (i = 0; i < al->size; i++) {
for (j = 0; j < al->list[i].providesCount; j++) {
ai->index[k].package = al->list + i;
ai->index[k].entry = al->list[i].provides[j];
ai->index[k].entryLen = strlen(al->list[i].provides[j]);
ai->index[k].entryIx = j;
ai->index[k].type = IET_PROVIDES;
k++;
}
int provIx;
for (provIx = 0; provIx < alp->providesCount; provIx++) {
struct alProvEntry *pe = &px->prov[px->size++];
pe->name = alp->provides[provIx];
pe->len = strlen(pe->name);
pe->pkgIx = pkgIx;
pe->provIx = provIx;
}
qsort(ai->index, ai->size, sizeof(*ai->index), indexcmp);
px->sorted = 0;
}
/**
* Destroy available item index.
* @param al available list
*/
static void alFreeIndex(availableList al)
/*@modifies al @*/
static
struct alProvEntry *alSearchProv(availableList al, const char *name, int *n)
{
al->index = _free(al->index);
return axSearch(al->provIndex, sizeof(*al->provIndex->prov), name, n);
}
static
void alFreeProvIndex(availableList al)
{
al->provIndex = _free(al->provIndex);
}
/**
@ -283,8 +256,8 @@ alAllSatisfiesDepend(const availableList al,
const char * keyType, const char * keyDepend,
const char * keyName, const char * keyEVR, int keyFlags)
{
struct availablePackage * p, ** ret = NULL;
int i, rc, found;
struct availablePackage ** ret = NULL;
int i, n;
if (*keyName == '/') {
ret = alAllFileSatisfiesDepend(al, keyType, keyName);
@ -293,55 +266,25 @@ alAllSatisfiesDepend(const availableList al,
return ret;
}
const struct availableIndex *ai = al->index;
if (ai == NULL)
return NULL;
struct availableIndexEntry needle, * match;
needle.entry = keyName;
needle.entryLen = strlen(keyName);
match = bsearch(&needle, ai->index, ai->size, sizeof(*ai->index), indexcmp);
if (match == NULL)
return NULL;
/* rewind to the first match */
while (match > ai->index && indexcmp(match-1, &needle) == 0)
match--;
for (ret = NULL, found = 0;
match < ai->index + ai->size &&
indexcmp(match, &needle) == 0;
match++)
{
p = match->package;
rc = 0;
switch (match->type) {
case IET_PROVIDES:
i = match->entryIx;
{ const char * proEVR;
int proFlags;
proEVR = (p->providesEVR ? p->providesEVR[i] : NULL);
proFlags = (p->provideFlags ? p->provideFlags[i] : 0);
if ((keyFlags & RPMSENSE_SENSEMASK) && !(proFlags & RPMSENSE_SENSEMASK))
proFlags |= RPMSENSE_EQUAL;
rc = rpmRangesOverlap(p->provides[i], proEVR, proFlags,
int found = 0;
const struct alProvEntry *pe = alSearchProv(al, keyName, &n);
for (i = 0, ret = NULL; pe && i < n; i++, pe++) {
struct availablePackage *alp = &al->list[pe->pkgIx];
int provIx = pe->provIx;
const char *provName = alp->provides[provIx];
const char *provEVR = alp->providesEVR ? alp->providesEVR[provIx] : NULL;
int provFlags = alp->provideFlags ? alp->provideFlags[provIx] : 0;
if ((keyFlags & RPMSENSE_SENSEMASK) && !(provFlags & RPMSENSE_SENSEMASK))
provFlags |= RPMSENSE_EQUAL;
int rc = rpmRangesOverlap(provName, provEVR, provFlags,
keyName, keyEVR, keyFlags);
if (rc)
/*@switchbreak@*/ break;
}
if (keyType && keyDepend && rc)
rpmMessage(RPMMESS_DEBUG, _("%s: %-45s YES (added provide)\n"),
keyType, keyDepend+2);
break;
}
if (rc) {
ret = xrealloc(ret, (found + 2) * sizeof(*ret));
if (ret) /* can't happen */
ret[found++] = p;
}
if (rc == 0)
continue;
if (keyType && keyDepend)
rpmMessage(RPMMESS_DEBUG, _("%s: %-45s YES (added provide)\n"),
keyType, keyDepend+2);
ret = xrealloc(ret, (found + 2) * sizeof(*ret));
ret[found++] = alp;
}
if (ret)
@ -500,8 +443,7 @@ alAddPackage(availableList al,
p->relocs = NULL;
}
alFreeIndex(al);
alIndexPkgProvides(al, pkgNum);
return p;
}
@ -550,5 +492,5 @@ void alFree(availableList al)
al->dirs = _free(al->dirs);
al->numDirs = 0;
al->list = _free(al->list);
alFreeIndex(al);
alFreeProvIndex(al);
}

View File

@ -13,7 +13,7 @@ void alCreate(availableList al)
al->size = 0;
al->dirs = NULL;
al->numDirs = 0;
al->index = NULL;
al->provIndex = NULL;
}
/**
@ -38,13 +38,6 @@ alAddPackage(availableList al,
/*@null@*/ FD_t fd, /*@null@*/ rpmRelocation * relocs)
/*@modifies al, h @*/;
/**
* Generate index for available list.
* @param al available list
*/
void alMakeIndex(availableList al)
/*@modifies al @*/;
/**
* Check added package file lists for package(s) that have a provide.
* @param al available list

View File

@ -1205,8 +1205,6 @@ int rpmdepOrder(rpmTransactionSet ts)
int qlen;
int i, j;
alMakeIndex(&ts->addedPackages);
/* T1. Initialize. */
loopcheck = npkgs;
@ -1539,8 +1537,6 @@ int rpmdepCheck(rpmTransactionSet ts,
*conflicts = NULL;
*numConflicts = 0;
alMakeIndex(&ts->addedPackages);
/*
* Look at all of the added packages and make sure their dependencies
* are satisfied.

View File

@ -89,7 +89,7 @@ typedef /*@abstract@*/ struct availableList_s {
int size; /*!< No. of pkgs in list. */
/*@owned@*/ /*@null@*/ dirInfo dirs; /*!< Set of directories. */
int numDirs; /*!< No. of directories. */
struct availableIndex *index; /*!< Set of available items. */
struct alProvIndex *provIndex; /*!< Provides index. */
} * availableList;
/** \ingroup rpmdep