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);
}
}
+/* 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;
+}
+
/* repository sidedata is solvable data allocated on demand.
* It is used for data that is normally not present
#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.
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)
{
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);
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 long long
repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned long long notfound)
{
+ Pool *pool = repo->pool;
Repodata *data;
int i;
unsigned long long value;
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 && q->count)
+ if (!r)
+ return 0;
+ if (marker == -1 || marker == 1)
+ marker = solv_depmarker(keyname, marker);
+ if (marker && q->count)
{
int i;
if (marker < 0)
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;
}
{
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);
return;
case RPM_RPMDBID:
if (repo->rpmdbid)
- repo->rpmdbid[p] = 0;
+ repo->rpmdbid[p - repo->start] = 0;
return;
case SOLVABLE_PROVIDES:
s->provides = 0;
repodata_disable_paging(data);
}
-/*
-vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
-*/