Skip to content

Commit 9f4d51c

Browse files
committed
Merge branch 'next-major' into fsa/string-interning
2 parents fcb50cd + ac249ef commit 9f4d51c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2259
-3476
lines changed

.github/workflows/make-release.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ jobs:
1212
finish_release:
1313
if: github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/automated_v')
1414
runs-on: ubuntu-latest
15+
environment:
16+
name: Production
17+
url: ${{ steps.publish-github-release.outputs.html_url }}
1518
steps:
1619
- name: Checkout
1720
uses: actions/checkout@v4
@@ -29,6 +32,7 @@ jobs:
2932
shell: bash
3033
- name: Make Tag and Publish Github Release
3134
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 #! 1.14.0
35+
id: publish-github-release
3236
with:
3337
bodyFile: extracted_changelog.md
3438
name: Realm Core v${{ steps.get-version.outputs.version }}

.github/workflows/prepare-release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ jobs:
2323
- name: Change Version
2424
run: tools/release-init.sh ${{ inputs.version }}
2525
shell: bash
26+
env:
27+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # the gh command in the release script requires this token
2628
- name: Create Release PR
2729
id: prepare-pr
2830
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #! 6.0.5
2931
with:
3032
branch: release/automated_v${{ inputs.version }}
3133
title: Prepare for ${{ inputs.version }}
3234
draft: false
33-
body-path: changes-since-last-tag.txt
35+
body-path: pr-body.txt
3436
labels: no-jira-ticket
3537
commit-message: Prepare for release ${{ inputs.version }}
3638
token: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,4 @@ ssh_agent_commands.sh
110110

111111
# release script artifacts
112112
extracted_changelog.md
113-
changes-since-last-tag.txt
113+
pr-body.txt

CHANGELOG.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# NEXT RELEASE
1+
# NEXT MAJOR RELEASE
22

