Id dirpool_add_dir(Dirpool *dp, Id parent, Id comp, int create) { Id did, d, ds; if (!dp->ndirs) { if (!create) return 0; dp->ndirs = 2; dp->dirs = solv_extend_resize(dp->dirs, dp->ndirs, sizeof(Id), DIR_BLOCK); dp->dirs[0] = 0; dp->dirs[1] = 1; /* "" */ } if (comp <= 0) return 0; if (parent == 0 && comp == 1) return 1; if (!dp->dirtraverse) dirpool_make_dirtraverse(dp); /* check all entries with this parent if we * already have this component */ ds = dp->dirtraverse[parent]; while (ds) { /* ds: first component in this block * ds-1: parent link */ for (d = ds--; d < dp->ndirs; d++) { if (dp->dirs[d] == comp) return d; if (dp->dirs[d] <= 0) /* reached end of this block */ break; } if (ds) ds = dp->dirtraverse[ds]; } if (!create) return 0; /* a new one, find last parent */ for (did = dp->ndirs - 1; did > 0; did--) if (dp->dirs[did] <= 0) break; if (dp->dirs[did] != -parent) { /* make room for parent entry */ dp->dirs = solv_extend(dp->dirs, dp->ndirs, 1, sizeof(Id), DIR_BLOCK); dp->dirtraverse = solv_extend(dp->dirtraverse, dp->ndirs, 1, sizeof(Id), DIR_BLOCK); /* new parent block, link in */ dp->dirs[dp->ndirs] = -parent; dp->dirtraverse[dp->ndirs] = dp->dirtraverse[parent]; dp->dirtraverse[parent] = ++dp->ndirs; } /* make room for new entry */ dp->dirs = solv_extend(dp->dirs, dp->ndirs, 1, sizeof(Id), DIR_BLOCK); dp->dirtraverse = solv_extend(dp->dirtraverse, dp->ndirs, 1, sizeof(Id), DIR_BLOCK); dp->dirs[dp->ndirs] = comp; dp->dirtraverse[dp->ndirs] = 0; return dp->ndirs++; }
Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num) { num++; /* room for trailing ID_NULL */ if (!repo->idarraysize) /* ensure buffer space */ { repo->idarraysize = 1; repo->idarraydata = solv_extend_resize(0, 1 + num, sizeof(Id), IDARRAY_BLOCK); repo->idarraydata[0] = 0; repo->lastoff = 1; return 1; } if (olddeps && olddeps != repo->lastoff) /* if not appending */ { /* can't insert into idarray, this would invalidate all 'larger' offsets * so create new space at end and move existing deps there. * Leaving 'hole' at old position. */ Id *idstart, *idend; int count; for (idstart = idend = repo->idarraydata + olddeps; *idend++; ) /* find end */ ; count = idend - idstart - 1 + num; /* new size */ repo->idarraydata = solv_extend(repo->idarraydata, repo->idarraysize, count, sizeof(Id), IDARRAY_BLOCK); /* move old deps to end */ olddeps = repo->lastoff = repo->idarraysize; memcpy(repo->idarraydata + olddeps, idstart, count - num); repo->idarraysize = olddeps + count - num; return olddeps; } if (olddeps) /* appending */ repo->idarraysize--; /* make room*/ repo->idarraydata = solv_extend(repo->idarraydata, repo->idarraysize, num, sizeof(Id), IDARRAY_BLOCK); /* appending or new */ repo->lastoff = olddeps ? olddeps : repo->idarraysize; return repo->lastoff; }
Offset repo_addid(Repo *repo, Offset olddeps, Id id) { Id *idarray; int idarraysize; int i; idarray = repo->idarraydata; idarraysize = repo->idarraysize; if (!idarray) /* alloc idarray if not done yet */ { idarraysize = 1; idarray = solv_extend_resize(0, 1, sizeof(Id), IDARRAY_BLOCK); idarray[0] = 0; repo->lastoff = 0; } if (!olddeps) /* no deps yet */ { olddeps = idarraysize; idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK); } else if (olddeps == repo->lastoff) /* extend at end */ idarraysize--; else /* can't extend, copy old */ { i = olddeps; olddeps = idarraysize; for (; idarray[i]; i++) { idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK); idarray[idarraysize++] = idarray[i]; } idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK); } idarray[idarraysize++] = id; /* insert Id into array */ idarray = solv_extend(idarray, idarraysize, 1, sizeof(Id), IDARRAY_BLOCK); idarray[idarraysize++] = 0; /* ensure NULL termination */ repo->idarraydata = idarray; repo->idarraysize = idarraysize; repo->lastoff = olddeps; return olddeps; }
void dirpool_make_dirtraverse(Dirpool *dp) { Id parent, i, *dirtraverse; if (!dp->ndirs) return; dp->dirs = solv_extend_resize(dp->dirs, dp->ndirs, sizeof(Id), DIR_BLOCK); dirtraverse = solv_calloc_block(dp->ndirs, sizeof(Id), DIR_BLOCK); for (i = 0; i < dp->ndirs; i++) { if (dp->dirs[i] > 0) continue; parent = -dp->dirs[i]; dirtraverse[i] = dirtraverse[parent]; dirtraverse[parent] = i + 1; } dp->dirtraverse = dirtraverse; }
void pool_shrink_rels(Pool *pool) { pool->rels = solv_extend_resize(pool->rels, pool->nrels, sizeof(Reldep), REL_BLOCK); }