8000 Eliminate copies when accessing values from Bson types by tgoyne · Pull Request #7377 · realm/realm-core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Eliminate copies when accessing values from Bson types #7377

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

Merged
merged 2 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* Fix a performance regression when reading values from Bson containers and revert some breaking changes to the Bson API ([PR #7377](https://github.com/realm/realm-core/pull/7377), since v14.0.0)
* List KVO information was being populated for non-list collections ([PR #7378](https://github.com/realm/realm-core/pull/7378), since v14.0.0)
* Setting a Mixed property to an ObjLink equal to its existing value would remove the existing backlinks and then exit before re-adding them, resulting in later assertion failures due to the backlink state being invalid ([PR #7384](https://github.com/realm/realm-core/pull/7384), since v14.0.0).
* Opening file with file format 23 in read-only mode will crash ([#7388](https://github.com/realm/realm-core/issues/7388), since v14.0.0)
Expand Down Expand Up @@ -48,7 +49,6 @@
* You can now use query substitution for the @type argument ([#7289](https://github.com/realm/realm-core/issues/7289))

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* Fixed crash when adding a collection to an indexed Mixed property ([#7246](https://github.com/realm/realm-core/issues/7246), since 14.0.0-beta.0)
* \[C-API] Fixed the return type of `realm_set_list` and `realm_set_dictionary` to be the newly inserted collection, similarly to the behavior of `list/dictionary_insert_collection` (PR [#7247](https://github.com/realm/realm-core/pull/7247), since 14.0.0-beta.0)
* Throw an exception when trying to insert an embedded object into a list of Mixed ([#7254](https://github.com/realm/realm-core/issues/7254), since 14.0.0-beta.0)
Expand All @@ -69,14 +69,14 @@
-----------

### Internals
* to_json API changed according to https://docs.google.com/document/d/1YtJN0sC89LMb4UVcPKFIfwC0Hsi9Vj7sIEP2vHQzVcY/edit?usp=sharing. Links to not embedded objects will never be followed.
* to_json API changed according to https://docs.google.com/document/d/1YtJN0sC89LMb4UVcPKFIfwC0Hsi9Vj7sIEP2vHQzVcY/edit?usp=sharing. Links to non-embedded objects will never be followed.

----------------------------------------------

# 14.0.0-beta.0 Release notes

### Enhancements
* Storage of Decimal128 properties has been optimised so that the individual values will take up 0 bits (if all nulls), 32 bits, 64 bits or 128 bits depending on what is needed. (PR [#6111]https://github.com/realm/realm-core/pull/6111))
* Storage of Decimal128 properties has been optimised so that the individual values will take up 0 bits (if all nulls), 32 bits, 64 bits or 128 bits depending on what is needed. (PR [#6111](https://github.com/realm/realm-core/pull/6111))
* You can have a collection embedded in any Mixed property (except Set<Mixed>).
* Querying a specific entry in a collection (in particular 'first and 'last') is supported. (PR [#4269](https://github.com/realm/realm-core/issues/4269))
* Index on list of strings property now supported (PR [#7142](https://github.com/realm/realm-core/pull/7142))
Expand All @@ -87,7 +87,7 @@
* Fixed equality queries on a Mixed property with an index possibly returning the wrong result if values of different types happened to have the same StringIndex hash. ([6407](https://github.com/realm/realm-core/issues/6407) since v11.0.0-beta.5).
* If you have more than 8388606 links pointing to one specific object, the program will crash. ([#6577](https://github.com/realm/realm-core/issues/6577), since v6.0.0)
* Query for NULL value in Dictionary<Mixed> would give wrong results ([6748])(https://github.com/realm/realm-core/issues/6748), since v10.0.0)
* A Realm generated on a non-apple ARM 64 device and copied to another platform (and vice-versa) were non-portable due to a sorting order difference. This impacts strings or binaries that have their first difference at a non-ascii character. These items may not be found in a set, or in an indexed column if the strings had a long common prefix (> 200 characters). ([PR # 6670](https://github.com/realm/realm-core/pull/6670), since 2.0.0-rc7 for indexes, and since since the introduction of sets in v10.2.0)
* A Realm generated on a non-apple ARM 64 device and copied to another platform (and vice-versa) were non-portable due to a sorting order difference. This impacts strings or binaries that have their first difference at a non-ascii character. These items may not be found in a set, or in an indexed column if the strings had a long common prefix (> 200 characters). ([PR #6670](https://github.com/realm/realm-core/pull/6670), since 2.0.0-rc7 for indexes, and since since the introduction of sets in v10.2.0)

### Breaking changes
* Support for upgrading from Realm files produced by RealmCore v5.23.9 or earlier is no longer supported.
Expand Down
30 changes: 15 additions & 15 deletions src/realm/object-store/sync/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,20 +694,20 @@ void App::attach_auth_options(BsonDocument& body)
log_debug("App: version info: platform: %1 version: %2 - sdk: %3 - sdk version: %4 - core version: %5",
m_config.device_info.platform, m_config.dev 8000 ice_info.platform_version, m_config.device_info.sdk,
m_config.device_info.sdk_version, m_config.device_info.core_version);
options.append("appId", m_config.app_id);
options.append("platform", m_config.device_info.platform);
options.append("platformVersion", m_config.device_info.platform_version);
options.append("sdk", m_config.device_info.sdk);
options.append("sdkVersion", m_config.device_info.sdk_version);
options.append("cpuArch", m_config.device_info.cpu_arch);
options.append("deviceName", m_config.device_info.device_name);
options.append("deviceVersion", m_config.device_info.device_version);
options.append("frameworkName", m_config.device_info.framework_name);
options.append("frameworkVersion", m_config.device_info.framework_version);
options.append("coreVersion", m_config.device_info.core_version);
options.append("bundleId", m_config.device_info.bundle_id);

body.append("options", BsonDocument({{"device", options}}));
options["appId"] = m_config.app_id;
options["platform"] = m_config.device_info.platform;
options["platformVersion"] = m_config.device_info.platform_version;
options["sdk"] = m_config.device_info.sdk;
options["sdkVersion"] = m_config.device_info.sdk_version;
options["cpuArch"] = m_config.device_info.cpu_arch;
options["deviceName"] = m_config.device_info.device_name;
options["deviceVersion"] = m_config.device_info.device_version;
options["frameworkName"] = m_config.device_info.framework_name;
options["frameworkVersion"] = m_config.device_info.framework_version;
options["coreVersion"] = m_config.device_info.core_version;
options["bundleId"] = m_config.device_info.bundle_id;

body["options"] = BsonDocument({{"device", options}});
}

void App::log_in_with_credentials(
Expand Down Expand Up @@ -1339,7 +1339,7 @@ Request App::make_streaming_request(const std::shared_ptr<SyncUser>& user, const
{"name", name},
};
if (service_name) {
args.append("service", *service_name);
args["service"] = *service_name;
}
const auto args_json = Bson(args).to_string();

Expand Down
4 changes: 2 additions & 2 deletions src/realm/object-store/sync/app_credentials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ AppCredentials::AppCredentials(AuthProvider provider,
: m_provider(provider)
, m_payload(std::make_unique<bson::BsonDocument>())
{
m_payload->append(kAppProviderKey, provider_type_from_enum(provider));
(*m_payload)[kAppProviderKey] = provider_type_from_enum(provider);
for (auto& [key, value] : values) {
m_payload->append(key, std::move(value));
(*m_payload)[key] = std::move(value);
}
}

Expand Down
52 changes: 26 additions & 26 deletions src/realm/object-store/sync/mongo_collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,23 +279,23 @@ void MongoCollection::call_function(const char* name, const bson::BsonDocument&
static void set_options(BsonDocument& base_args, const MongoCollection::FindOptions& options)
{
if (options.limit) {
base_args.append("limit", *options.limit);
base_args["limit"] = *options.limit;
}

if (options.projection_bson) {
base_args.append("project", *options.projection_bson);
base_args["project"] = *options.projection_bson;
}

if (options.sort_bson) {
base_args.append("sort", *options.sort_bson);
base_args["sort"] = *options.sort_bson;
}
}

void MongoCollection::find_bson(const BsonDocument& filter_bson, const FindOptions& options,
ResponseHandler<util::Optional<Bson>>&& completion)
try {
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args["query"] = filter_bson;
set_options(base_args, options);

call_function("find", base_args, std::move(completion));
Expand All @@ -308,7 +308,7 @@ void MongoCollection::find_one_bson(const BsonDocument& filter_bson, const FindO
ResponseHandler<util::Optional<Bson>>&& completion)
try {
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args["query"] = filter_bson;
set_options(base_args, options);
call_function("findOne", base_args, std::move(completion));
}
Expand All @@ -320,68 +320,68 @@ void MongoCollection::insert_one_bson(const BsonDocument& value_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("document", value_bson);
base_args["document"] = value_bson;
call_function("insertOne", base_args, std::move(completion));
}

void MongoCollection::aggregate_bson(const BsonArray& pipline, ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("pipeline", pipline);
base_args["pipeline"] = pipline;
call_function("aggregate", base_args, std::move(completion));
}

void MongoCollection::count_bson(const BsonDocument& filter_bson, int64_t limit,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args["query"] = filter_bson;
if (limit != 0) {
base_args.append("limit", limit);
base_args["limit"] = limit;
}
call_function("count", base_args, std::move(completion));
}

void MongoCollection::insert_many_bson(const BsonArray& documents, ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("documents", documents);
base_args["documents"] = documents;
call_function("insertMany", base_args, std::move(completion));
}

void MongoCollection::delete_one_bson(const BsonDocument& filter_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args["query"] = filter_bson;
call_function("deleteOne", base_args, std::move(completion));
}

void MongoCollection::delete_many_bson(const BsonDocument& filter_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args["query"] = filter_bson;
call_function("deleteMany", base_args, std::move(completion));
}

void MongoCollection::update_one_bson(const BsonDocument& filter_bson, const BsonDocument& update_bson, bool upsert,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args.append("update", update_bson);
base_args.append("upsert", upsert);
base_args["query"] = filter_bson;
base_args["update"] = update_bson;
base_args["upsert"] = upsert;
call_function("updateOne", base_args, std::move(completion));
}

void MongoCollection::update_many_bson(const BsonDocument& filter_bson, const BsonDocument& update_bson, bool upsert,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("query", filter_bson);
base_args.append("update", update_bson);
base_args.append("upsert", upsert);
base_args["query"] = filter_bson;
base_args["update"] = update_bson;
base_args["upsert"] = upsert;
call_function("updateMany", base_args, std::move(completion));
}

Expand All @@ -390,8 +390,8 @@ void MongoCollection::find_one_and_update_bson(const BsonDocument& filter_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("filter", filter_bson);
base_args.append("update", update_bson);
base_args["filter"] = filter_bson;
base_args["update"] = update_bson;
options.set_bson(base_args);
call_function("findOneAndUpdate", base_args, std::move(completion));
}
Expand All @@ -401,8 +401,8 @@ void MongoCollection::find_one_and_replace_bson(const BsonDocument& filter_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("filter", filter_bson);
base_args.append("update", replacement_bson);
base_args["filter"] = filter_bson;
base_args["update"] = replacement_bson;
options.set_bson(base_args);
call_function("findOneAndReplace", base_args, std::move(completion));
}
Expand All @@ -412,7 +412,7 @@ void MongoCollection::find_one_and_delete_bson(const BsonDocument& filter_bson,
ResponseHandler<util::Optional<Bson>>&& completion)
{
auto base_args = m_base_operation_args;
base_args.append("filter", filter_bson);
base_args["filter"] = filter_bson;
options.set_bson(base_args);
call_function("findOneAndDelete", base_args, std::move(completion));
}
Expand Down Expand Up @@ -568,16 +568,16 @@ void WatchStream::feed_sse(ServerSentEvent sse)
if (parsed.type() != Bson::Type::Document)
return;
auto& obj = static_cast<BsonDocument&>(parsed);
auto code = obj.at("error_code");
auto msg = obj.at("error");
auto& code = obj.at("error_code");
auto& msg = obj.at("error");
if (code.type() != Bson::Type::String)
return;
if (msg.type() != Bson::Type::String)
return;
auto error_code = ErrorCodes::from_string(static_cast<const std::string&>(code));
if (error_code == ErrorCodes::UnknownError)
error_code = ErrorCodes::AppUnknownError;
m_error = std::make_unique<AppError>(error_code, std::move(static_cast<const std::string&>(msg)));
m_error = std::make_unique<AppError>(error_code, std::move(static_cast<std::string&>(msg)));
}
catch (...) {
return; // Use the default state.
Expand Down
8 changes: 4 additions & 4 deletions src/realm/object-store/sync/mongo_collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@ class MongoCollection {
void set_bson(bson::BsonDocument& bson) const
{
if (upsert) {
bson.append("upsert", true);
bson["upsert"] = true;
}

if (return_new_document) {
bson.append("returnNewDocument", true);
bson["returnNewDocument"] = true;
}

if (projection_bson) {
bson.append("projection", *projection_bson);
bson["projection"] = *projection_bson;
}

if (sort_bson) {
bson.append("sort", *sort_bson);
bson["sort"] = *sort_bson;
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/realm/util/bson/bson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ Bson dom_elem_to_bson(const Json& json)
case Json::value_t::array: {
BsonArray out;
for (auto&& elem : json) {
out.append(dom_elem_to_bson(elem));
out.push_back(dom_elem_to_bson(elem));
}
return Bson(std::move(out));
}
Expand Down Expand Up @@ -786,7 +786,7 @@ Bson dom_obj_to_bson(const Json& json)

BsonDocument out;
for (auto&& [k, v] : json.items()) {
out.append(k, dom_elem_to_bson(v));
out[k] = dom_elem_to_bson(v);
}
return out;
}
Expand Down
46 changes: 21 additions & 25 deletions src/realm/util/bson/bson.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,31 +308,40 @@ class BsonDocument : private IndexedMap<Bson> {
return size() == 0;
}

void append(const std::string& key, const Bson& val)
Bson& operator[](const std::string& k)
{
IndexedMap<Bson>::operator[](key) = val;
return IndexedMap<Bson>::operator[](k);
}

Bson operator[](const std::string& k) const
Bson& at(const std::string& k)
{
return at(k);
return IndexedMap<Bson>::at(k);
}

Bson at(const std::string& k) const
const Bson& at(const std::string& k) const
{
return IndexedMap<Bson>::at(k);
}

std::optional<Bson> find(const std::string& key) const
Bson* find(const std::string& key)
{
auto& raw = entries();
if (auto it = raw.find(key); it != raw.end()) {
return &it->second;
}
return nullptr;
}

const Bson* find(const std::string& key) const
{
auto& raw = entries();
if (auto it = raw.find(key); it != raw.end()) {
return it->second;
return &it->second;
}
return {};
return nullptr;
}

bool operator==(const BsonDocument& other) const
bool operator==(const BsonDocument& other) const noexcept
{
return static_cast<const IndexedMap<Bson>*>(this)->entries() == other.entries();
}
Expand All @@ -341,26 +350,13 @@ class BsonDocument : private IndexedMap<Bson> {
class BsonArray : private std::vector<Bson> {
public:
using entry = Bson;
using vector<Bson>::vector;
using vector<Bson>::begin;
using vector<Bson>::end;
using vector<Bson>::size;
using vector<Bson>::empty;

BsonArray() {}
BsonArray(std::initializer_list<entry> entries)
: std::vector<Bson>(entries)
{
}

Bson operator[](size_t n) const
{
return std::vector<Bson>::operator[](n);
}

void append(const Bson& val)
{
std::vector<Bson>::push_back(val);
}
using vector<Bson>::push_back;
using vector<Bson>::operator[];

bool operator==(const BsonArray& other) const
{
Expand Down
Loading
0