#include "fastlz.c"
-/*#define DEBUG_PAGING*/
+/* #define DEBUG_PAGING */
#define BLOB_BLOCK 65535
add_attr (s, entry, nv);
}
+void
+merge_attrs (Attrstore *s, unsigned dest, unsigned src)
+{
+ LongNV *nv;
+ ensure_entry (s, dest);
+ nv = s->attrs[src];
+ if (nv)
+ {
+ for (; nv->key; nv++)
+ if (!find_attr (s, dest, s->keys[nv->key].name))
+ switch (s->keys[nv->key].type)
+ {
+ case TYPE_ATTR_INTLIST:
+ {
+ unsigned len = 0;
+ while (nv->v.intlist[len])
+ add_attr_intlist_int (s, dest, s->keys[nv->key].name, nv->v.intlist[len++]);
+ }
+ break;
+ case TYPE_ATTR_LOCALIDS:
+ {
+ unsigned len = 0;
+ while (nv->v.localids[len])
+ add_attr_localids_id (s, dest, s->keys[nv->key].name, nv->v.localids[len++]);
+ }
+ break;
+ case TYPE_ATTR_STRING:
+ add_attr_string (s, dest, s->keys[nv->key].name, nv->v.str);
+ break;
+ default:
+ add_attr (s, dest, *nv);
+ break;
+ }
+ }
+}
+
#define pool_debug(a,b,...) fprintf (stderr, __VA_ARGS__)
static Id read_id (FILE *fp, Id max);
/* And search for cheapest space. */
unsigned int best_cost = -1;
unsigned int best = 0;
+ unsigned int same_cost = 0;
for (i = 0; i + pend - pstart < s->ncanmap; i++)
{
unsigned int c = cost[i];
c += cost[i+j];
if (c < best_cost)
best_cost = c, best = i;
+ else if (c == best_cost)
+ same_cost++;
/* A null cost won't become better. */
if (c == 0)
break;
}
+ /* If all places have the same cost we would thrash on slot 0. Avoid
+ this by doing a round-robin strategy in this case. */
+ if (same_cost == s->ncanmap - pend + pstart - 1)
+ best = s->rr_counter++ % (s->ncanmap - pend + pstart);
/* So we want to map our pages from [best] to [best+pend-pstart].
Use a very simple strategy, which doesn't make the best use of
void add_attr_intlist_int (Attrstore *s, unsigned int entry, Id name, int val);
void add_attr_localids_id (Attrstore *s, unsigned int entry, Id name, LocalId id);
void add_attr_void (Attrstore *s, unsigned int entry, Id name);
+void merge_attrs (Attrstore *s, unsigned dest, unsigned src);
const void * attr_retrieve_blob (Attrstore *s, unsigned int ofs, unsigned int len);
otherwise it contains the pagenumber plus one (of the mapped page). */
unsigned int *mapped;
unsigned int nmapped, ncanmap;
+ unsigned int rr_counter;
Stringpool ss;
char **sources;
int nsources;
int last_found_source;
+ char **share_with;
+ int nshare;
};
static Id
add_attr_blob (attr, last_found_pack, id_messagedel, line + 6, strlen (line + 6) + 1);
continue;
case CTAG('=', 'S', 'h', 'r'):
- /* XXX Not yet handled. Two possibilities: either include all
- referenced data verbatim here, or write out the sharing
- information. */
+ if (last_found_pack >= pd.nshare)
+ {
+ if (pd.share_with)
+ {
+ pd.share_with = realloc (pd.share_with, (last_found_pack + 256) * sizeof (*pd.share_with));
+ memset (pd.share_with + pd.nshare, 0, (last_found_pack + 256 - pd.nshare) * sizeof (*pd.share_with));
+ }
+ else
+ pd.share_with = calloc (last_found_pack + 256, sizeof (*pd.share_with));
+ pd.nshare = last_found_pack + 256;
+ }
+ pd.share_with[last_found_pack] = strdup (line + 6);
continue;
case CTAG('=', 'V', 'e', 'r'):
last_found_pack = 0;
if (pd.sources)
{
- int i;
+ int i, last_found;
for (i = 0; i < pd.nsources; i++)
if (pd.sources[i])
{
free (pd.sources[i]);
}
free (pd.sources);
+
+ last_found = 0;
+ for (i = 0; i < pd.nshare; i++)
+ if (pd.share_with[i])
+ {
+ if (split(pd.share_with[i], sp, 5) != 4)
+ {
+ fprintf(stderr, "Bad =Shr line: %s\n", pd.share_with[i]);
+ exit(1);
+ }
+
+ Id name = str2id(pool, sp[0], 1);
+ Id evr = makeevr(pool, join(&pd, sp[1], "-", sp[2]));
+ Id arch = str2id(pool, sp[3], 1);
+ unsigned n, nn;
+ Solvable *found = 0;
+ for (n = repo->start, nn = repo->start + last_found;
+ n < repo->end; n++, nn++)
+ {
+ if (nn >= repo->end)
+ nn = repo->start;
+ found = pool->solvables + nn;
+ if (found->repo == repo
+ && found->name == name
+ && found->evr == evr
+ && found->arch == arch)
+ {
+ last_found = nn - repo->start;
+ break;
+ }
+ }
+ if (n != repo->end)
+ merge_attrs (attr, i, last_found);
+ }
+ free (pd.share_with);
}
if (pd.tmp)
free(pd.tmp);