@@ -40,7 +40,6 @@ bool TDatabase::TChangeCounter::operator<(const TChangeCounter& rhs) const {
40
40
41
41
TDatabase::TDatabase (TDatabaseImpl *databaseImpl) noexcept
42
42
: DatabaseImpl(databaseImpl ? databaseImpl : new TDatabaseImpl(0 , new TScheme, nullptr ))
43
- , NoMoreReadsFlag(true )
44
43
{
45
44
46
45
}
@@ -59,7 +58,7 @@ TIntrusiveConstPtr<TRowScheme> TDatabase::GetRowScheme(ui32 table) const noexcep
59
58
60
59
TAutoPtr<TTableIter> TDatabase::Iterate (ui32 table, TRawVals key, TTagsRef tags, ELookup mode) const noexcept
61
60
{
62
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u " , table);
61
+ CheckReadAllowed ( table);
63
62
64
63
const auto seekBy = [](TRawVals key, ELookup mode) {
65
64
if (!key && mode != ELookup::ExactMatch) {
@@ -92,7 +91,7 @@ TAutoPtr<TTableIter> TDatabase::IterateExact(ui32 table, TRawVals key, TTagsRef
92
91
const ITransactionMapPtr& visible,
93
92
const ITransactionObserverPtr& observer) const noexcept
94
93
{
95
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u " , table);
94
+ CheckReadAllowed ( table);
96
95
97
96
auto iter = Require (table)->Iterate (key, tags, Env, ESeek::Exact, snapshot, visible, observer);
98
97
@@ -144,7 +143,7 @@ TAutoPtr<TTableIter> TDatabase::IterateRange(ui32 table, const TKeyRange& range,
144
143
const ITransactionMapPtr& visible,
145
144
const ITransactionObserverPtr& observer) const noexcept
146
145
{
147
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u " , table);
146
+ CheckReadAllowed ( table);
148
147
149
148
Y_DEBUG_ABORT_UNLESS (!IsAmbiguousRange (range, Require (table)->GetScheme ()->Keys ->Size ()),
150
149
" %s" , IsAmbiguousRangeReason (range, Require (table)->GetScheme ()->Keys ->Size ()));
@@ -171,7 +170,7 @@ TAutoPtr<TTableReverseIter> TDatabase::IterateRangeReverse(ui32 table, const TKe
171
170
const ITransactionMapPtr& visible,
172
171
const ITransactionObserverPtr& observer) const noexcept
173
172
{
174
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u " , table);
173
+ CheckReadAllowed ( table);
175
174
176
175
Y_DEBUG_ABORT_UNLESS (!IsAmbiguousRange (range, Require (table)->GetScheme ()->Keys ->Size ()),
177
176
" %s" , IsAmbiguousRangeReason (range, Require (table)->GetScheme ()->Keys ->Size ()));
@@ -226,7 +225,7 @@ EReady TDatabase::Select(ui32 table, TRawVals key, TTagsRef tags, TRowState &row
226
225
const ITransactionObserverPtr& observer) const noexcept
227
226
{
228
227
TempIterators.clear ();
229
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u " , table);
228
+ CheckReadAllowed ( table);
230
229
231
230
auto prevSieved = stats.Sieved ;
232
231
auto prevWeeded = stats.Weeded ;
@@ -268,7 +267,8 @@ void TDatabase::CalculateReadSize(TSizeEnv& env, ui32 table, TRawVals minKey, TR
268
267
TTagsRef tags, ui64 flg, ui64 items, ui64 bytes,
269
268
EDirection direction, TRowVersion snapshot)
270
269
{
271
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to do precharge after reads prohibited, table %u" , table);
270
+ CheckReadAllowed (table);
271
+
272
272
TSelectStats stats;
273
273
Require (table)->Precharge (minKey, maxKey, tags, &env, flg, items, bytes, direction, snapshot, stats);
274
274
}
@@ -277,7 +277,8 @@ bool TDatabase::Precharge(ui32 table, TRawVals minKey, TRawVals maxKey,
277
277
TTagsRef tags, ui64 flg, ui64 items, ui64 bytes,
278
278
EDirection direction, TRowVersion snapshot)
279
279
{
280
- Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to do precharge after reads prohibited, table %u" , table);
280
+ CheckPrechargeAllowed (table, minKey, maxKey);
281
+
281
282
TSelectStats stats;
282
283
auto ready = Require (table)->Precharge (minKey, maxKey, tags, Env, flg, items, bytes, direction, snapshot, stats);
283
284
Change->Stats .ChargeSieved += stats.Sieved ;
@@ -428,6 +429,10 @@ void TDatabase::NoMoreReadsForTx() {
428
429
NoMoreReadsFlag = true ;
429
430
}
430
431
432
+ void TDatabase::NoMoreUnprechargedReadsForTx () {
433
+ NoMoreUnprechargedReadsFlag = true ;
434
+ }
435
+
431
436
void TDatabase::Begin (TTxStamp stamp, IPages& env)
432
437
{
433
438
Y_ABORT_UNLESS (!Redo, " Transaction already in progress" );
@@ -438,6 +443,8 @@ void TDatabase::Begin(TTxStamp stamp, IPages& env)
438
443
Change = MakeHolder<TChange>(stamp, DatabaseImpl->Serial ());
439
444
Env = &env;
440
445
NoMoreReadsFlag = false ;
446
+ NoMoreUnprechargedReadsFlag = false ;
447
+ PrechargedTables.clear ();
441
448
}
442
449
443
450
void TDatabase::RollbackChanges ()
@@ -802,6 +809,30 @@ TTable* TDatabase::RequireForUpdate(ui32 table) const noexcept
802
809
return DatabaseImpl->GetForUpdate (table).Self .Get ();
803
810
}
804
811
812
+ void TDatabase::CheckReadAllowed (ui32 table) const noexcept
813
+ {
814
+ Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to read after reads prohibited, table %u" , table);
815
+ if (NoMoreUnprechargedReadsFlag) [[unlikely]] {
816
+ Y_DEBUG_ABORT_UNLESS (
817
+ std::find (PrechargedTables.begin (), PrechargedTables.end (), table) != PrechargedTables.end (),
818
+ " Trying to read a previously unprecharged table %u" , table);
819
+ }
820
+ }
821
+
822
+ void TDatabase::CheckPrechargeAllowed (ui32 table, TRawVals minKey, TRawVals maxKey) const noexcept
823
+ {
824
+ Y_ABORT_UNLESS (!NoMoreReadsFlag, " Trying to precharge after reads prohibited, table %u" , table);
825
+ if (NoMoreUnprechargedReadsFlag) [[unlikely]] {
826
+ Y_DEBUG_ABORT_UNLESS (
827
+ std::find (PrechargedTables.begin (), PrechargedTables.end (), table) != PrechargedTables.end (),
828
+ " Trying to precharge a previously unprecharged table %u" , table);
829
+ } else if (!minKey && !maxKey) {
830
+ // Note: tables are usually fully precharged only in init transcations
831
+ // This vector is small or empty most of the time and not worth using a hash table
832
+ PrechargedTables.push_back (table);
833
+ }
834
+ }
835
+
805
836
TGarbage TDatabase::RollUp (TTxStamp stamp, TArrayRef<const char > delta, TArrayRef<const char > redo,
806
837
TMemGlobs annex)
807
838
{
0 commit comments