unsigned int numotherarchs = 0;
Id *otherarchs = 0;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
-
memset(&pd, 0, sizeof(pd));
line = sat_malloc(1024);
aline = 1024;
- if (repo->nrepodata)
- /* use last repodata */
- data = repo->repodata + repo->nrepodata - 1;
- else
- data = repo_add_repodata(repo, 0);
-
pd.repo = repo;
linep = line;
s = 0;
+ data = repo_add_repodata(repo, flags);
+
for (;;)
{
char *key, *value;
int bufl, l, ll;
Solvable *s;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
buf = sat_malloc(4096);
bufl = 4096;
l = 0;
Solvable *s;
struct stat stb;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
for (i = 0; i < ndebs; i++)
{
if ((fp = fopen(debs[i], "r")) == 0)
struct stateswitch *sw;
Repodata *data;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
unsigned int now;
now = sat_timems(0);
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
/* prepare parsedata */
memset(&pd, 0, sizeof(pd));
DIR *dir;
int i;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
pd.repo = repo;
int i, l;
struct stateswitch *sw;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
pd.timestamp = 0;
if (!rootdir)
rootdir = "";
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
if (ref && !(ref->nsolvables && ref->rpmdbid))
ref = 0;
Id chksumtype = 0;
void *chksumh = 0;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
if ((flags & RPM_ADD_WITH_SHA256SUM) != 0)
chksumtype = REPOKEY_TYPE_SHA256;
Repodata *data;
Solvable *s;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&state, 0, sizeof(state));
if (!(state.dbenv = opendbenv(rootdir)))
int i, bufl, l, ll;
FILE *fp;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
buf = 0;
bufl = 0;
for (i = 0; i < nkeys; i++)
pubkey2solvable(s, data, buf);
}
sat_free(buf);
+ if (!(flags & REPO_NO_INTERNALIZE))
+ repodata_internalize(data);
}
unsigned int now;
now = sat_timems(0);
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
if ((flags & SUSETAGS_EXTEND) && repo->nrepodata)
indesc = 1;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
line = malloc(1024);
struct stateswitch *sw;
Repodata *data;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
FILE *fp;
Repodata *data;
- if (!(flags & REPO_REUSE_REPODATA))
- data = repo_add_repodata(repo, 0);
- else
- data = repo_last_repodata(repo);
-
+ data = repo_add_repodata(repo, flags);
memset(&pd, 0, sizeof(pd));
pd.repo = repo;
pd.pool = repo->pool;
pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids);
}
+void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
+{
+ Solvable *s;
+ Repodata *data;
+ int i;
+ if (start + count == repo->end)
+ repo->end -= count;
+ repo->nsolvables -= count;
+ for (s = repo->pool->solvables + start, i = count; i--; s++)
+ s->repo = 0;
+ pool_free_solvable_block(repo->pool, start, count, reuseids);
+ for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+ if (data->end > repo->end)
+ repodata_shrink(data, repo->end);
+}
+
/* repository sidedata is solvable data allocated on demand.
* It is used for data that is normally not present
/***********************************************************************/
Repodata *
-repo_add_repodata(Repo *repo, int localpool)
+repo_add_repodata(Repo *repo, int flags)
{
- Repodata *data;
-
- repo->nrepodata++;
- repo->repodata = sat_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
- data = repo->repodata + repo->nrepodata - 1;
- repodata_initdata(data, repo, localpool);
- return data;
+ if ((flags & REPO_REUSE_REPODATA) != 0)
+ {
+ int i;
+ for (i = repo->nrepodata - 1; i >= 0; i--)
+ if (repo->repodata[i].state != REPODATA_STUB)
+ return repo->repodata + i;
+ }
+ return repodata_create(repo, (flags & REPO_LOCALPOOL) ? 1 : 0);
}
Repodata *
extern Repo *repo_create(Pool *pool, const char *name);
extern void repo_free(Repo *repo, int reuseids);
extern void repo_freeallrepos(Pool *pool, int reuseids);
+extern void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids);
extern void *repo_sidedata_create(Repo *repo, size_t size);
extern void *repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count);
return p;
}
-static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
-{
- extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
- Solvable *s;
- int i;
- if (start + count == repo->end)
- repo->end -= count;
- repo->nsolvables -= count;
- for (s = repo->pool->solvables + start, i = count; i--; s++)
- s->repo = 0;
- pool_free_solvable_block(repo->pool, start, count, reuseids);
-}
#define FOR_REPO_SOLVABLES(r, p, s) \
for (p = (r)->start, s = (r)->pool->solvables + p; p < (r)->end; p++, s = (r)->pool->solvables + p) \
/* standard flags used in the repo_add functions */
#define REPO_REUSE_REPODATA (1 << 0)
#define REPO_NO_INTERNALIZE (1 << 1)
+#define REPO_LOCALPOOL (1 << 2)
-Repodata *repo_add_repodata(Repo *repo, int localpool);
+Repodata *repo_add_repodata(Repo *repo, int flags);
Repodata *repo_last_repodata(Repo *repo);
void repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
#include "pool.h"
#include "poolid_private.h"
#include "util.h"
+#include "hash.h"
+#include "chksum.h"
#include "repopack.h"
#include "repopage.h"
sat_free(data->attriddata);
}
+Repodata *
+repodata_create(Repo *repo, int localpool)
+{
+ Repodata *data;
+
+ repo->nrepodata++;
+ repo->repodata = sat_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
+ data = repo->repodata + repo->nrepodata - 1;
+ repodata_initdata(data, repo, localpool);
+ return data;
+}
+
void
repodata_free(Repodata *data)
{
}
}
+void
+repodata_shrink(Repodata *data, int end)
+{
+ int i;
+
+ if (data->end <= end)
+ return;
+ if (data->start >= end)
+ {
+ if (data->attrs)
+ {
+ for (i = 0; i < data->end - data->start; i++)
+ sat_free(data->attrs[i]);
+ data->attrs = sat_free(data->attrs);
+ }
+ data->incoreoffset = sat_free(data->incoreoffset);
+ data->start = data->end = 0;
+ return;
+ }
+ if (data->attrs)
+ {
+ for (i = end; i < data->end; i++)
+ sat_free(data->attrs[i - data->start]);
+ data->attrs = sat_extend_resize(data->attrs, end - data->start, sizeof(Id *), REPODATA_BLOCK);
+ }
+ if (data->incoreoffset)
+ data->incoreoffset = sat_extend_resize(data->incoreoffset, end - data->start, sizeof(Id), REPODATA_BLOCK);
+ data->end = end;
+}
+
/* extend repodata so that it includes solvables from start to start + num - 1 */
void
repodata_extend_block(Repodata *data, Id start, Id num)
repopagestore_disable_paging(&data->store);
}
+static inline Hashval
+repodata_join_hash(Solvable *s, Id joinkey)
+{
+ if (joinkey == SOLVABLE_NAME)
+ return s->name;
+ if (joinkey == SOLVABLE_CHECKSUM)
+ {
+ Id type;
+ const unsigned char *chk = solvable_lookup_bin_checksum(s, joinkey, &type);
+ if (chk)
+ return 1 << 31 | chk[0] << 24 | chk[1] << 16 | chk[2] << 7 | chk[3];
+ }
+ return 0;
+}
+
+static inline int
+repodata_join_match(Solvable *s1, Solvable *s2, Id joinkey)
+{
+ if (joinkey == SOLVABLE_NAME)
+ return s1->name == s2->name && s1->evr == s2->evr && s1->arch == s2->arch ? 1 : 0;
+ if (joinkey == SOLVABLE_CHECKSUM)
+ {
+ const unsigned char *chk1, *chk2;
+ Id type1, type2;
+ chk1 = solvable_lookup_bin_checksum(s1, joinkey, &type1);
+ if (!chk1)
+ return 0;
+ chk2 = solvable_lookup_bin_checksum(s2, joinkey, &type2);
+ if (!chk2 || type1 != type2)
+ return 0;
+ return memcmp(chk1, chk2, sat_chksum_len(type1)) ? 0 : 1;
+ }
+ return 0;
+}
+
+void
+repodata_join(Repodata *data, Id joinkey)
+{
+ Repo *repo = data->repo;
+ Pool *pool = repo->pool;
+ Hashmask hm = mkmask(repo->nsolvables);
+ Hashtable ht = sat_calloc(hm + 1, sizeof(*ht));
+ Hashval h, hh;
+ int i, datastart, dataend;
+ Solvable *s;
+
+ datastart = data->start;
+ dataend = data->end;
+ if (datastart == dataend || repo->start == repo->end)
+ return;
+ FOR_REPO_SOLVABLES(repo, i, s)
+ {
+ if (i >= datastart && i < dataend)
+ continue;
+ h = repodata_join_hash(s, joinkey);
+ if (!h)
+ continue;
+ h &= hm;
+ hh = HASHCHAIN_START;
+ while (ht[h])
+ h = HASHCHAIN_NEXT(h, hh, hm);
+ ht[h] = i;
+ }
+ for (i = datastart; i < dataend; i++)
+ {
+ Solvable *s = pool->solvables + i;
+ if (s->repo != data->repo)
+ continue;
+ if (!data->attrs[i - data->start])
+ continue;
+ h = repodata_join_hash(s, joinkey);
+ if (!h)
+ continue;
+ h &= hm;
+ hh = HASHCHAIN_START;
+ while (ht[h])
+ {
+ Solvable *s2 = pool->solvables + ht[h];
+ if (repodata_join_match(s, s2, joinkey))
+ {
+ /* a match! move data over */
+ repodata_extend(data, ht[h]);
+ repodata_merge_attrs(data, ht[h], i);
+ }
+ h = HASHCHAIN_NEXT(h, hh, hm);
+ }
+ }
+ sat_free(ht);
+ /* all done! now free solvables */
+ repo_free_solvable_block(repo, datastart, dataend - datastart, 1);
+}
+
/*
vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
*/
*/
void repodata_initdata(Repodata *data, struct _Repo *repo, int localpool);
void repodata_freedata(Repodata *data);
+
+Repodata *repodata_create(struct _Repo *repo, int localpool);
void repodata_free(Repodata *data);
*/
void repodata_extend(Repodata *data, Id p);
void repodata_extend_block(Repodata *data, Id p, int num);
+void repodata_shrink(Repodata *data, int end);
/* internalize freshly set data, so that it is found by the search
* functions and written out */
*/
void repodata_merge_attrs(Repodata *data, Id dest, Id src);
+void repodata_join(Repodata *data, Id joinkey);
+
/*
* load all paged data, used to speed up copying in repo_rpmdb
*/