コード例 #1
0
int
repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
{
  Repodata *data;
  int i;
  if (entry >= 0)
    {
      switch (keyname)
        {
	case SOLVABLE_PROVIDES:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].provides, q);
	case SOLVABLE_OBSOLETES:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].obsoletes, q);
	case SOLVABLE_CONFLICTS:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].conflicts, q);
	case SOLVABLE_REQUIRES:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].requires, q);
	case SOLVABLE_RECOMMENDS:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].recommends, q);
	case SOLVABLE_SUGGESTS:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].suggests, q);
	case SOLVABLE_SUPPLEMENTS:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].supplements, q);
	case SOLVABLE_ENHANCES:
	  return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q);
        }
    }
  FOR_REPODATAS(repo, i, data)
    {
      if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
	continue;
      if (!repodata_precheck_keyname(data, keyname))
	continue;
      if (repodata_lookup_idarray(data, entry, keyname, q))
	{
	  if (data->localpool)
	    {
	      for (i = 0; i < q->count; i++)
		q->elements[i] = repodata_globalize_id(data, q->elements[i], 1);
	    }
	  return 1;
	}
      if (repodata_lookup_type(data, entry, keyname))
	break;
    }
  queue_empty(q);
  return 0;
}
コード例 #2
0
ファイル: fileprovides.c プロジェクト: openSUSE/libsolv
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;
}