Exemple #1
0
void map_insert(Map* map, char key, void* value) {
    int start = hash(key) % map->length;
    int end = start ? start : map->length;
    int i;
    for (i = start; i != end - 1; i = (i + 1) % map->length) {
        if (key == map->items[i].key || !map->items[i].value) {
            map->items[i].key = key;
            map->items[i].value = value;
            return;
        }
    }
    map_grow(map);
    map_insert(map, key, value);
}
Exemple #2
0
void
sack_recompute_considered(HySack sack)
{
    Pool *pool = sack_pool(sack);
    if (sack->considered_uptodate)
	return;
    if (!pool->considered) {
	if (!sack->repo_excludes && !sack->pkg_excludes)
	    return;
	pool->considered = solv_calloc(1, sizeof(Map));
	map_init(pool->considered, pool->nsolvables);
    } else
	map_grow(pool->considered, pool->nsolvables);

    // considered = (all - repo_excludes - pkg_excludes) and pkg_includes
    map_setall(pool->considered);
    if (sack->repo_excludes)
	map_subtract(pool->considered, sack->repo_excludes);
    if (sack->pkg_excludes)
	map_subtract(pool->considered, sack->pkg_excludes);
    if (sack->pkg_includes)
	map_and(pool->considered, sack->pkg_includes);
    sack->considered_uptodate = 1;
}
Exemple #3
0
static void
repo_addfileprovides_search(Repo *repo, struct addfileprovides_cbdata *cbd, struct searchfiles *sf)
{
  Repodata *data;
  int rdid, p, i;
  int provstart, provend;
  Map todo;
  Map providedids;

  if (repo->end <= repo->start || !repo->nsolvables || !sf->nfiles)
    return;

  /* update search data if changed */
  if (cbd->nfiles != sf->nfiles || cbd->ids != sf->ids)
    {
      free_dirs_names_array(cbd);
      cbd->nfiles = sf->nfiles;
      cbd->ids = sf->ids;
      cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id));
    }

  /* create todo map and range */
  map_init(&todo, repo->end - repo->start);
  for (p = repo->start; p < repo->end; p++)
    if (repo->pool->solvables[p].repo == repo)
      MAPSET(&todo, p - repo->start);
  cbd->todo = &todo;
  cbd->todo_start = repo->start;
  cbd->todo_end = repo->end;
  prune_todo_range(repo, cbd);

  provstart = provend = 0;
  map_init(&providedids, 0);
  data = repo_lookup_repodata(repo, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES);
  if (data)
    {
      Queue fileprovidesq;
      queue_init(&fileprovidesq);
      if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
	{
	  map_grow(&providedids, repo->pool->ss.nstrings);
	  cbd->providedids = &providedids;
	  provstart = data->start;
	  provend = data->end;
	  for (i = 0; i < fileprovidesq.count; i++)
	    MAPSET(&providedids, fileprovidesq.elements[i]);
	  for (i = 0; i < cbd->nfiles; i++)
	    if (!MAPTST(&providedids, cbd->ids[i]))
	      break;
	  if (i == cbd->nfiles)
	    {
	      /* all included, clear entries from todo list */
	      if (provstart <= cbd->todo_start && provend >= cbd->todo_end)
		cbd->todo_end = cbd->todo_start;	/* clear complete range */
	      else
		{
		  for (p = provstart; p < provend; p++)
		    MAPCLR(&todo, p - repo->start);
		  prune_todo_range(repo, cbd);
		}
	    }
	}
      queue_free(&fileprovidesq);
    }

  if (cbd->todo_start >= cbd->todo_end)
    {
      map_free(&todo);
      cbd->todo = 0;
      map_free(&providedids);
      cbd->providedids = 0;
      return;
    }

  /* this is similar to repo_lookup_filelist_repodata in repo.c */

  for (rdid = 1, data = repo->repodata + rdid; rdid < repo->nrepodata; rdid++, data++)
    if (data->filelisttype == REPODATA_FILELIST_FILTERED)
      break;
  for (; rdid < repo->nrepodata; rdid++, data++)
    if (data->filelisttype == REPODATA_FILELIST_EXTENSION)
      break;

  if (rdid < repo->nrepodata)
    {
      /* have at least one repodata with REPODATA_FILELIST_FILTERED followed by REPODATA_FILELIST_EXTENSION */
      Map postpone;
      map_init(&postpone, 0);
      for (rdid = repo->nrepodata - 1, data = repo->repodata + rdid; rdid > 0; rdid--, data--)
	{
	  if (data->filelisttype != REPODATA_FILELIST_FILTERED)
	    continue;
	  if (!repodata_intersects_todo(data, cbd))
	    continue;
	  if (data->state != REPODATA_AVAILABLE)
	    {
	      if (data->state != REPODATA_STUB)
		continue;
	      repodata_load(data);
	      if (data->state != REPODATA_AVAILABLE || data->filelisttype != REPODATA_FILELIST_FILTERED)
		continue;
	    }
	  repo_addfileprovides_search_filtered(repo, cbd, rdid, &postpone);
	}
      if (postpone.size)
	{
	  /* add postponed entries back to todo */
	  map_or(&todo, &postpone);
	  cbd->todo_start = repo->start;
	  cbd->todo_end = repo->end;
	  prune_todo_range(repo, cbd);
	}
      map_free(&postpone);
    }

  /* search remaining entries in the standard way */
  if (cbd->todo_start < cbd->todo_end)
    {
      for (rdid = repo->nrepodata - 1, data = repo->repodata + rdid; rdid > 0; rdid--, data--)
	{
	  if (data->start >= cbd->todo_end || data->end <= cbd->todo_start)
	    continue;
	  if (!repodata_has_keyname(data, SOLVABLE_FILELIST))
	    continue;
	  if (!repodata_intersects_todo(data, cbd))
	    continue;
	  repodata_addfileprovides_search(data, cbd);
	  if (cbd->todo_start >= cbd->todo_end)
	    break;
	}
    }

  map_free(&todo);
  cbd->todo = 0;
  map_free(&providedids);
  cbd->providedids = 0;
}
Exemple #4
0
static void
repo_addfileprovides_search_filtered(Repo *repo, struct addfileprovides_cbdata *cbd, int filteredid, Map *postpone)
{
  Repodata *data = repo->repodata + filteredid;
  Map *providedids = cbd->providedids;
  int rdid;
  int start, end, p, i;
  Map old_todo;
  int old_todo_start, old_todo_end;

  start = cbd->todo_start > data->start ? cbd->todo_start : data->start;
  end = cbd->todo_end > data->end ? data->end : cbd->todo_end;

  if (providedids)
    {
      /* check if all solvables are in the provide range */
      if (start < cbd->provstart || end > cbd->provend)
	{
	  /* unclear, check each solvable */
	  for (p = start; p < end; p++)
	    {
	      if (p >= cbd->provstart && p < cbd->provend)
		continue;
	      if (data->incoreoffset[p - data->start] && MAPTST(cbd->todo, p - repo->start))
		{
		  providedids = 0;	/* nope, cannot prune with providedids */
		  break;
		}
	    }
	}
    }

  /* check if the filtered files are enough */
  for (i = 0; i < cbd->nfiles; i++)
    {
      if (providedids && MAPTST(providedids, cbd->ids[i]))	/* this one is already provided */
	continue;
      if (!repodata_filelistfilter_matches(data, pool_id2str(repo->pool, cbd->ids[i])))
        break;
    }
  if (i < cbd->nfiles)
    {
      /* nope, need to search the extensions as well. postpone. */
      for (p = start; p < end; p++)
	{
	  if (data->incoreoffset[p - data->start] && MAPTST(cbd->todo, p - repo->start))
	    {
	      if (!postpone->size)
		map_grow(postpone, repo->nsolvables);
	      MAPSET(postpone, p - repo->start);
	      MAPCLR(cbd->todo, p - repo->start);
	    }
	}
      prune_todo_range(repo, cbd);
      return;
    }

  /* now check if there is no data marked withour EXTENSION */
  /* limit todo to the solvables in this repodata */
  old_todo_start = cbd->todo_start;
  old_todo_end = cbd->todo_end;
  old_todo = *cbd->todo;
  map_init(cbd->todo, repo->nsolvables);
  for (p = start; p < end; p++)
    if (data->incoreoffset[p - data->start] && MAPTST(&old_todo, p - repo->start))
      {
        MAPCLR(&old_todo, p - repo->start);
        MAPSET(cbd->todo, p - repo->start);
      }
  prune_todo_range(repo, cbd);

  /* do the check */
  for (rdid = repo->nrepodata - 1, data = repo->repodata + rdid; rdid > filteredid ; rdid--, data--)
    {
      if (data->filelisttype == REPODATA_FILELIST_EXTENSION)
	continue;
      if (data->start >= cbd->todo_end || data->end <= cbd->todo_start)
	continue;
      if (!repodata_has_keyname(data, SOLVABLE_FILELIST))
	continue;
      if (!repodata_intersects_todo(data, cbd))
	continue;
      /* oh no, this filelist data is not tagged with REPODATA_FILELIST_EXTENSION! */
      /* postpone entries that have filelist data */
      start = cbd->todo_start > data->start ? cbd->todo_start : data->start;
      end = cbd->todo_end > data->end ? data->end : cbd->todo_end;
      for (p = start; p < end; p++)
	if (MAPTST(cbd->todo, p - repo->start))
	  if (repodata_lookup_type(data, p, SOLVABLE_FILELIST))
	    {
	      if (!postpone->size)
		map_grow(postpone, repo->nsolvables);
	      MAPSET(postpone, p - repo->start);
	      MAPCLR(cbd->todo, p - repo->start);
	    }
      prune_todo_range(repo, cbd);
      if (cbd->todo_start >= cbd->todo_end)
	break;
    }

  /* do the search over the filtered file list with the remaining entries*/
  if (cbd->todo_start < cbd->todo_end)
    repodata_addfileprovides_search(repo->repodata + filteredid, cbd);

  /* restore todo map */
  map_free(cbd->todo);
  *cbd->todo = old_todo;
  cbd->todo_start = old_todo_start;
  cbd->todo_end = old_todo_end;
  prune_todo_range(repo, cbd);
}