33
### Enhancements
44
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
5+
* Storage of integers changed so that they take up less space in the file. This can cause commits and some queries to take a bit longer (PR [#7668](https://github.com/realm/realm-core/pull/7668))
56

67
### Fixed
78
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
9+
* None.
810

911
### Breaking changes
1012
* None.
@@ -19,12 +21,43 @@
1921

2022
----------------------------------------------
2123

24+
# 14.10.0 Release notes
25+
26+
### Enhancements
27+
* Include the originating client reset error in AutoClientResetFailure errors. ([#7761](https://github.com/realm/realm-core/pull/7761))
28+
* Reduce the size of the local transaction log produced by creating objects, improving the performance of insertion-heavy transactions ([PR #7734](https://github.com/realm/realm-core/pull/7734)).
29+
30+
### Fixed
31+
* Fix some client resets (such as migrating to flexible sync) potentially failing with AutoClientResetFailed if a new client reset condition (such as rolling back a flexible sync migration) occurred before the first one completed. ([PR #7542](https://github.com/realm/realm-core/pull/7542), since v13.11.0)
32+
* Encrypted files on Windows had a maximum size of 2GB even on x64 due to internal usage of `off_t`, which is a 32-bit type on 64-bit Windows ([PR #7698](https://github.com/realm/realm-core/pull/7698), since the introduction of encryption support on Windows in v3.0.0).
33+
* The encryption code no longer behaves differently depending on the system page size, which should entirely eliminate a recurring source of bugs related to copying encrypted Realm files between platforms with different page sizes. One known outstanding bug was ([RNET-1141](https://github.com/realm/realm-dotnet/issues/3592)), where opening files on a system with a larger page size than the writing system would attempt to read sections of the file which had never been written to ([PR #7698](https://github.com/realm/realm-core/pull/7698)).
34+
* There were several complicated scenarios which could result in stale reads from encrypted files in multiprocess scenarios. These were very difficult to hit and would typically lead to a crash, either due to an assertion failure or DecryptionFailure being thrown ([PR #7698](https://github.com/realm/realm-core/pull/7698), since v13.9.0).
35+
* Encrypted files have some benign data races where we can memcpy a block of memory while another thread is writing to a limited range of it. It is logically impossible to ever read from that range when this happens, but Thread Sanitizer quite reasonably complains about this. We now perform a slower operations when running with TSan which avoids this benign race ([PR #7698](https://github.com/realm/realm-core/pull/7698)).
36+
* Tokenizing strings for full-text search could pass values outside the range [-1, 255] to `isspace()`, which is undefined behavior ([PR #7698](https://github.com/realm/realm-core/pull/7698), since the introduction of FTS in v13.0.0).
37+
38+
### Breaking changes
39+
* Any `stitch_` prefixed fields in the `BsonDocument` returned from `app::User::custom_data()` are being renamed on the server to have a `baas_` prefix instead ([PR #7769](https://github.com/realm/realm-core/pull/7769)).
40+
41+
### Compatibility
42+
* Fileformat: Generates files with format v24. Reads and automatically upgrade from fileformat v10. If you want to upgrade from an earlier file format version you will have to use RealmCore v13.x.y or earlier.
43+
44+
-----------
45+
46+
### Internals
47+
* Removed references to `stitch_` fields in access tokens in sync unit tests ([PR #7769](https://github.com/realm/realm-core/pull/7769)).
48+
* Added back iOS simulator testing to evergreen after Jenkins went away ([PR #7758](https://github.com/realm/realm-core/pull/7758)).
49+
* `realm-trawler -c` did not work on Realm using SyncClient history ([PR #7734](https://github.com/realm/realm-core/pull/7734)).
50+
* `File::Map`'s move constructor and assignment operator left `m_fd` unchanged, which appears to have never actually resulted in problems with how it was used ([PR #7698](https://github.com/realm/realm-core/pull/7698)).
51+
52+
----------------------------------------------
53+
2254
# 14.9.0 Release notes
2355

2456
### Enhancements
2557
* Report the originating error that caused a client reset to occur. ([#6154](https://github.com/realm/realm-core/issues/6154))
2658

2759
### Fixed
60+
* Add a missing file from the bid library to the android blueprint. (PR [#7738](https://github.com/realm/realm-core/pull/7738))
2861
* After compacting, a file upgrade would be triggered. This could cause loss of data if schema mode is SoftResetFile ([#7747](https://github.com/realm/realm-core/issues/7747), since 14.0.0)
2962
* Add missing `REALM_APP_SERVICES` flag to the android blueprint. (PR [#7755](https://github.com/realm/realm-core/pull/7755))
3063

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import PackageDescription
44
import Foundation
55

6-
let versionStr = "14.9.0"
6+
let versionStr = "14.10.0"
77
let versionPieces = versionStr.split(separator: "-")
88
let versionCompontents = versionPieces[0].split(separator: ".")
99
let versionExtra = versionPieces.count > 1 ? versionPieces[1] : ""

dependencies.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PACKAGE_NAME: realm-core
2-
VERSION: 14.9.0
2+
VERSION: 14.10.0
33
OPENSSL_VERSION: 3.2.0
44
ZLIB_VERSION: 1.2.13
55
# https://github.com/10gen/baas/commits

src/realm/alloc.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ char* Allocator::translate_less_critical(RefTranslation* ref_translation_ptr, re
120120
RefTranslation& txl = ref_translation_ptr[idx];
121121
size_t offset = ref - get_section_base(idx);
122122
char* addr = txl.mapping_addr + offset;
123-
#if REALM_ENABLE_ENCRYPTION
124-
realm::util::encryption_read_barrier(addr, NodeHeader::header_size, txl.encrypted_mapping, nullptr);
125-
#endif
123+
util::encryption_read_barrier(addr, NodeHeader::header_size, txl.encrypted_mapping);
126124
// if we know the translation is inside the slab area, we don't need to check
127125
// for anything beyond the header, and we don't need to check if decryption is needed
128126
auto size = known_in_slab ? 8 : NodeHeader::get_byte_size_from_header(addr);
@@ -138,27 +136,21 @@ char* Allocator::translate_less_critical(RefTranslation* ref_translation_ptr, re
138136
}
139137
if (REALM_LIKELY(!crosses_mapping)) {
140138
// Array fits inside primary mapping, no new mapping needed.
141-
#if REALM_ENABLE_ENCRYPTION
142-
realm::util::encryption_read_barrier(addr, size, txl.encrypted_mapping, nullptr);
143-
#endif
139+
util::encryption_read_barrier(addr, size, txl.encrypted_mapping);
144140
return addr;
145141
}
146-
else {
147-
// we need a cross-over mapping. If one is already established, use that.
148-
auto xover_mapping_addr = txl.xover_mapping_addr.load(std::memory_order_acquire);
149-
if (!xover_mapping_addr) {
150-
// we need to establish a xover mapping - or wait for another thread to finish
151-
// establishing one:
152-
const_cast<Allocator*>(this)->get_or_add_xover_mapping(txl, idx, offset, size);
153-
// reload (can be relaxed since the call above synchronizes on a mutex)
154-
xover_mapping_addr = txl.xover_mapping_addr.load(std::memory_order_relaxed);
155-
}
156-
// array is now known to be inside the established xover mapping:
157-
addr = xover_mapping_addr + (offset - txl.xover_mapping_base);
158-
#if REALM_ENABLE_ENCRYPTION
159-
realm::util::encryption_read_barrier(addr, size, txl.xover_encrypted_mapping, nullptr);
160-
#endif
161-
return addr;
142+
// we need a cross-over mapping. If one is already established, use that.
143+
auto xover_mapping_addr = txl.xover_mapping_addr.load(std::memory_order_acquire);
144+
if (!xover_mapping_addr) {
145+
// we need to establish a xover mapping - or wait for another thread to finish
146+
// establishing one:
147+
const_cast<Allocator*>(this)->get_or_add_xover_mapping(txl, idx, offset, size);
148+
// reload (can be relaxed since the call above synchronizes on a mutex)
149+
xover_mapping_addr = txl.xover_mapping_addr.load(std::memory_order_relaxed);
162150
}
151+
// array is now known to be inside the established xover mapping:
152+
addr = xover_mapping_addr + (offset - txl.xover_mapping_base);
153+
util::encryption_read_barrier(addr, size, txl.xover_encrypted_mapping);
154+
return addr;
163155
}
164156
} // namespace realm

src/realm/alloc.hpp

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class Allocator {
174174
// into equal chunks.
175175
struct RefTranslation {
176176
char* mapping_addr;
177-
uint64_t cookie;
177+
uint64_t cookie = 0x1234567890;
178178
std::atomic<size_t> lowest_possible_xover_offset = 0;
179179

180180
// member 'xover_mapping_addr' is used for memory synchronization of the fields
@@ -186,14 +186,12 @@ class Allocator {
186186
#if REALM_ENABLE_ENCRYPTION
187187
util::EncryptedFileMapping* encrypted_mapping = nullptr;
188188
util::EncryptedFileMapping* xover_encrypted_mapping = nullptr;
189+
#else
190+
static inline util::EncryptedFileMapping* const encrypted_mapping = nullptr;
191+
static inline util::EncryptedFileMapping* const xover_encrypted_mapping = nullptr;
189192
#endif
190-
explicit RefTranslation(char* addr)
193+
explicit RefTranslation(char* addr = nullptr)
191194
: mapping_addr(addr)
192-
, cookie(0x1234567890)
193-
{
194-
}
195-
RefTranslation()
196-
: RefTranslation(nullptr)
197195
{
198196
}
199197
~RefTranslation()
@@ -225,7 +223,7 @@ class Allocator {
225223
};
226224
// This pointer may be changed concurrently with access, so make sure it is
227225
// atomic!
228-
std::atomic<RefTranslation*> m_ref_translation_ptr;
226+
std::atomic<RefTranslation*> m_ref_translation_ptr{nullptr};
229227

230228
/// The specified size must be divisible by 8, and must not be
231229
/// zero.
@@ -255,7 +253,7 @@ class Allocator {
255253
char* translate_critical(RefTranslation*, ref_type ref, bool known_in_slab = false) const noexcept;
256254
char* translate_less_critical(RefTranslation*, ref_type ref, bool known_in_slab = false) const noexcept;
257255
virtual void get_or_add_xover_mapping(RefTranslation&, size_t, size_t, size_t) = 0;
258-
Allocator() noexcept;
256+
Allocator() noexcept = default;
259257
size_t get_section_index(size_t pos) const noexcept;
260258
inline size_t get_section_base(size_t index) const noexcept;
261259

@@ -274,11 +272,9 @@ class Allocator {
274272
// used to detect if the allocator (and owning structure, e.g. Table)
275273
// is recycled. Mismatch on this counter will cause accesors
276274
// lower in the hierarchy to throw if access is attempted.
277-
std::atomic<uint_fast64_t> m_content_versioning_counter;
278-
279-
std::atomic<uint_fast64_t> m_storage_versioning_counter;
280-
281-
std::atomic<uint_fast64_t> m_instance_versioning_counter;
275+
std::atomic<uint_fast64_t> m_content_versioning_counter{0};
276+
std::atomic<uint_fast64_t> m_storage_versioning_counter{0};
277+
std::atomic<uint_fast64_t> m_instance_versioning_counter{0};
282278

283279
inline uint_fast64_t get_storage_version(uint64_t instance_version)
284280
{
@@ -550,14 +546,6 @@ inline bool Allocator::is_read_only(ref_type ref) const noexcept
550546
return ref < m_baseline.load(std::memory_order_relaxed);
551547
}
552548

553-
inline Allocator::Allocator() noexcept
554-
{
555-
m_content_versioning_counter = 0;
556-
m_storage_versioning_counter = 0;
557-
m_instance_versioning_counter = 0;
558-
m_ref_translation_ptr = nullptr;
559-
}
560-
561549
// performance critical part of the translation process. Less critical code is in translate_less_critical.
562550
inline char* Allocator::translate_critical(RefTranslation* ref_translation_ptr, ref_type ref,
563551
bool known_in_slab) const noexcept
@@ -570,30 +558,23 @@ inline char* Allocator::translate_critical(RefTranslation* ref_translation_ptr,
570558
if (REALM_LIKELY(offset < lowest_possible_xover_offset)) {
571559
// the lowest possible xover offset may grow concurrently, but that will not affect this code path
572560
char* addr = txl.mapping_addr + offset;
573-
#if REALM_ENABLE_ENCRYPTION
574-
realm::util::encryption_read_barrier(addr, NodeHeader::header_size, txl.encrypted_mapping,
575-
NodeHeader::get_byte_size_from_header);
576-
#endif
561+
util::encryption_read_barrier(addr, NodeHeader::header_size, txl.encrypted_mapping);
562+
size_t size = NodeHeader::get_byte_size_from_header(addr);
563+
util::encryption_read_barrier(addr, size, txl.encrypted_mapping);
577564
return addr;
578565
}
579-
else {
580-
// the lowest possible xover offset may grow concurrently, but that will be handled inside the call
581-
return translate_less_critical(ref_translation_ptr, ref, known_in_slab);
582-
}
566+
// the lowest possible xover offset may grow concurrently, but that will be handled inside the call
567+
return translate_less_critical(ref_translation_ptr, ref, known_in_slab);
583568
}
584569
realm::util::terminate("Invalid ref translation entry", __FILE__, __LINE__, txl.cookie, 0x1234567890, ref, idx);
585-
return nullptr;
586570
}
587571

588572
inline char* Allocator::translate(ref_type ref) const noexcept
589573
{
590-
auto ref_translation_ptr = m_ref_translation_ptr.load(std::memory_order_acquire);
591-
if (REALM_LIKELY(ref_translation_ptr)) {
592-
return translate_critical(ref_translation_ptr, ref);
593-
}
594-
else {
595-
return do_translate(ref);
574+
if (auto ptr = m_ref_translation_ptr.load(std::memory_order_acquire); REALM_LIKELY(ptr)) {
575+
return translate_critical(ptr, ref);
596576
}
577+
return do_translate(ref);
597578
}
598579

599580
inline char* Allocator::translate_in_slab(ref_type ref) const noexcept

0 commit comments

Comments
 (0)