if (s->repo != repo)
break;
pool_free_solvable_block(pool, i + 1, repo->end - (i + 1), reuseids);
+ repo->end = i + 1;
}
/* zero out (i.e. free) solvables belonging to this repo */
for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++)
if (s->repo == repo)
memset(s, 0, sizeof(*s));
+ repo->end = repo->start;
repo->nsolvables = 0;
/* free all data belonging to this repo */
repo->start = repo->end = p;
/* warning: sidedata must be extended before adapting start/end */
if (repo->rpmdbid)
- repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, 1);
+ repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, 1);
if (p < repo->start)
repo->start = p;
if (p + 1 > repo->end)
repo_add_solvable_block(Repo *repo, int count)
{
Id p;
- Solvable *s;
+ Solvable *s;
if (!count)
return 0;
p = pool_add_solvable_block(repo->pool, count);
s->repo = 0;
pool_free_solvable_block(repo->pool, start, count, reuseids);
FOR_REPODATAS(repo, i, data)
- if (data->end > repo->end)
- repodata_shrink(data, repo->end);
+ {
+ int dstart, dend;
+ if (data->end > repo->end)
+ repodata_shrink(data, repo->end);
+ dstart = data->start > start ? data->start : start;
+ dend = data->end < start + count ? data->end : start + count;
+ if (dstart < dend)
+ {
+ if (data->attrs)
+ {
+ int j;
+ for (j = dstart; j < dend; j++)
+ data->attrs[j - data->start] = solv_free(data->attrs[j - data->start]);
+ }
+ if (data->incoreoffset)
+ memset(data->incoreoffset + (dstart - data->start), 0, (dend - dstart) * sizeof(Id));
+ }
+ }
+}
+
+/* specialized version of repo_add_solvable_block that inserts the new solvable
+ * block before the indicated repo, which gets relocated.
+ * used in repo_add_rpmdb
+ */
+Id
+repo_add_solvable_block_before(Repo *repo, int count, Repo *beforerepo)
+{
+ Pool *pool = repo->pool;
+ Id p;
+ Solvable *s;
+ Repodata *data;
+ int i;
+
+ if (!count || !beforerepo || beforerepo->end != pool->nsolvables || beforerepo->start == beforerepo->end)
+ return repo_add_solvable_block(repo, count);
+ p = beforerepo->start;
+ /* make sure all solvables belong to beforerepo */
+ for (i = p, s = pool->solvables + i; i < beforerepo->end; i++, s++)
+ if (s->repo && s->repo != beforerepo)
+ return repo_add_solvable_block(repo, count);
+ /* now move beforerepo to back */
+ pool_add_solvable_block(pool, count); /* must return beforerepo->end! */
+ memmove(pool->solvables + p + count, pool->solvables + p, (beforerepo->end - p) * sizeof(Solvable));
+ memset(pool->solvables + p, 0, sizeof(Solvable) * count);
+ /* adapt repodata */
+ FOR_REPODATAS(beforerepo, i, data)
+ {
+ if (data->start < p)
+ continue;
+ data->start += count;
+ data->end += count;
+ }
+ beforerepo->start += count;
+ beforerepo->end += count;
+ /* we now have count free solvables at id p */
+ /* warning: sidedata must be extended before adapting start/end */
+ if (repo->rpmdbid)
+ repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, count);
+ if (p < repo->start)
+ repo->start = p;
+ if (p + count > repo->end)
+ repo->end = p + count;
+ repo->nsolvables += count;
+ for (s = pool->solvables + p; count--; s++)
+ s->repo = repo;
+ return p;
}
#define REPO_ADDID_DEP_HASHTHRES 64
#define REPO_ADDID_DEP_HASHMIN 128
-/*
+/*
* Optimization for packages with an excessive amount of provides/requires:
* if the number of deps exceed a threshold, we build a hash of the already
* seen ids.
}
/* maintain hash and lastmarkerpos */
- if (repo->lastidhash_idarraysize != repo->idarraysize || size * 2 > repo->lastidhash_mask || repo->lastmarker != marker)
+ if (repo->lastidhash_idarraysize != repo->idarraysize || (Hashval)size * 2 > repo->lastidhash_mask || repo->lastmarker != marker)
{
repo->lastmarkerpos = 0;
- if (size * 2 > repo->lastidhash_mask)
+ if (size * 2 > (Hashval)repo->lastidhash_mask)
{
repo->lastidhash_mask = mkmask(size < REPO_ADDID_DEP_HASHMIN ? REPO_ADDID_DEP_HASHMIN : size);
repo->lastidhash = solv_realloc2(repo->lastidhash, repo->lastidhash_mask + 1, sizeof(Id));
return repo_addid(repo, olddeps, id);
}
+/* return standard marker for the keyname dependency.
+ * 1: return positive marker, -1: return negative marker
+ */
+Id
+solv_depmarker(Id keyname, Id marker)
+{
+ if (marker != 1 && marker != -1)
+ return marker;
+ if (keyname == SOLVABLE_PROVIDES)
+ return marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
+ if (keyname == SOLVABLE_REQUIRES)
+ return marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
+ return 0;
+}
/*
* reserve Ids
*
* reserved ids will always begin at offset idarraysize
*/
-
Offset
repo_reserve_ids(Repo *repo, Offset olddeps, int num)
{
/***********************************************************************/
-/*
- * some SUSE specific fixups, should go into a separate file
- */
-
-Offset
-repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens)
-{
- Pool *pool = repo->pool;
- Id id, idp, idl;
- char buf[1024], *p, *dep;
- int i, l;
-
- if (provides)
- {
- for (i = provides; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "locale(", 7) && strlen(dep) < sizeof(buf) - 2)
- {
- idp = 0;
- strcpy(buf + 2, dep);
- dep = buf + 2 + 7;
- if ((p = strchr(dep, ':')) != 0 && p != dep)
- {
- *p++ = 0;
- idp = pool_str2id(pool, dep, 1);
- dep = p;
- }
- id = 0;
- while ((p = strchr(dep, ';')) != 0)
- {
- if (p == dep)
- {
- dep = p + 1;
- continue;
- }
- *p++ = 0;
- idl = pool_str2id(pool, dep, 1);
- idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
- if (id)
- id = pool_rel2id(pool, id, idl, REL_OR, 1);
- else
- id = idl;
- dep = p;
- }
- if (dep[0] && dep[1])
- {
- for (p = dep; *p && *p != ')'; p++)
- ;
- *p = 0;
- idl = pool_str2id(pool, dep, 1);
- idl = pool_rel2id(pool, NAMESPACE_LANGUAGE, idl, REL_NAMESPACE, 1);
- if (id)
- id = pool_rel2id(pool, id, idl, REL_OR, 1);
- else
- id = idl;
- }
- if (idp)
- id = pool_rel2id(pool, idp, id, REL_AND, 1);
- if (id)
- supplements = repo_addid_dep(repo, supplements, id, 0);
- }
- else if ((p = strchr(dep, ':')) != 0 && p != dep && p[1] == '/' && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- p = buf + (p - dep);
- *p++ = 0;
- idp = pool_str2id(pool, buf, 1);
- /* strip trailing slashes */
- l = strlen(p);
- while (l > 1 && p[l - 1] == '/')
- p[--l] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, idp, id, REL_WITH, 1);
- id = pool_rel2id(pool, NAMESPACE_SPLITPROVIDES, id, REL_NAMESPACE, 1);
- supplements = repo_addid_dep(repo, supplements, id, 0);
- }
- }
- }
- if (supplements)
- {
- for (i = supplements; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "system:modalias(", 16))
- dep += 7;
- if (!strncmp(dep, "modalias(", 9) && dep[9] && dep[10] && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- p = strchr(buf + 9, ':');
- if (p && p != buf + 9 && strchr(p + 1, ':'))
- {
- *p++ = 0;
- idp = pool_str2id(pool, buf + 9, 1);
- p[strlen(p) - 1] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
- id = pool_rel2id(pool, idp, id, REL_AND, 1);
- }
- else
- {
- p = buf + 9;
- p[strlen(p) - 1] = 0;
- id = pool_str2id(pool, p, 1);
- id = pool_rel2id(pool, NAMESPACE_MODALIAS, id, REL_NAMESPACE, 1);
- }
- if (id)
- repo->idarraydata[i] = id;
- }
- else if (!strncmp(dep, "packageand(", 11) && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep);
- id = 0;
- dep = buf + 11;
- while ((p = strchr(dep, ':')) != 0)
- {
- if (p == dep)
- {
- dep = p + 1;
- continue;
- }
- /* argh, allow pattern: prefix. sigh */
- if (p - dep == 7 && !strncmp(dep, "pattern", 7))
- {
- p = strchr(p + 1, ':');
- if (!p)
- break;
- }
- *p++ = 0;
- idp = pool_str2id(pool, dep, 1);
- if (id)
- id = pool_rel2id(pool, id, idp, REL_AND, 1);
- else
- id = idp;
- dep = p;
- }
- if (dep[0] && dep[1])
- {
- dep[strlen(dep) - 1] = 0;
- idp = pool_str2id(pool, dep, 1);
- if (id)
- id = pool_rel2id(pool, id, idp, REL_AND, 1);
- else
- id = idp;
- }
- if (id)
- repo->idarraydata[i] = id;
- }
- else if (!strncmp(dep, "filesystem(", 11) && strlen(dep) < sizeof(buf))
- {
- strcpy(buf, dep + 11);
- if ((p = strrchr(buf, ')')) != 0)
- *p = 0;
- id = pool_str2id(pool, buf, 1);
- id = pool_rel2id(pool, NAMESPACE_FILESYSTEM, id, REL_NAMESPACE, 1);
- repo->idarraydata[i] = id;
- }
- }
- }
- if (freshens && repo->idarraydata[freshens])
- {
- Id idsupp = 0, idfresh = 0;
- if (!supplements || !repo->idarraydata[supplements])
- return freshens;
- for (i = supplements; repo->idarraydata[i]; i++)
- {
- if (!idsupp)
- idsupp = repo->idarraydata[i];
- else
- idsupp = pool_rel2id(pool, idsupp, repo->idarraydata[i], REL_OR, 1);
- }
- for (i = freshens; repo->idarraydata[i]; i++)
- {
- if (!idfresh)
- idfresh = repo->idarraydata[i];
- else
- idfresh = pool_rel2id(pool, idfresh, repo->idarraydata[i], REL_OR, 1);
- }
- if (!idsupp)
- idsupp = idfresh;
- else
- idsupp = pool_rel2id(pool, idsupp, idfresh, REL_AND, 1);
- supplements = repo_addid_dep(repo, 0, idsupp, 0);
- }
- return supplements;
-}
-
-Offset
-repo_fix_conflicts(Repo *repo, Offset conflicts)
-{
- char buf[1024], *p, *dep;
- Pool *pool = repo->pool;
- Id id;
- int i;
-
- if (!conflicts)
- return conflicts;
- for (i = conflicts; repo->idarraydata[i]; i++)
- {
- id = repo->idarraydata[i];
- if (ISRELDEP(id))
- continue;
- dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
- {
- strcpy(buf, dep + 15);
- if ((p = strchr(buf, ')')) != 0)
- *p = 0;
- id = pool_str2id(pool, buf, 1);
- id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
- repo->idarraydata[i] = id;
- }
- }
- return conflicts;
-}
-
-/***********************************************************************/
-
struct matchdata
{
Pool *pool;
if (md->matcher.match)
{
- if (!repodata_stringify(md->pool, data, key, kv, md->flags))
+ const char *str;
+ if (key->name == SOLVABLE_FILELIST && key->type == REPOKEY_TYPE_DIRSTRARRAY && (md->matcher.flags & SEARCH_FILES) != 0)
+ if (!datamatcher_checkbasename(&md->matcher, kv->str))
+ return 0;
+ if (!(str = repodata_stringify(md->pool, data, key, kv, md->flags)))
return 0;
- if (!datamatcher_match(&md->matcher, kv->str))
+ if (!datamatcher_match(&md->matcher, str))
return 0;
}
md->stop = md->callback(md->callback_data, s, data, key, kv);
{ SOLVABLE_SUGGESTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
{ SOLVABLE_SUPPLEMENTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
{ SOLVABLE_ENHANCES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { RPM_RPMDBID, REPOKEY_TYPE_U32, 0, KEY_STORAGE_SOLVABLE },
+ { RPM_RPMDBID, REPOKEY_TYPE_NUM, 0, KEY_STORAGE_SOLVABLE },
};
static void
if (repo->rpmdbid)
{
kv.num = repo->rpmdbid[p - repo->start];
+ kv.num2 = 0;
repo_matchvalue(md, s, 0, repo_solvablekeys + (RPM_RPMDBID - SOLVABLE_NAME), &kv);
}
if (keyname || md->stop > SEARCH_NEXT_KEY)
return pool_id2str(pool, pool->solvables[entry].vendor);
}
}
+ else if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_str(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname);
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
}
-unsigned int
-repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned int notfound)
+unsigned long long
+repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned long long notfound)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
- unsigned int value;
+ unsigned long long value;
if (entry >= 0)
{
return notfound;
}
}
+ else if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_num(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname, &value) ? value : notfound;
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
Id
repo_lookup_id(Repo *repo, Id entry, Id keyname)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
Id id;
return repo->pool->solvables[entry].vendor;
}
}
+ else if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ {
+ Repodata *data = pool->pos.repo->repodata + pool->pos.repodataid;
+ Id id = repodata_lookup_id(data, entry, keyname);
+ return data->localpool ? repodata_globalize_id(data, id, 1) : id;
+ }
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
int
repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
if (entry >= 0)
return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q);
}
}
+ else if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ {
+ Repodata *data = pool->pos.repo->repodata + pool->pos.repodataid;
+ if (repodata_lookup_idarray(data, entry, keyname, q))
+ {
+ if (data->localpool)
+ {
+ for (i = 0; i < q->count; i++)
+ q->elements[i] = repodata_globalize_id(data, q->elements[i], 1);
+ }
+ return 1;
+ }
+ }
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
repo_lookup_deparray(Repo *repo, Id entry, Id keyname, Queue *q, Id marker)
{
int r = repo_lookup_idarray(repo, entry, keyname, q);
- if (r && marker)
+ if (!r)
+ return 0;
+ if (marker == -1 || marker == 1)
+ marker = solv_depmarker(keyname, marker);
+ if (marker && q->count)
{
int i;
if (marker < 0)
queue_deleten(q, 0, i + 1);
return r;
}
+ queue_empty(q);
}
}
return r;
const unsigned char *
repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
const unsigned char *chk;
+ if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_bin_checksum(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname, typep);
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
int
repo_lookup_void(Repo *repo, Id entry, Id keyname)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
Id type;
+ if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_void(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname);
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
Id
repo_lookup_type(Repo *repo, Id entry, Id keyname)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
Id type;
+ if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_type(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname);
FOR_REPODATAS(repo, i, data)
{
if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
return 0;
}
+const void *
+repo_lookup_binary(Repo *repo, Id entry, Id keyname, int *lenp)
+{
+ Pool *pool = repo->pool;
+ Repodata *data;
+ int i;
+ const void *bin;
+
+ if (entry == SOLVID_POS && pool->pos.repo == repo && pool->pos.repodataid)
+ return repodata_lookup_binary(pool->pos.repo->repodata + pool->pos.repodataid, entry, keyname, lenp);
+ FOR_REPODATAS(repo, i, data)
+ {
+ if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
+ continue;
+ if (!repodata_precheck_keyname(data, keyname))
+ continue;
+ bin = repodata_lookup_binary(data, entry, keyname, lenp);
+ if (bin)
+ return bin;
+ }
+ *lenp = 0;
+ return 0;
+}
+
/***********************************************************************/
Repodata *
return repo->repodata + i;
}
if (!repo->nrepodata)
- {
+ {
repo->nrepodata = 2; /* start with id 1 */
repo->repodata = solv_calloc(repo->nrepodata, sizeof(*data));
- }
- else
- {
+ }
+ else
+ {
repo->nrepodata++;
repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
- }
- data = repo->repodata + repo->nrepodata - 1;
+ }
+ data = repo->repodata + repo->nrepodata - 1;
repodata_initdata(data, repo, (flags & REPO_LOCALPOOL) ? 1 : 0);
return data;
}
}
void
-repo_set_num(Repo *repo, Id p, Id keyname, unsigned int num)
+repo_set_num(Repo *repo, Id p, Id keyname, unsigned long long num)
{
Repodata *data;
if (p >= 0)
{
if (!repo->rpmdbid)
repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
- repo->rpmdbid[p] = num;
+ repo->rpmdbid[p - repo->start] = num;
return;
}
}
repo_add_deparray(Repo *repo, Id p, Id keyname, Id dep, Id marker)
{
Repodata *data;
+ if (marker == -1 || marker == 1)
+ marker = solv_depmarker(keyname, marker);
if (p >= 0)
{
Solvable *s = repo->pool->solvables + p;
repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
{
Repodata *data;
+ if (marker == -1 || marker == 1)
+ marker = solv_depmarker(keyname, marker);
if (marker)
{
/* complex case, splice old and new arrays */
{
if (q2.count)
queue_insert(&q2, 0, -marker);
- queue_insertn(&q2, 0, q->count);
- for (i = 0; i < q->count; i++)
- q2.elements[i] = q->elements[i];
+ queue_insertn(&q2, 0, q->count, q->elements);
}
repo_set_deparray(repo, p, keyname, &q2, 0);
queue_free(&q2);
}
void
+repo_unset(Repo *repo, Id p, Id keyname)
+{
+ Repodata *data;
+ if (p >= 0)
+ {
+ Solvable *s = repo->pool->solvables + p;
+ switch (keyname)
+ {
+ case SOLVABLE_NAME:
+ s->name = 0;
+ return;
+ case SOLVABLE_ARCH:
+ s->arch = 0;
+ return;
+ case SOLVABLE_EVR:
+ s->evr = 0;
+ return;
+ case SOLVABLE_VENDOR:
+ s->vendor = 0;
+ return;
+ case RPM_RPMDBID:
+ if (repo->rpmdbid)
+ repo->rpmdbid[p - repo->start] = 0;
+ return;
+ case SOLVABLE_PROVIDES:
+ s->provides = 0;
+ return;
+ case SOLVABLE_OBSOLETES:
+ s->obsoletes = 0;
+ return;
+ case SOLVABLE_CONFLICTS:
+ s->conflicts = 0;
+ return;
+ case SOLVABLE_REQUIRES:
+ s->requires = 0;
+ return;
+ case SOLVABLE_RECOMMENDS:
+ s->recommends = 0;
+ return;
+ case SOLVABLE_SUGGESTS:
+ s->suggests = 0;
+ return;
+ case SOLVABLE_SUPPLEMENTS:
+ s->supplements = 0;
+ case SOLVABLE_ENHANCES:
+ s->enhances = 0;
+ return;
+ default:
+ break;
+ }
+ }
+ data = repo_last_repodata(repo);
+ repodata_unset(data, p, keyname);
+}
+
+void
repo_internalize(Repo *repo)
{
int i;
repodata_disable_paging(data);
}
-/*
-vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
-*/