@@ -154,18 +154,24 @@ struct ResolutionRequestBuilder {
154
154
for (int idx = 0 ; idx < trIn.read_conflict_ranges .size (); ++idx) {
155
155
const auto & r = trIn.read_conflict_ranges [idx];
156
156
auto ranges = self->keyResolvers .intersectingRanges (r);
157
- std::set<int > resolvers;
157
+ std::vector<int > resolvers;
158
+ resolvers.reserve (self->resolvers .size ());
158
159
for (auto & ir : ranges) {
159
160
auto & version_resolver = ir.value ();
160
161
for (int i = version_resolver.size () - 1 ; i >= 0 ; i--) {
161
- resolvers.insert (version_resolver[i].second );
162
+ int resolver_id = version_resolver[i].second ;
163
+ if (std::find (resolvers.begin (), resolvers.end (), resolver_id) == resolvers.end ()) {
164
+ resolvers.push_back (resolver_id);
165
+ }
162
166
if (version_resolver[i].first < trIn.read_snapshot )
163
167
break ;
164
168
}
165
169
}
166
170
if (SERVER_KNOBS->PROXY_USE_RESOLVER_PRIVATE_MUTATIONS && systemKeys.intersects (r)) {
167
171
for (int k = 0 ; k < self->resolvers .size (); k++) {
168
- resolvers.insert (k);
172
+ if (std::find (resolvers.begin (), resolvers.end (), k) == resolvers.end ()) {
173
+ resolvers.push_back (k);
174
+ }
169
175
}
170
176
}
171
177
ASSERT (resolvers.size ());
@@ -181,16 +187,22 @@ struct ResolutionRequestBuilder {
181
187
void addWriteConflictRanges (CommitTransactionRef& trIn) {
182
188
for (auto & r : trIn.write_conflict_ranges ) {
183
189
auto ranges = self->keyResolvers .intersectingRanges (r);
184
- std::set<int > resolvers;
190
+ std::vector<int > resolvers;
191
+ resolvers.reserve (20 ); // Optimized for small resolver counts
185
192
for (auto & ir : ranges) {
186
193
auto & version_resolver = ir.value ();
187
194
if (!version_resolver.empty ()) {
188
- resolvers.insert (version_resolver.back ().second );
195
+ int resolver_id = version_resolver.back ().second ;
196
+ if (std::find (resolvers.begin (), resolvers.end (), resolver_id) == resolvers.end ()) {
197
+ resolvers.push_back (resolver_id);
198
+ }
189
199
}
190
200
}
191
201
if (SERVER_KNOBS->PROXY_USE_RESOLVER_PRIVATE_MUTATIONS && systemKeys.intersects (r)) {
192
202
for (int k = 0 ; k < self->resolvers .size (); k++) {
193
- resolvers.insert (k);
203
+ if (std::find (resolvers.begin (), resolvers.end (), k) == resolvers.end ()) {
204
+ resolvers.push_back (k);
205
+ }
194
206
}
195
207
}
196
208
ASSERT (resolvers.size ());
@@ -1619,11 +1631,25 @@ void applyMetadataEffect(CommitBatchContext* self) {
1619
1631
transactionIndex < self->resolution [0 ].stateMutations [versionIndex].size () && !self->forceRecovery ;
1620
1632
transactionIndex++) {
1621
1633
bool committed = true ;
1622
- for (int resolver = 0 ; resolver < self->resolution .size (); resolver++) {
1623
- committed =
1624
- committed && self->resolution [resolver].stateMutations [versionIndex][transactionIndex].committed ;
1634
+ auto & res = self->resolution ;
1635
+ auto isCommitted = [&](int i) { return res[i].stateMutations [versionIndex][transactionIndex].committed ; };
1636
+ // Unroll the loop for the common number of resolvers
1637
+ switch (res.size ()) {
1638
+ case 2 :
1639
+ committed = isCommitted (0 ) && isCommitted (1 );
1640
+ break ;
1641
+ case 4 :
1642
+ committed = isCommitted (0 ) && isCommitted (1 ) && isCommitted (2 ) && isCommitted (3 );
1643
+ break ;
1644
+ case 8 :
1645
+ committed = isCommitted (0 ) && isCommitted (1 ) && isCommitted (2 ) && isCommitted (3 ) && isCommitted (4 ) &&
1646
+ isCommitted (5 ) && isCommitted (6 ) && isCommitted (7 );
1647
+ break ;
1648
+ default :
1649
+ for (int resolver = 0 ; resolver < res.size (); resolver++) {
1650
+ committed = committed && isCommitted (resolver);
1651
+ }
1625
1652
}
1626
-
1627
1653
if (committed && self->pProxyCommitData ->getTenantMode () == TenantMode::REQUIRED) {
1628
1654
auto & tenantIds = self->resolution [0 ].stateMutations [versionIndex][transactionIndex].tenantIds ;
1629
1655
ASSERT (tenantIds.present ());
@@ -1672,7 +1698,8 @@ void applyMetadataEffect(CommitBatchContext* self) {
1672
1698
}
1673
1699
}
1674
1700
1675
- // These changes to txnStateStore will be committed by the other proxy, so we simply discard the commit message
1701
+ // These changes to txnStateStore will be committed by the other proxy, so we simply discard the commit
1702
+ // message
1676
1703
auto fcm = self->pProxyCommitData ->logAdapter ->getCommitMessage ();
1677
1704
self->storeCommits .emplace_back (fcm, self->pProxyCommitData ->txnStateStore ->commit ());
1678
1705
@@ -1735,8 +1762,8 @@ void determineCommittedTransactions(CommitBatchContext* self) {
1735
1762
}
1736
1763
}
1737
1764
1738
- // This first pass through committed transactions deals with "metadata" effects (modifications of txnStateStore, changes
1739
- // to storage servers' responsibilities)
1765
+ // This first pass through committed transactions deals with "metadata" effects (modifications of txnStateStore,
1766
+ // changes to storage servers' responsibilities)
1740
1767
ACTOR Future<Void> applyMetadataToCommittedTransactions (CommitBatchContext* self) {
1741
1768
state ProxyCommitData* const pProxyCommitData = self->pProxyCommitData ;
1742
1769
state std::unordered_set<int64_t > rawAccessTenantIds;
@@ -2025,7 +2052,8 @@ void addAccumulativeChecksumMutations(CommitBatchContext* self) {
2025
2052
self->toCommit .writeTypedMessage (acsMutation);
2026
2053
}
2027
2054
}
2028
- // RangeLock takes effect only when the feature flag is on and database is unlocked and the mutation is not encrypted
2055
+ // RangeLock takes effect only when the feature flag is on and database is unlocked and the mutation is not
2056
+ // encrypted
2029
2057
void rejectMutationsForReadLockOnRange (CommitBatchContext* self) {
2030
2058
ASSERT (self->rangeLockEnabled ());
2031
2059
ProxyCommitData* const pProxyCommitData = self->pProxyCommitData ;
@@ -2328,6 +2356,7 @@ ACTOR Future<Void> postResolution(CommitBatchContext* self) {
2328
2356
self->isMyFirstBatch = !pProxyCommitData->version .get ();
2329
2357
self->previousCoordinators = pProxyCommitData->txnStateStore ->readValue (coordinatorsKey).get ();
2330
2358
2359
+ // debug mode only?
2331
2360
assertResolutionStateMutationsSizeConsistent (self->resolution );
2332
2361
2333
2362
applyMetadataEffect (self);
@@ -2694,7 +2723,8 @@ ACTOR Future<Void> reply(CommitBatchContext* self) {
2694
2723
2695
2724
if (SERVER_KNOBS->ENABLE_VERSION_VECTOR_TLOG_UNICAST ) {
2696
2725
// We have received a reply from the sequencer, so all versions prior to the current version have been
2697
- // made durable and we can consider the current transaction to be committed - advance min commit version now.
2726
+ // made durable and we can consider the current transaction to be committed - advance min commit version
2727
+ // now.
2698
2728
if (self->prevVersion && self->commitVersion - self->prevVersion < SERVER_KNOBS->MAX_VERSIONS_IN_FLIGHT / 2 ) {
2699
2729
// TraceEvent("CPAdvanceMinVersion", self->pProxyCommitData->dbgid).detail("PrvVersion", self->prevVersion).detail("CommitVersion", self->commitVersion).detail("Master", self->pProxyCommitData->master.id().toString()).detail("TxSize", self->trs.size());
2700
2730
debug_advanceMinCommittedVersion (UID (), self->commitVersion );
@@ -2845,15 +2875,16 @@ ACTOR Future<Void> commitBatchImpl(CommitBatchContext* pContext) {
2845
2875
pContext->stage = INITIALIZE;
2846
2876
getCurrentLineage ()->modify (&TransactionLineage::operation) = TransactionLineage::Operation::Commit;
2847
2877
2848
- // Active load balancing runs at a very high priority (to obtain accurate estimate of memory used by commit batches)
2849
- // so we need to downgrade here
2878
+ // Active load balancing runs at a very high priority (to obtain accurate estimate of memory used by commit
2879
+ // batches) so we need to downgrade here
2850
2880
wait (delay (0 , TaskPriority::ProxyCommit));
2851
2881
2852
2882
pContext->pProxyCommitData ->lastVersionTime = pContext->startTime ;
2853
2883
++pContext->pProxyCommitData ->stats .commitBatchIn ;
2854
2884
pContext->setupTraceBatch ();
2855
2885
2856
- // ///// Phase 1: Pre-resolution processing (CPU bound except waiting for a version # which is separately pipelined
2886
+ // ///// Phase 1: Pre-resolution processing (CPU bound except waiting for a version # which is separately
2887
+ // / pipelined
2857
2888
// / and *should* be available by now (unless empty commit); ordered; currently atomic but could yield)
2858
2889
pContext->stage = PRE_RESOLUTION;
2859
2890
wait (CommitBatch::preresolutionProcessing (pContext));
@@ -2866,12 +2897,14 @@ ACTOR Future<Void> commitBatchImpl(CommitBatchContext* pContext) {
2866
2897
pContext->stage = RESOLUTION;
2867
2898
wait (CommitBatch::getResolution (pContext));
2868
2899
2869
- // //// Phase 3: Post-resolution processing (CPU bound except for very rare situations; ordered; currently atomic but
2900
+ // //// Phase 3: Post-resolution processing (CPU bound except for very rare situations; ordered; currently atomic
2901
+ // / but
2870
2902
// / doesn't need to be)
2871
2903
pContext->stage = POST_RESOLUTION;
2872
2904
wait (CommitBatch::postResolution (pContext));
2873
2905
2874
- // ///// Phase 4: Logging (network bound; pipelined up to MAX_READ_TRANSACTION_LIFE_VERSIONS (limited by loop above))
2906
+ // ///// Phase 4: Logging (network bound; pipelined up to MAX_READ_TRANSACTION_LIFE_VERSIONS (limited by loop
2907
+ // / above))
2875
2908
pContext->stage = TRANSACTION_LOGGING;
2876
2909
wait (CommitBatch::transactionLogging (pContext));
2877
2910
0 commit comments