Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

option to check duplicate object keys #801

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

grisumbras
Copy link
Member

Fix #127

@cppalliance-bot
Copy link

@codecov
Copy link

codecov bot commented Nov 7, 2022

Codecov Report

Merging #801 (8715073) into develop (4d22409) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop     #801   +/-   ##
========================================
  Coverage    99.00%   99.00%           
========================================
  Files           71       71           
  Lines         6831     6833    +2     
========================================
+ Hits          6763     6765    +2     
  Misses          68       68           
Impacted Files Coverage Δ
include/boost/json/object.hpp 100.00% <ø> (ø)
include/boost/json/detail/impl/handler.ipp 100.00% <100.00%> (ø)
include/boost/json/detail/object.hpp 100.00% <100.00%> (ø)
include/boost/json/impl/error.ipp 100.00% <100.00%> (ø)
include/boost/json/impl/object.hpp 100.00% <100.00%> (ø)
include/boost/json/impl/object.ipp 100.00% <100.00%> (ø)
include/boost/json/impl/parser.ipp 100.00% <100.00%> (ø)
include/boost/json/impl/stream_parser.ipp 100.00% <100.00%> (ø)
include/boost/json/impl/value_stack.ipp 100.00% <100.00%> (ø)
include/boost/json/value.hpp 98.94% <100.00%> (ø)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4d22409...8715073. Read the comment docs.

@vinniefalco
Copy link
Member

yeah please don't merge this with the commit message as "different approach" :)

@@ -232,6 +230,11 @@ object(detail::unchecked_object&& uo)
continue;
}
// handle duplicate
if( !uo.ignore_duplicate_keys() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a constant in the loop, so you should lift the conditional out of the loop

@@ -270,6 +274,11 @@ object(detail::unchecked_object&& uo)
}

// handle duplicate
if( !uo.ignore_duplicate_keys() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a constant in the loop, so you should lift the conditional out of the loop

@cppalliance-bot
Copy link

void
push_object(std::size_t n);
error_code
push_object(std::size_t n, bool ignore_duplicates = true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer it as allow_duplicates, defaulting to false. Rationale: The default settings should have the all-zero bit-pattern. It is also easier to understand this way, you are opting in to the setting by assigning true. Rather than opting out to disallowing duplicates by assigning false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Ignore duplicates" and "allow duplicates" are the same thing (at least in this case). The reverse of "ingore" would be "forbid". So, "forbid_duplicate_keys" option, with false as default?

@grisumbras grisumbras marked this pull request as draft November 7, 2022 17:01
template< class Object >
static constexpr
index_t
null_index(Object const&) noexcept
Copy link
Member

@vinniefalco vinniefalco Nov 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we mucking about with value? And why are these templates?

value* p = data_;
while(size_--)

for( value* p = data_; p != end_; p += 2 )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this loop? I prefer the while form, as it puts each of the statements on their own line. The for is wider, and puts multiple statements on one line, which makes debugging and code coverage worse.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why, because the loop is simpler.

@cppalliance-bot
Copy link


std::size_t
unchecked_object::
size() const noexcept
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we move this from a header that wasn't visible to a header that is visible?

@cppalliance-bot
Copy link

}

inline
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the inline goes on the definition not the declaration (my fault)

@@ -70,6 +70,75 @@ find_in_object<string_view>(
object const& obj,
string_view key) noexcept;

template< bool SmallTable, bool IgnoreDuplicates >
void init_from_unchecked( object& obj, unchecked_object& uo )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be noexcept?

void init_from_unchecked( object& obj, unchecked_object& uo )
{
// insert all elements, keeping
// the last of any duplicate keys, unless IgnoreDuplicates is false.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be an assert here, the precondition of the function requires capacity() >= uo.size()

@@ -364,16 +364,25 @@ push_array(std::size_t n)
st_.exchange(std::move(ua));
}

void
error_code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is going to force the construction of a new error code for every object even when there is no error and even when ignore_duplicates is true. It should be an outparam. Or even a bool

if( uo.size() )
{
BOOST_JSON_FAIL( ec, error::duplicate_key );
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that the way this is implemented has impacted performance, which is causing the regression in the per-commit performance checker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request for I-JSON (RFC 7493) Parsing Mode
3 participants