/* Compute the intersection of src_1 and src_2 and write the result to * dst. It is allowed for dst to be equal to src_1. We assume that dst is a * valid container. */ void array_run_container_intersection(const array_container_t *src_1, const run_container_t *src_2, array_container_t *dst) { if (dst->capacity < src_1->cardinality) array_container_grow(dst, src_1->cardinality, INT32_MAX, false); if (src_2->n_runs == 0) { return; } int32_t rlepos = 0; int32_t arraypos = 0; rle16_t rle = src_2->runs[rlepos]; int32_t newcard = 0; while (arraypos < src_1->cardinality) { const uint16_t arrayval = src_1->array[arraypos]; while (rle.value + rle.length < arrayval) { // this will frequently be false ++rlepos; if (rlepos == src_2->n_runs) { dst->cardinality = newcard; return; // we are done } rle = src_2->runs[rlepos]; } if (rle.value > arrayval) { arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality, rle.value); } else { dst->array[newcard] = arrayval; newcard++; arraypos++; } } dst->cardinality = newcard; }
/* Compute the intersection of src_1 and src_2 and write the result to * dst. */ void array_bitset_container_intersection(const array_container_t *src_1, const bitset_container_t *src_2, array_container_t *dst) { if (dst->capacity < src_1->cardinality) array_container_grow(dst, src_1->cardinality, INT32_MAX, false); const int32_t origcard = src_1->cardinality; dst->cardinality = 0; for (int i = 0; i < origcard; ++i) { // could probably be vectorized uint16_t key = src_1->array[i]; // next bit could be branchless if (bitset_container_contains(src_2, key)) { dst->array[dst->cardinality++] = key; } } }
/* Compute the andnot of src_1 and src_2 and write the result to * dst, a valid array container that could be the same as dst.*/ void array_bitset_container_andnot(const array_container_t *src_1, const bitset_container_t *src_2, array_container_t *dst) { // follows Java implementation as of June 2016 if (dst->capacity < src_1->cardinality) array_container_grow(dst, src_1->cardinality, INT32_MAX, false); int32_t newcard = 0; const int32_t origcard = src_1->cardinality; for (int i = 0; i < origcard; ++i) { uint16_t key = src_1->array[i]; if (!bitset_container_contains(src_2, key)) { dst->array[newcard++] = key; } } dst->cardinality = newcard; }