mirror of
https://github.com/typesense/typesense.git
synced 2025-05-20 21:52:23 +08:00
commit
8ab753f571
165
src/field.cpp
165
src/field.cpp
@ -660,168 +660,3 @@ Option<bool> field::validate_and_init_embed_field(const tsl::htrie_map<char, fie
|
||||
|
||||
return Option<bool>(true);
|
||||
}
|
||||
|
||||
void filter_result_t::and_filter_results(const filter_result_t& a, const filter_result_t& b, filter_result_t& result) {
|
||||
auto lenA = a.count, lenB = b.count;
|
||||
if (lenA == 0 || lenB == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.docs = new uint32_t[std::min(lenA, lenB)];
|
||||
|
||||
auto A = a.docs, B = b.docs, out = result.docs;
|
||||
const uint32_t *endA = A + lenA;
|
||||
const uint32_t *endB = B + lenB;
|
||||
|
||||
// Add an entry of references in the result for each unique collection in a and b.
|
||||
for (auto const& item: a.reference_filter_results) {
|
||||
if (result.reference_filter_results.count(item.first) == 0) {
|
||||
result.reference_filter_results[item.first] = new reference_filter_result_t[std::min(lenA, lenB)];
|
||||
}
|
||||
}
|
||||
for (auto const& item: b.reference_filter_results) {
|
||||
if (result.reference_filter_results.count(item.first) == 0) {
|
||||
result.reference_filter_results[item.first] = new reference_filter_result_t[std::min(lenA, lenB)];
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
while (*A < *B) {
|
||||
SKIP_FIRST_COMPARE:
|
||||
if (++A == endA) {
|
||||
result.count = out - result.docs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (*A > *B) {
|
||||
if (++B == endB) {
|
||||
result.count = out - result.docs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (*A == *B) {
|
||||
*out = *A;
|
||||
|
||||
// Copy the references of the document from every collection into result.
|
||||
for (auto const& item: a.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][out - result.docs] = item.second[A - a.docs];
|
||||
}
|
||||
for (auto const& item: b.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][out - result.docs] = item.second[B - b.docs];
|
||||
}
|
||||
|
||||
out++;
|
||||
|
||||
if (++A == endA || ++B == endB) {
|
||||
result.count = out - result.docs;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
goto SKIP_FIRST_COMPARE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void filter_result_t::or_filter_results(const filter_result_t& a, const filter_result_t& b, filter_result_t& result) {
|
||||
if (a.count == 0 && b.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If either one of a or b does not have any matches, copy other into result.
|
||||
if (a.count == 0) {
|
||||
result = b;
|
||||
return;
|
||||
}
|
||||
if (b.count == 0) {
|
||||
result = a;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t indexA = 0, indexB = 0, res_index = 0, lenA = a.count, lenB = b.count;
|
||||
result.docs = new uint32_t[lenA + lenB];
|
||||
|
||||
// Add an entry of references in the result for each unique collection in a and b.
|
||||
for (auto const& item: a.reference_filter_results) {
|
||||
if (result.reference_filter_results.count(item.first) == 0) {
|
||||
result.reference_filter_results[item.first] = new reference_filter_result_t[lenA + lenB];
|
||||
}
|
||||
}
|
||||
for (auto const& item: b.reference_filter_results) {
|
||||
if (result.reference_filter_results.count(item.first) == 0) {
|
||||
result.reference_filter_results[item.first] = new reference_filter_result_t[lenA + lenB];
|
||||
}
|
||||
}
|
||||
|
||||
while (indexA < lenA && indexB < lenB) {
|
||||
if (a.docs[indexA] < b.docs[indexB]) {
|
||||
// check for duplicate
|
||||
if (res_index == 0 || result.docs[res_index - 1] != a.docs[indexA]) {
|
||||
result.docs[res_index] = a.docs[indexA];
|
||||
res_index++;
|
||||
}
|
||||
|
||||
// Copy references of the last result document from every collection in a.
|
||||
for (auto const& item: a.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][res_index - 1] = item.second[indexA];
|
||||
}
|
||||
|
||||
indexA++;
|
||||
} else {
|
||||
if (res_index == 0 || result.docs[res_index - 1] != b.docs[indexB]) {
|
||||
result.docs[res_index] = b.docs[indexB];
|
||||
res_index++;
|
||||
}
|
||||
|
||||
for (auto const& item: b.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][res_index - 1] = item.second[indexB];
|
||||
}
|
||||
|
||||
indexB++;
|
||||
}
|
||||
}
|
||||
|
||||
while (indexA < lenA) {
|
||||
if (res_index == 0 || result.docs[res_index - 1] != a.docs[indexA]) {
|
||||
result.docs[res_index] = a.docs[indexA];
|
||||
res_index++;
|
||||
}
|
||||
|
||||
for (auto const& item: a.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][res_index - 1] = item.second[indexA];
|
||||
}
|
||||
|
||||
indexA++;
|
||||
}
|
||||
|
||||
while (indexB < lenB) {
|
||||
if(res_index == 0 || result.docs[res_index - 1] != b.docs[indexB]) {
|
||||
result.docs[res_index] = b.docs[indexB];
|
||||
res_index++;
|
||||
}
|
||||
|
||||
for (auto const& item: b.reference_filter_results) {
|
||||
result.reference_filter_results[item.first][res_index - 1] = item.second[indexB];
|
||||
}
|
||||
|
||||
indexB++;
|
||||
}
|
||||
|
||||
result.count = res_index;
|
||||
|
||||
// shrink fit
|
||||
auto out = new uint32_t[res_index];
|
||||
memcpy(out, result.docs, res_index * sizeof(uint32_t));
|
||||
delete[] result.docs;
|
||||
result.docs = out;
|
||||
|
||||
for (auto &item: result.reference_filter_results) {
|
||||
auto out_references = new reference_filter_result_t[res_index];
|
||||
|
||||
for (uint32_t i = 0; i < result.count; i++) {
|
||||
out_references[i] = item.second[i];
|
||||
}
|
||||
delete[] item.second;
|
||||
item.second = out_references;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user