Skip to content

Commit

Permalink
Fixing binary search, with linear search; #529
Browse files Browse the repository at this point in the history
  • Loading branch information
the-moisrex committed Apr 12, 2024
1 parent c822994 commit 436bdb7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 46 deletions.
2 changes: 0 additions & 2 deletions webpp/uri/idna/details/generate_idna_mapping_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,6 @@ class MapTable extends TableTraits {
console.log(`Splitting: ${page}-${page_end}; block length: ${
page_end - page}; remaining: ${remaining}`);
}
// this.map(page - this.lengthLimit, end, mappedTo);
// console.log(`Splitting: ${page - this.lengthLimit}-${end}`);
return true;
}
return false;
Expand Down
103 changes: 59 additions & 44 deletions webpp/uri/idna/idna_mappings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ namespace webpp::uri::idna {

// anything bigger than the last element is disallowed
if ((asked_char & disallowed_mask) != 0U) {
auto const last_element = idna_mapping_table.begin() + (idna_mapping_table.size() - 1);
return last_element;
// last element:
return idna_mapping_table.begin() + (idna_mapping_table.size() - 1);
}

map_table_byte_type const element = asked_char | disallowed_mask;
Expand All @@ -86,52 +86,67 @@ namespace webpp::uri::idna {
// |
// first-byte: this is the byte we should find and compare against
// Binary Search:
// for (;;) {
// length >>= 1U; // devided by 2
// auto middle = first; // NOLINT(*-qualified-auto)
// std::advance(middle, length);
//
// // non-first-characters are ignored here
// decltype(length) remaining = 0;
// while ((*middle & mapped_mask) == 0U) {
// --middle;
// ++remaining;
// }
//
// if (first == middle) {
// stl::advance(middle, remaining);
// ++middle;
// while ((*middle & mapped_mask) == 0U) {
// ++middle;
// }
//
// if (element >= (*middle | disallowed_mask)) {
// first = middle;
// break;
// }
//
// break;
// }
// if (element < (*middle | disallowed_mask)) {
// length -= remaining;
// } else {
// // let's look into the hight half now
// first = middle;
// length += remaining;
// }
// }


// Alternative Linear Search:
for (auto cur = first; cur != idna_mapping_table.end(); ++cur) {
if ((*cur & mapped_mask) == 0U) {
continue;
for (;;) {
length >>= 1U; // devided by 2
auto middle = first; // NOLINT(*-qualified-auto)
std::advance(middle, length);

// non-first-characters are ignored here
decltype(length) remaining = 0;
while ((*middle & mapped_mask) == 0U) {
--middle;
++remaining;
}
if ((*cur | disallowed_mask) > element) {

// Why we need linear search in the middle of a binary search:
// if this last one is the result,
// dots are ignored characters, and
// '1' is the code-point we have to check.
// /
// 1..X
// ^ length >>= 1
// ^ length += remaining
// ^ length >>= 1
// ^ length += remaining
// ^ length >>= 1
// Then it's a loop.
if (first == middle) {
stl::advance(middle, remaining);
++middle;

// liniear search:
for (; middle != idna_mapping_table.end(); ++middle) {
if ((*middle & mapped_mask) == 0U) {
continue;
}
if ((*middle | disallowed_mask) > element) {
break;
}
first = middle;
}
break;
}
first = cur;
if (auto const cur_element = (*middle | disallowed_mask); cur_element <= element) {
// let's look into the hight half now
first = middle;
length += remaining;
} else {
// length -= remaining;
// --length;
}
}


// Alternative Linear Search:
// for (auto cur = first; cur != idna_mapping_table.end(); ++cur) {
// if ((*cur & mapped_mask) == 0U) {
// continue;
// }
// if ((*cur | disallowed_mask) > element) {
// break;
// }
// first = cur;
// }
return first;
}

Expand Down

0 comments on commit 436bdb7

Please sign in to comment.