From: Michael Matz Date: Fri, 21 Dec 2007 11:58:38 +0000 (+0000) Subject: Improve the page eviction a bit. X-Git-Tag: BASE-SuSE-Code-12_1-Branch~308^2~738 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b973539bc725a70cce08c2f69a46d7ebbd7cbe27;p=thirdparty%2Flibsolv.git Improve the page eviction a bit. Add possibility to merge attributes between entities, use it to handle =Shr susetags headers. --- diff --git a/src/attr_store.c b/src/attr_store.c index 85978dd8..8bc8dc35 100644 --- a/src/attr_store.c +++ b/src/attr_store.c @@ -30,7 +30,7 @@ #include "fastlz.c" -/*#define DEBUG_PAGING*/ +/* #define DEBUG_PAGING */ #define BLOB_BLOCK 65535 @@ -272,6 +272,42 @@ add_attr_void (Attrstore *s, unsigned int entry, Id name) 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); @@ -423,6 +459,7 @@ load_page_range (Attrstore *s, unsigned int pstart, unsigned int pend) /* 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]; @@ -431,10 +468,16 @@ load_page_range (Attrstore *s, unsigned int pstart, unsigned int pend) 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 diff --git a/src/attr_store.h b/src/attr_store.h index 657b5b6e..0173e6fb 100644 --- a/src/attr_store.h +++ b/src/attr_store.h @@ -39,6 +39,7 @@ void add_attr_string (Attrstore *s, unsigned int entry, Id name, const char *val 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); diff --git a/src/attr_store_p.h b/src/attr_store_p.h index 6258aed1..49c1001f 100644 --- a/src/attr_store_p.h +++ b/src/attr_store_p.h @@ -53,6 +53,7 @@ struct _Attrstore otherwise it contains the pagenumber plus one (of the mapped page). */ unsigned int *mapped; unsigned int nmapped, ncanmap; + unsigned int rr_counter; Stringpool ss; diff --git a/tools/repo_susetags.c b/tools/repo_susetags.c index 96657bd1..2e3d1e58 100644 --- a/tools/repo_susetags.c +++ b/tools/repo_susetags.c @@ -45,6 +45,8 @@ struct parsedata { char **sources; int nsources; int last_found_source; + char **share_with; + int nshare; }; static Id @@ -598,9 +600,18 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) 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; @@ -615,7 +626,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) if (pd.sources) { - int i; + int i, last_found; for (i = 0; i < pd.nsources; i++) if (pd.sources[i]) { @@ -623,6 +634,41 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) 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);