Map idxmap;
+ unsigned int lastdiridx; /* last diridx we have seen */
+ unsigned int lastdirhash; /* strhash of last dir we have seen */
+
Id idx; /* index of package we're looking at */
Id hx; /* used in findfileconflicts2_cb, limit to files matching hx */
}
static void
-finddirs_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
+finddirs_cb(void *cbdatav, const char *fn, struct filelistinfo *info)
{
struct cbdata *cbdata = cbdatav;
Hashval h, hh;
}
static void
-findfileconflicts_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
+findfileconflicts_cb(void *cbdatav, const char *fn, struct filelistinfo *info)
{
struct cbdata *cbdata = cbdatav;
- int isdir = S_ISDIR(fmode);
- char *dp;
+ int isdir = S_ISDIR(info->mode);
+ const char *dp;
Id idx, oidx;
Id hx, qx;
Hashval h, hh, dhx;
idx = cbdata->idx;
- dp = strrchr(fn, '/');
- if (!dp)
+ if (!info->dirlen)
return;
- dhx = strnhash(fn, dp + 1 - fn);
+ dp = fn + info->dirlen;
+ if (info->diridx != cbdata->lastdiridx)
+ {
+ cbdata->lastdiridx = info->diridx;
+ cbdata->lastdirhash = strnhash(fn, dp - fn);
+ }
+ dhx = cbdata->lastdirhash;
#if 1
/* this mirrors the "if (!hx) hx = strlen(fn) + 1" in finddirs_cb */
- if (!isindirmap(cbdata, dhx ? dhx : dp + 1 - fn + 1))
+ if (!isindirmap(cbdata, dhx ? dhx : dp - fn + 1))
return;
#endif
- hx = strhash_cont(dp + 1, dhx);
+ hx = strhash_cont(dp, dhx);
if (!hx)
hx = strlen(fn) + 1;
}
static void
-findfileconflicts2_cb(void *cbdatav, const char *fn, int fmode, const char *md5)
+findfileconflicts2_cb(void *cbdatav, const char *fn, struct filelistinfo *info)
{
struct cbdata *cbdata = cbdatav;
- Hashval hx = strhash(fn);
+ Hashval hx;
+ const char *dp;
char md5padded[34];
+ if (!info->dirlen)
+ return;
+ dp = fn + info->dirlen;
+ if (info->diridx != cbdata->lastdiridx)
+ {
+ cbdata->lastdiridx = info->diridx;
+ cbdata->lastdirhash = strnhash(fn, dp - fn);
+ }
+ hx = cbdata->lastdirhash;
+ hx = strhash_cont(dp, hx);
if (!hx)
hx = strlen(fn) + 1;
if ((Id)hx != cbdata->hx)
return;
- strncpy(md5padded, md5, 32);
+ strncpy(md5padded, info->digest, 32);
md5padded[32] = 0;
- md5padded[33] = fmode >> 24;
+ md5padded[33] = info->color;
/* printf("%d, hx %x -> %s %d %s\n", cbdata->idx, hx, fn, fmode, md5); */
queue_push(&cbdata->files, cbdata->filesspacen);
addfilesspace(cbdata, (unsigned char *)md5padded, 34);
if (i == cutoff)
cbdata.create = 0;
handle = (*handle_cb)(pool, p, handle_cbdata);
- if (handle)
- rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, findfileconflicts_cb, &cbdata);
+ if (!handle)
+ continue;
+ cbdata.lastdiridx = -1;
+ rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, findfileconflicts_cb, &cbdata);
}
POOL_DEBUG(SOLV_DEBUG_STATS, "filemap size: %d, used %d\n", cbdata.cflmapn + 1, cbdata.cflmapused);
handle = (*handle_cb)(pool, p, handle_cbdata);
if (!handle)
continue;
+ cbdata.lastdiridx = -1;
rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata);
pend = cbdata.files.count;
handle = (*handle_cb)(pool, q, handle_cbdata);
if (!handle)
continue;
+ cbdata.lastdiridx = -1;
rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata);
for (ii = 0; ii < pend; ii++)
for (jj = pend; jj < cbdata.files.count; jj++)
l = strlen(lt);
while ((c = *str++) != 0)
r += (r << 3) + c;
- sprintf(hash, "%08x", r);
- sprintf(hash + 8, "%08x", l);
- sprintf(hash + 16, "%08x", 0);
- sprintf(hash + 24, "%08x", 0);
+ sprintf(hash, "%08x%08x%08x%08x", r, l, 0, 0);
}
void
-rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, int, const char *), void *cbdata)
+rpm_iterate_filelist(void *rpmhandle, int flags, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata)
{
RpmHead *rpmhead = rpmhandle;
char **bn;
int i, l1, l;
char *space = 0;
int spacen = 0;
- char md5[33], *md5p = 0;
+ char md5[33];
+ struct filelistinfo info;
dn = headstringarray(rpmhead, TAG_DIRNAMES, &dcnt);
if (!dn)
if ((flags & RPM_ITERATE_FILELIST_ONLYDIRS) != 0)
{
for (i = 0; i < dcnt; i++)
- (*cb)(cbdata, dn[i], 0, (char *)0);
+ (*cb)(cbdata, dn[i], 0);
solv_free(dn);
return;
}
}
lastdir = dcnt;
lastdirl = 0;
+ memset(&info, 0, sizeof(info));
for (i = 0; i < cnt; i++)
{
if (ff && (ff[i] & FILEFLAG_GHOST) != 0)
if (diidx >= dcnt)
continue;
l1 = lastdir == diidx ? lastdirl : strlen(dn[diidx]);
- if (l1 == 0)
- continue;
l = l1 + strlen(bn[i]) + 1;
if (l > spacen)
{
lastdirl = l1;
}
strcpy(space + l1, bn[i]);
+ info.diridx = diidx;
+ info.dirlen = l1;
+ if (fm)
+ info.mode = fm[i];
if (md)
{
- md5p = md[i];
- if (S_ISLNK(fm[i]))
+ info.digest = md[i];
+ if (fm && S_ISLNK(fm[i]))
{
- md5p = 0;
+ info.digest = 0;
if (!lt)
{
lt = headstringarray(rpmhead, TAG_FILELINKTOS, &cnt2);
if (lt)
{
linkhash(lt[i], md5);
- md5p = md5;
+ info.digest = md5;
}
}
- if (!md5p)
+ if (!info.digest)
{
sprintf(md5, "%08x%08x%08x%08x", (fm[i] >> 12) & 65535, 0, 0, 0);
- md5p = md5;
+ info.digest = md5;
}
}
- (*cb)(cbdata, space, co ? (fm[i] | co[i] << 24) : fm[i], md5p);
+ if (co)
+ info.color = co[i];
+ (*cb)(cbdata, space, &info);
}
solv_free(space);
solv_free(lt);