MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / loadInventoryPages

Method loadInventoryPages

src/jrd/tpc.cpp:293–358  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

291}
292
293void TipCache::loadInventoryPages(thread_db* tdbb, GlobalTpcHeader* header)
294{
295 // check the header page for the oldest and newest transaction numbers
296
297#ifdef SUPERSERVER_V2
298 Database* dbb = tdbb->getDatabase();
299 const TraNumber top = dbb->dbb_next_transaction;
300 const TraNumber hdr_oldest = dbb->dbb_oldest_transaction;
301#else
302 WIN window(HEADER_PAGE_NUMBER);
303 const Ods::header_page* header_page = (Ods::header_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_header);
304 const TraNumber hdr_oldest_transaction = Ods::getOIT(header_page);
305 const TraNumber hdr_next_transaction = Ods::getNT(header_page);
306 const AttNumber hdr_attachment_id = Ods::getAttID(header_page);
307 CCH_RELEASE(tdbb, &window);
308#endif
309
310 header->oldest_transaction.store(hdr_oldest_transaction, std::memory_order_relaxed);
311 header->latest_attachment_id.store(hdr_attachment_id, std::memory_order_relaxed);
312 header->latest_transaction_id.store(hdr_next_transaction, std::memory_order_relaxed);
313
314 // Check if TIP has any interesting transactions.
315 // At database creation time, it doesn't and the code below breaks
316 // if there isn't a single one transaction to care about.
317 if (hdr_oldest_transaction >= hdr_next_transaction)
318 return;
319
320 // Round down the oldest to a multiple of four, which puts the
321 // transaction in temporary buffer on a byte boundary
322 TraNumber base = hdr_oldest_transaction & ~TRA_MASK;
323
324 const FB_SIZE_T buffer_length = (hdr_next_transaction + 1 - base + TRA_MASK) / 4;
325 Array<UCHAR> transactions(buffer_length);
326
327 UCHAR* buffer = transactions.begin();
328 TRA_get_inventory(tdbb, buffer, base, hdr_next_transaction);
329
330 static const CommitNumber init_state_mapping[4] = {CN_ACTIVE, CN_LIMBO, CN_DEAD, CN_PREHISTORIC};
331
332 TpcBlockNumber blockNumber = hdr_oldest_transaction / m_transactionsPerBlock;
333 ULONG transOffset = hdr_oldest_transaction % m_transactionsPerBlock;
334
335 SyncLockGuard sync(&m_sync_status, SYNC_EXCLUSIVE, FB_FUNCTION);
336 TransactionStatusBlock* statusBlock = createTransactionStatusBlock(header->tpc_block_size, blockNumber);
337
338 for (TraNumber t = hdr_oldest_transaction; ; )
339 {
340 int state = TRA_state(buffer, base, t);
341 CommitNumber cn = init_state_mapping[state];
342
343 // Barrier is not needed as our thread is the only one here.
344 // At the same time, simple write to a volatile variable is not good
345 // as it is not deterministic. Some compilers generate barriers and some do not.
346 (statusBlock->data + transOffset)->store(cn, std::memory_order_relaxed);
347
348 if (++t > hdr_next_transaction)
349 break;
350

Callers 1

initializeMethod · 0.80

Calls 10

CCH_FETCHFunction · 0.85
getOITFunction · 0.85
getNTFunction · 0.85
getAttIDFunction · 0.85
CCH_RELEASEFunction · 0.85
TRA_get_inventoryFunction · 0.85
TRA_stateFunction · 0.85
getDatabaseMethod · 0.80
storeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected