+ return pool_intersect_evrs(pool, rd1->flags, rd1->evr, rd2->flags, rd2->evr);
+}
+
+Id
+pool_searchlazywhatprovidesq(Pool *pool, Id d)
+{
+ int start = 0;
+ int end = pool->lazywhatprovidesq.count;
+ Id *elements;
+ if (!end)
+ return 0;
+ elements = pool->lazywhatprovidesq.elements;
+ while (end - start > 16)
+ {
+ int mid = (start + end) / 2 & ~1;
+ if (elements[mid] == d)
+ return elements[mid + 1];
+ if (elements[mid] < d)
+ start = mid + 2;
+ else
+ end = mid;
+ }
+ for (; start < end; start += 2)
+ if (elements[start] == d)
+ return elements[start + 1];
+ return 0;
+}
+
+/*
+ * addstdproviders
+ *
+ * lazy populating of the whatprovides array, non relation case
+ */
+static Id
+pool_addstdproviders(Pool *pool, Id d)
+{
+ const char *str;
+ Queue q;
+ Id qbuf[16];
+ Dataiterator di;
+ Id oldoffset;
+
+ if (pool->addedfileprovides == 2)
+ {
+ pool->whatprovides[d] = 1;
+ return 1;
+ }
+ str = pool->ss.stringspace + pool->ss.strings[d];
+ if (*str != '/')
+ {
+ pool->whatprovides[d] = 1;
+ return 1;
+ }
+ queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
+ dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, str, SEARCH_STRING|SEARCH_FILES);
+ for (; dataiterator_step(&di); dataiterator_skip_solvable(&di))
+ {
+ Solvable *s = pool->solvables + di.solvid;
+ /* XXX: maybe should add a provides dependency to the solvables
+ * OTOH this is only needed for rel deps that filter the provides,
+ * and those should not use filelist entries */
+ if (s->repo->disabled)
+ continue;
+ if (!pool_installable_whatprovides(pool, s))
+ continue;
+ queue_push(&q, di.solvid);
+ }
+ dataiterator_free(&di);
+ oldoffset = pool_searchlazywhatprovidesq(pool, d);
+ if (!q.count)
+ pool->whatprovides[d] = oldoffset ? oldoffset : 1;
+ else
+ {
+ if (oldoffset)
+ {
+ Id *oo = pool->whatprovidesdata + oldoffset;
+ int i;
+ /* unify both queues. easy, as we know both are sorted */
+ for (i = 0; i < q.count; i++)
+ {
+ if (*oo > q.elements[i])
+ continue;
+ if (*oo < q.elements[i])
+ queue_insert(&q, i, *oo);
+ oo++;
+ if (!*oo)
+ break;
+ }
+ while (*oo)
+ queue_push(&q, *oo++);
+ if (q.count == oo - (pool->whatprovidesdata + oldoffset))
+ {
+ /* end result has same size as oldoffset -> no new entries */
+ queue_free(&q);
+ pool->whatprovides[d] = oldoffset;
+ return oldoffset;
+ }
+ }
+ pool->whatprovides[d] = pool_queuetowhatprovides(pool, &q);
+ }
+ queue_free(&q);
+ return pool->whatprovides[d];
+}
+
+
+static inline int
+pool_is_kind(Pool *pool, Id name, Id kind)
+{
+ const char *n;
+ if (!kind)
+ return 1;
+ n = pool_id2str(pool, name);
+ if (kind != 1)
+ {
+ const char *kn = pool_id2str(pool, kind);
+ int knl = strlen(kn);
+ return !strncmp(n, kn, knl) && n[knl] == ':' ? 1 : 0;
+ }
+ else
+ {
+ if (*n == ':')
+ return 1;
+ while(*n >= 'a' && *n <= 'z')
+ n++;
+ return *n == ':' ? 0 : 1;
+ }
+}
+
+/*
+ * rpm eq magic:
+ *
+ * some dependencies are of the from "foo = md5sum", like the
+ * buildid provides. There's not much we can do to speed up
+ * getting the providers, because rpm's complex evr comparison
+ * rules get in the way. But we can use the first character(s)
+ * of the md5sum to do a simple pre-check.
+ */
+static inline int
+rpmeqmagic(Pool *pool, Id evr)
+{
+ const char *s = pool_id2str(pool, evr);
+ if (*s == '0')
+ {
+ while (*s == '0' && s[1] >= '0' && s[1] <= '9')
+ s++;
+ /* ignore epoch 0 */
+ if (*s == '0' && s[1] == ':')
+ {
+ s += 2;
+ while (*s == '0' && s[1] >= '0' && s[1] <= '9')
+ s++;
+ }
+ }
+ if (*s >= '0' && *s <= '9')
+ {
+ if (s[1] >= '0' && s[1] <= '9')
+ return *s + (s[1] << 8);
+ return *s;
+ }
+ if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z'))
+ {
+ if ((s[1] >= 'a' && s[1] <= 'z') || (s[1] >= 'A' && s[1] <= 'Z'))
+ return *s + (s[1] << 8);
+ return *s;
+ }
+ return -1;
+}
+
+static inline int
+rpmeqmagic_init(Pool *pool, int flags, Id evr)
+{
+ if (flags != REL_EQ || pool->disttype != DISTTYPE_RPM || pool->promoteepoch || ISRELDEP(evr))
+ return -1;
+ else
+ return rpmeqmagic(pool, evr);
+}
+
+static inline int
+rpmeqmagic_cantmatch(Pool *pool, int flags, Id evr, int eqmagic)
+{
+ int peqmagic = rpmeqmagic(pool, evr);
+ if (peqmagic > 0 && peqmagic != eqmagic)
+ return 1;
+ return 0;