#define REPODATA_BLOCK 255
+
+void
+repodata_init(Repodata *data, Repo *repo, int localpool)
+{
+ memset(data, 0, sizeof (*data));
+ data->repo = repo;
+ data->localpool = localpool;
+ if (localpool)
+ stringpool_init_empty(&data->spool);
+ data->keys = sat_calloc(1, sizeof(Repokey));
+ data->nkeys = 1;
+ data->schemata = sat_calloc(1, sizeof(Id));
+ data->schemadata = sat_calloc(1, sizeof(Id));
+ data->nschemata = 1;
+ data->schemadatalen = 1;
+ data->start = repo->start;
+ data->end = repo->end;
+ data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
+ data->pagefd = -1;
+}
+
void
repodata_free(Repodata *data)
{
sat_free(data->attrdata);
sat_free(data->attriddata);
+ sat_free(data->location);
+
if (data->pagefd != -1)
close(data->pagefd);
}
static unsigned char *
-forward_to_key(Repodata *data, Id key, Id schemaid, unsigned char *dp)
+forward_to_key(Repodata *data, Id keyid, Id schemaid, unsigned char *dp)
{
Id k, *keyp;
keyp = data->schemadata + data->schemata[schemaid];
while ((k = *keyp++) != 0)
{
- if (k == key)
+ if (k == keyid)
return dp;
if (data->keys[k].storage == KEY_STORAGE_VERTICAL_OFFSET)
{
if (i > pend)
return data->blob_store + data->pages[pstart].mapped_at;
+ if (data->pagefd == -1)
+ return 0;
+
/* Ensure that we can map the numbers of pages we need at all. */
if (pend - pstart + 1 > data->ncanmap)
{
make_vertical_available(Repodata *data, Repokey *key, Id off, Id len)
{
unsigned char *dp;
- if (key->type == REPOKEY_TYPE_VOID)
+ if (!len)
return 0;
if (off >= data->lastverticaloffset)
{
return 0;
return data->vincore + off;
}
- if (data->pagefd == -1)
- return 0;
if (off + len > key->size)
return 0;
/* we now have the offset, go into vertical */
off += data->verticaloffset[key - data->keys];
+ /* fprintf(stderr, "key %d page %d\n", key->name, off / BLOB_PAGESIZE); */
dp = load_page_range(data, off / BLOB_PAGESIZE, (off + len - 1) / BLOB_PAGESIZE);
if (dp)
dp += off % BLOB_PAGESIZE;
}
static inline int
-maybe_load_repodata(Repodata *data)
+maybe_load_repodata(Repodata *data, Id *keyid)
{
if (data->state == REPODATA_STUB)
{
if (data->loadcallback)
- data->loadcallback(data);
+ {
+ if (keyid)
+ {
+ /* key order may change when loading */
+ int i;
+ Id name = data->keys[*keyid].name;
+ Id type = data->keys[*keyid].type;
+ data->loadcallback(data);
+ if (data->state == REPODATA_AVAILABLE)
+ {
+ for (i = 1; i < data->nkeys; i++)
+ if (data->keys[i].name == name && data->keys[i].type == type)
+ break;
+ if (i < data->nkeys)
+ *keyid = i;
+ else
+ return 0;
+ }
+ }
+ else
+ data->loadcallback(data);
+ }
else
data->state = REPODATA_ERROR;
}
Id id, *keyp;
unsigned char *dp;
- if (!maybe_load_repodata (data))
+ if (!maybe_load_repodata(data, &keyid))
return 0;
dp = data->incoredata + data->incoreoffset[entry];
}
int
-repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
+repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value)
{
Id schema;
Repokey *key;
*value = 0;
- if (!maybe_load_repodata (data))
+ if (!maybe_load_repodata(data, &keyid))
return 0;
dp = data->incoredata + data->incoreoffset[entry];
return 0;
}
+int
+repodata_lookup_void(Repodata *data, Id entry, Id keyid)
+{
+ Id schema;
+ Id *keyp;
+ unsigned char *dp;
+ if (!maybe_load_repodata(data, &keyid))
+ return 0;
+ dp = data->incoredata + data->incoreoffset[entry];
+ dp = data_read_id(dp, &schema);
+ for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
+ if (!*keyp)
+ return 0;
+ return 1;
+}
+
void
repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
{
int stop;
KeyValue kv;
- if (!maybe_load_repodata (data))
+ if (!maybe_load_repodata(data, 0))
return;
dp = data->incoredata + data->incoreoffset[entry];
return 1;
}
-void
-repodata_init(Repodata *data, Repo *repo, int localpool)
-{
- memset(data, 0, sizeof (*data));
- data->repo = repo;
- data->localpool = localpool;
- if (localpool)
- stringpool_init_empty(&data->spool);
- data->keys = sat_calloc(1, sizeof(Repokey));
- data->nkeys = 1;
- data->schemata = sat_calloc(1, sizeof(Id));
- data->schemadata = sat_calloc(1, sizeof(Id));
- data->nschemata = 1;
- data->schemadatalen = 1;
- data->start = repo->start;
- data->end = repo->end;
- data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
- data->pagefd = -1;
-}
-
/* extend repodata so that it includes solvables p */
void
repodata_extend(Repodata *data, Id p)
return;
if (!data->incoreoffset)
{
- data->incoreoffset = sat_extend_resize(data->incoreoffset, num, sizeof(Id), REPODATA_BLOCK);
- memset(data->incoreoffset, 0, num * sizeof(Id));
+ data->incoreoffset = sat_calloc_block(num, sizeof(Id), REPODATA_BLOCK);
data->start = start;
data->end = start + num;
return;
repodata_extend(data, start + num - 1);
}
+/**********************************************************************/
+
#define REPODATA_ATTRS_BLOCK 63
#define REPODATA_ATTRDATA_BLOCK 1023
#define REPODATA_ATTRIDDATA_BLOCK 63
int i;
if (!data->attrs)
{
- data->attrs = sat_extend_resize(0, data->end - data->start, sizeof(Id *), REPODATA_BLOCK);
- memset(data->attrs, 0, (data->end - data->start) * sizeof(Id *));
+ data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *),
+ REPODATA_BLOCK);
}
i = 0;
if (data->attrs[entry])
}
void
-repodata_merge_attrs (Repodata *data, Id dest, Id src)
+repodata_merge_attrs(Repodata *data, Id dest, Id src)
{
Id *keyp;
- for (keyp = data->attrs[src]; *keyp; keyp += 2)
+ if (dest == src || !(keyp = data->attrs[src]))
+ return;
+ for (; *keyp; keyp += 2)
repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
}
parent = 0;
while (*dir == '/' && dir[1] == '/')
dir++;
+ if (*dir == '/' && !dir[1])
+ return 1;
while (*dir)
{
dire = strchrnul(dir, '/');
return parent;
}
+const char *
+repodata_dir2str(Repodata *data, Id did, const char *suf)
+{
+ Pool *pool = data->repo->pool;
+ int l = 0;
+ Id parent, comp;
+ const char *comps;
+ char *p;
+
+ if (!did)
+ return suf ? suf : "";
+ parent = did;
+ while (parent)
+ {
+ comp = dirpool_compid(&data->dirpool, parent);
+ comps = stringpool_id2str(data->localpool ? &data->spool : &pool->ss, comp);
+ l += strlen(comps);
+ parent = dirpool_parent(&data->dirpool, parent);
+ if (parent)
+ l++;
+ }
+ if (suf)
+ l += strlen(suf) + 1;
+ p = pool_alloctmpspace(pool, l + 1) + l;
+ *p = 0;
+ if (suf)
+ {
+ p -= strlen(suf);
+ strcpy(p, suf);
+ *--p = '/';
+ }
+ parent = did;
+ while (parent)
+ {
+ comp = dirpool_compid(&data->dirpool, parent);
+ comps = stringpool_id2str(data->localpool ? &data->spool : &pool->ss, comp);
+ l = strlen(comps);
+ p -= l;
+ strncpy(p, comps, l);
+ parent = dirpool_parent(&data->dirpool, parent);
+ if (parent)
+ *--p = '/';
+ }
+ return p;
+}
+
unsigned int
repodata_compress_page(unsigned char *page, unsigned int len, unsigned char *cpage, unsigned int max)
{
}
}
+void
+repodata_disable_paging(Repodata *data)
+{
+ if (maybe_load_repodata(data, 0)
+ && data->num_pages)
+ load_page_range (data, 0, data->num_pages - 1);
+}
/*
vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
*/