LibWeb/IDB: Handle cursor iteration more correctly#6628
LibWeb/IDB: Handle cursor iteration more correctly#6628trflynn89 merged 1 commit intoLadybirdBrowser:masterfrom
Conversation
81dbe72 to
53b282f
Compare
| if (!Key::greater_than(inner_record.key, *key)) | ||
| return false; | ||
| // * If the record’s key is equal to key: | ||
| if (Key::equals(inner_record.key, *key)) { |
There was a problem hiding this comment.
Not sure about the retain_satisfaction I find this harder to read and the code doesn't short circuit there anymore
Seems like you could just keep the old style with the changes?
if (Key::equals(inner_record.key, *key)) {
if (!(Key::greater_than(inner_record.value, *primary_key) || Key::equals(inner_record.value, *primary_key)))
return false;
} else {
if (!Key::greater_than(inner_record.key, *key))
return false;
}There was a problem hiding this comment.
The inversion of the conditions made matching the logic and spec comments harder to follow imo
Since it reads as "If this, do that", but the code say "If not this, do that"
There was a problem hiding this comment.
I agree retain_satisfaction is quite awkward. It looks like a strange way to avoid using the &= operator. This also looks less efficient in that we no longer return early upon failure.
You've also changed the copied spec text in a way that makes it harder to compare to the spec itself, IMO.
Does the following not suffice?
diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
index 16ed5c6815..b69beca703 100644
--- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
+++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
@@ -1602,7 +1602,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::greater_than_or_equal(inner_record.key, *key);
});
if (!is_greater_than_or_equal)
@@ -1614,12 +1614,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to key and the record’s value is greater than or equal to primaryKey
- if (!(Key::equals(inner_record.key, *key) && (Key::greater_than(inner_record.value, *primary_key) || Key::equals(inner_record.value, *primary_key))))
- return false;
-
+ if (Key::equals(inner_record.key, *key)) {
+ if (!Key::greater_than_or_equal(inner_record.value, *primary_key))
+ return false;
+ }
// * The record’s key is greater than key.
- if (!Key::greater_than(inner_record.key, *key))
+ else if (!Key::greater_than(inner_record.key, *key)) {
return false;
+ }
}
// * If position is defined and source is an object store:
@@ -1636,12 +1638,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to position and the record’s value is greater than object store position
- if (!(Key::equals(inner_record.key, *position) && (Key::greater_than(inner_record.value, *object_store_position))))
- return false;
-
+ if (Key::equals(inner_record.key, *position)) {
+ if (!Key::greater_than(inner_record.value, *object_store_position))
+ return false;
+ }
// * The record’s key is greater than position.
- if (!Key::greater_than(inner_record.key, *position))
+ else if (!Key::greater_than(inner_record.key, *position)) {
return false;
+ }
}
// * The record’s key is in range.
@@ -1661,7 +1665,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::greater_than_or_equal(inner_record.key, *key);
});
if (!is_greater_than_or_equal)
@@ -1674,7 +1678,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_position = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[position](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *position) || Key::equals(inner_record.key, *position);
+ return Key::greater_than(inner_record.key, *position);
});
if (!is_greater_than_position)
@@ -1698,7 +1702,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::less_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::less_than_or_equal(inner_record.key, *key);
});
if (!is_less_than_or_equal)
@@ -1710,12 +1714,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to key and the record’s value is less than or equal to primaryKey
- if (!(Key::equals(inner_record.key, *key) && (Key::less_than(inner_record.value, *primary_key) || Key::equals(inner_record.value, *primary_key))))
- return false;
-
+ if (Key::equals(inner_record.key, *key)) {
+ if (!Key::less_than_or_equal(inner_record.value, *primary_key))
+ return false;
+ }
// * The record’s key is less than key.
- if (!Key::less_than(inner_record.key, *key))
+ else if (!Key::less_than(inner_record.key, *key)) {
return false;
+ }
}
// * If position is defined and source is an object store:
@@ -1732,12 +1738,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to position and the record’s value is less than object store position
- if (!(Key::equals(inner_record.key, *position) && Key::less_than(inner_record.value, *object_store_position)))
- return false;
-
+ if (Key::equals(inner_record.key, *position)) {
+ if (!Key::less_than(inner_record.value, *object_store_position))
+ return false;
+ }
// * The record’s key is less than position.
- if (!Key::less_than(inner_record.key, *position))
+ else if (!Key::less_than(inner_record.key, *position)) {
return false;
+ }
}
// * The record’s key is in range.
@@ -1757,7 +1765,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::less_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::less_than_or_equal(inner_record.key, *key);
});
if (!is_less_than_or_equal)
@@ -1770,7 +1778,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_position = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[position](auto const& inner_record) {
- return Key::less_than(inner_record.key, *position) || Key::equals(inner_record.key, *position);
+ return Key::less_than(inner_record.key, *position);
});
if (!is_less_than_position)There was a problem hiding this comment.
I agree retain_satisfaction is quite awkward. It looks like a strange way to avoid using the &= operator.
I forgot that &= existed tbh 😅
You've also changed the copied spec text in a way that makes it harder to compare to the spec itself, IMO.
It depends on the outcome of the linked spec PR. For now its matching the wording in that PR.
This also looks less efficient in that we no longer return early upon failure.
Ive restored the early return (and imo. improved readability) with a macro now
There was a problem hiding this comment.
Ive restored the early return (and imo. improved readability) with a macro now
This does not feel like an improvement to me, a macro just adds a level of indirection here when reading this code. Let's not be unnecessarily fancy, I would much prefer just a bog standard:
if (!condition)
return false;| if (!Key::greater_than(inner_record.key, *key)) | ||
| return false; | ||
| // * If the record’s key is equal to key: | ||
| if (Key::equals(inner_record.key, *key)) { |
There was a problem hiding this comment.
I agree retain_satisfaction is quite awkward. It looks like a strange way to avoid using the &= operator. This also looks less efficient in that we no longer return early upon failure.
You've also changed the copied spec text in a way that makes it harder to compare to the spec itself, IMO.
Does the following not suffice?
diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
index 16ed5c6815..b69beca703 100644
--- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
+++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp
@@ -1602,7 +1602,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::greater_than_or_equal(inner_record.key, *key);
});
if (!is_greater_than_or_equal)
@@ -1614,12 +1614,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to key and the record’s value is greater than or equal to primaryKey
- if (!(Key::equals(inner_record.key, *key) && (Key::greater_than(inner_record.value, *primary_key) || Key::equals(inner_record.value, *primary_key))))
- return false;
-
+ if (Key::equals(inner_record.key, *key)) {
+ if (!Key::greater_than_or_equal(inner_record.value, *primary_key))
+ return false;
+ }
// * The record’s key is greater than key.
- if (!Key::greater_than(inner_record.key, *key))
+ else if (!Key::greater_than(inner_record.key, *key)) {
return false;
+ }
}
// * If position is defined and source is an object store:
@@ -1636,12 +1638,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to position and the record’s value is greater than object store position
- if (!(Key::equals(inner_record.key, *position) && (Key::greater_than(inner_record.value, *object_store_position))))
- return false;
-
+ if (Key::equals(inner_record.key, *position)) {
+ if (!Key::greater_than(inner_record.value, *object_store_position))
+ return false;
+ }
// * The record’s key is greater than position.
- if (!Key::greater_than(inner_record.key, *position))
+ else if (!Key::greater_than(inner_record.key, *position)) {
return false;
+ }
}
// * The record’s key is in range.
@@ -1661,7 +1665,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::greater_than_or_equal(inner_record.key, *key);
});
if (!is_greater_than_or_equal)
@@ -1674,7 +1678,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_greater_than_position = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[position](auto const& inner_record) {
- return Key::greater_than(inner_record.key, *position) || Key::equals(inner_record.key, *position);
+ return Key::greater_than(inner_record.key, *position);
});
if (!is_greater_than_position)
@@ -1698,7 +1702,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::less_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::less_than_or_equal(inner_record.key, *key);
});
if (!is_less_than_or_equal)
@@ -1710,12 +1714,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to key and the record’s value is less than or equal to primaryKey
- if (!(Key::equals(inner_record.key, *key) && (Key::less_than(inner_record.value, *primary_key) || Key::equals(inner_record.value, *primary_key))))
- return false;
-
+ if (Key::equals(inner_record.key, *key)) {
+ if (!Key::less_than_or_equal(inner_record.value, *primary_key))
+ return false;
+ }
// * The record’s key is less than key.
- if (!Key::less_than(inner_record.key, *key))
+ else if (!Key::less_than(inner_record.key, *key)) {
return false;
+ }
}
// * If position is defined and source is an object store:
@@ -1732,12 +1738,14 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto const& inner_record = record.get<IndexRecord>();
// * The record’s key is equal to position and the record’s value is less than object store position
- if (!(Key::equals(inner_record.key, *position) && Key::less_than(inner_record.value, *object_store_position)))
- return false;
-
+ if (Key::equals(inner_record.key, *position)) {
+ if (!Key::less_than(inner_record.value, *object_store_position))
+ return false;
+ }
// * The record’s key is less than position.
- if (!Key::less_than(inner_record.key, *position))
+ else if (!Key::less_than(inner_record.key, *position)) {
return false;
+ }
}
// * The record’s key is in range.
@@ -1757,7 +1765,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_or_equal = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[key](auto const& inner_record) {
- return Key::less_than(inner_record.key, *key) || Key::equals(inner_record.key, *key);
+ return Key::less_than_or_equal(inner_record.key, *key);
});
if (!is_less_than_or_equal)
@@ -1770,7 +1778,7 @@ GC::Ptr<IDBCursor> iterate_a_cursor(JS::Realm& realm, GC::Ref<IDBCursor> cursor,
auto is_less_than_position = record.visit(
[](Empty) { VERIFY_NOT_REACHED(); },
[position](auto const& inner_record) {
- return Key::less_than(inner_record.key, *position) || Key::equals(inner_record.key, *position);
+ return Key::less_than(inner_record.key, *position);
});
if (!is_less_than_position)bbf9826 to
fe26907
Compare
fe26907 to
03ffb8d
Compare
Gives a few more WPT passes
Related spec bug: w3c/IndexedDB#481