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

Method allocateDifferencePage

src/jrd/nbak.cpp:742–814  ·  view source on GitHub ↗

Mark next difference page as used by some database page

Source from the content-addressed store, hash-verified

740
741// Mark next difference page as used by some database page
742ULONG BackupManager::allocateDifferencePage(thread_db* tdbb, ULONG db_page)
743{
744 LocalAllocWriteGuard localAllocGuard(this);
745
746 // This page may be allocated while we wait for a local lock above
747 if (ULONG diff_page = findPageIndex(tdbb, db_page)) {
748 return diff_page;
749 }
750
751 GlobalAllocWriteGuard globalAllocGuard(tdbb, this);
752
753 // This page may be allocated by other process
754 if (ULONG diff_page = findPageIndex(tdbb, db_page)) {
755 return diff_page;
756 }
757
758 NBAK_TRACE(("allocate_difference_page"));
759 fb_assert(last_allocated_page % (database->dbb_page_size / sizeof(ULONG)) == alloc_buffer[0]);
760
761 FbStatusVector* status_vector = tdbb->tdbb_status_vector;
762 // Grow file first. This is done in such order to keep difference
763 // file consistent in case of write error. We should always be able
764 // to read next alloc page when previous one is full.
765 BufferDesc temp_bdb(database->dbb_bcb);
766 temp_bdb.bdb_page = last_allocated_page + 1;
767 temp_bdb.bdb_buffer = reinterpret_cast<Ods::pag*>(empty_buffer);
768 if (!PIO_write(tdbb, diff_file, &temp_bdb, temp_bdb.bdb_buffer, status_vector))
769 return 0;
770
771 const bool alloc_page_full = alloc_buffer[0] == database->dbb_page_size / sizeof(ULONG) - 2;
772 if (alloc_page_full)
773 {
774 // Pointer page is full. Its time to create new one.
775 temp_bdb.bdb_page = last_allocated_page + 2;
776 temp_bdb.bdb_buffer = reinterpret_cast<Ods::pag*>(empty_buffer);
777 if (!PIO_write(tdbb, diff_file, &temp_bdb, temp_bdb.bdb_buffer, status_vector))
778 return 0;
779 }
780
781 // Write new item to the allocation table
782 temp_bdb.bdb_page = last_allocated_page & ~(database->dbb_page_size / sizeof(ULONG) - 1);
783 temp_bdb.bdb_buffer = reinterpret_cast<Ods::pag*>(alloc_buffer);
784 alloc_buffer[++alloc_buffer[0]] = db_page;
785 if (!PIO_write(tdbb, diff_file, &temp_bdb, temp_bdb.bdb_buffer, status_vector))
786 return 0;
787
788 last_allocated_page++;
789
790 // Register new page in the alloc table
791 try
792 {
793 alloc_table->add(AllocItem(db_page, last_allocated_page));
794 }
795 catch (const Firebird::Exception& ex)
796 {
797 // Handle out of memory error
798 delete alloc_table;
799 alloc_table = NULL;

Callers 1

set_diff_pageFunction · 0.80

Calls 4

AllocItemClass · 0.70
PIO_writeFunction · 0.50
addMethod · 0.45
stuffExceptionMethod · 0.45

Tested by

no test coverage detected