"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/dpm.epp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

dpm.epp  (Firebird-3.0.2.32703-0.tar.bz2):dpm.epp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 150 skipping to change at line 150
* Functional description * Functional description
* Backout a record where the record and previous version are on * Backout a record where the record and previous version are on
* the same page. * the same page.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_backout (record_param %" QUADFORMAT"d)\n", rpb->rpb_number.g "DPM_backout (rel_id %u, record_param %" QUADFORMAT"d)\n",
etValue()); relation->rel_id, rpb->rpb_number.getValue());
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back %" " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back %"
ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n", ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page, rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page,
rpb->rpb_f_line, rpb->rpb_flags); rpb->rpb_f_line, rpb->rpb_flags);
#endif #endif
CCH_MARK(tdbb, &rpb->getWindow(tdbb)); CCH_MARK(tdbb, &rpb->getWindow(tdbb));
skipping to change at line 231 skipping to change at line 233
* *
* D P M _ c a r d i n a l i t y * D P M _ c a r d i n a l i t y
* *
************************************** **************************************
* *
* Functional description * Functional description
* Estimate cardinality for the given relation. * Estimate cardinality for the given relation.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* const dbb = tdbb->getDatabase();
// Estimated number of total records for this relation,
// we assume that the records are compressed to 50%
// Every record has also a header and a jump section (13 + 4)
USHORT minRecordSize = static_cast<USHORT>(sizeof(Ods::data_page::dpg_rep
eat) + RHD_SIZE);
if (!(dbb->dbb_flags & DBB_no_reserve)) {
minRecordSize += RHDF_SIZE;
}
// Get the number of data-pages for this relation // Get the number of data pages for this relation
const ULONG dataPages = DPM_data_pages(tdbb, relation); const ULONG dataPages = DPM_data_pages(tdbb, relation);
// AB: If we have only 1 data-page then the cardinality calculation // Calculate record count and total compressed record length
// is to worse to be useful, therefore rely on the record count // on the first data page
// from the data-page.
if (dataPages == 1) ULONG recordCount = 0, recordLength = 0;
const RelationPages* const relPages = relation->getPages(tdbb);
const vcl* const vector = relPages->rel_pages;
if (vector)
{ {
RelationPages* relPages = relation->getPages(tdbb); WIN window(relPages->rel_pg_space_id, (*vector)[0]);
vcl* vector = relPages->rel_pages;
if (vector) Ods::pointer_page* ppage =
{ (Ods::pointer_page*) CCH_FETCH(tdbb, &window, LCK_read, p
WIN window(relPages->rel_pg_space_id, (*vector)[0]); ag_pointer);
Ods::pointer_page* ppage = if (!ppage)
(Ods::pointer_page*) CCH_FETCH(tdbb, &window, LCK {
_read, pag_pointer); BUGCHECK(243);
USHORT recordCount = 0; // msg 243 missing pointer page in DPM_data_pages
const ULONG* page = ppage->ppg_page; }
const ULONG* page = ppage->ppg_page;
const ULONG* const end_page = page + ppage->ppg_count;
while (page < end_page)
{
if (*page) if (*page)
{ {
Ods::data_page* dpage = Ods::data_page* dpage =
(Ods::data_page*) CCH_HANDOFF(tdbb, &wind ow, *page, LCK_read, pag_data); (Ods::data_page*) CCH_HANDOFF(tdbb, &wind ow, *page, LCK_read, pag_data);
recordCount = dpage->dpg_count;
const data_page::dpg_repeat* index = dpage->dpg_r
pt;
const data_page::dpg_repeat* const end = index +
dpage->dpg_count;
for (; index < end; index++)
{
if (index->dpg_offset)
{
recordCount++;
recordLength += index->dpg_length
- RHD_SIZE;
}
}
break;
} }
CCH_RELEASE(tdbb, &window); page++;
return (double) recordCount;
} }
CCH_RELEASE(tdbb, &window);
} }
// AB: If we have only 1 data-page then the cardinality calculation
// is too imprecise to be useful, therefore rely on the record count
// from the data-page.
if (dataPages == 1)
return (double) recordCount;
// Estimate total number of records for this relation
if (!format) if (!format)
format = relation->rel_current_format; format = MET_current(tdbb, relation);
static const double DEFAULT_COMPRESSION_RATIO = 0.5;
const ULONG compressedSize =
recordCount ? recordLength / recordCount :
format->fmt_length * DEFAULT_COMPRESSION_RATIO;
const ULONG recordSize = sizeof(Ods::data_page::dpg_repeat) +
ROUNDUP(compressedSize + RHD_SIZE, ODS_ALIGNMENT) +
((dbb->dbb_flags & DBB_no_reserve) ? 0 : SPACE_FUDGE);
return (double) dataPages * (dbb->dbb_page_size - DPG_SIZE) / return (double) dataPages * (dbb->dbb_page_size - DPG_SIZE) / recordSize;
(minRecordSize + (format->fmt_length * 0.5));
} }
bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb) bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
{ {
/************************************** /**************************************
* *
* D P M _ c h a i n * D P M _ c h a i n
* *
************************************** **************************************
* *
skipping to change at line 307 skipping to change at line 339
* that record number. The caller has to check the results to * that record number. The caller has to check the results to
* see what failed if false is returned. At the moment, there is * see what failed if false is returned. At the moment, there is
* only one caller, VIO_erase. * only one caller, VIO_erase.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = org_rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_chain (org_rpb %" QUADFORMAT"d, new_rpb %" "DPM_chain (rel_id %u, org_rpb %" QUADFORMAT"d, new_rpb %" QUADFO
QUADFORMAT"d)\n", org_rpb->rpb_number.getValue(), RMAT"d)\n",
relation->rel_id, org_rpb->rpb_number.getValue(),
new_rpb ? new_rpb->rpb_number.getValue() : 0); new_rpb ? new_rpb->rpb_number.getValue() : 0);
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" org record %" ULONGFORMAT":%d transaction %" ULONGFORMAT " org record %" ULONGFORMAT":%d transaction %" ULONGFORMAT
" back %" ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n" , " back %" ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n" ,
org_rpb->rpb_page, org_rpb->rpb_line, org_rpb->rpb_transaction_nr , org_rpb->rpb_page, org_rpb->rpb_line, org_rpb->rpb_transaction_nr ,
org_rpb->rpb_b_page, org_rpb->rpb_b_line, org_rpb->rpb_f_page, org_rpb->rpb_b_page, org_rpb->rpb_b_line, org_rpb->rpb_f_page,
org_rpb->rpb_f_line, org_rpb->rpb_flags); org_rpb->rpb_f_line, org_rpb->rpb_flags);
if (new_rpb) if (new_rpb)
skipping to change at line 477 skipping to change at line 510
header->rhd_b_page = new_rpb->rpb_b_page; header->rhd_b_page = new_rpb->rpb_b_page;
header->rhd_b_line = new_rpb->rpb_b_line; header->rhd_b_line = new_rpb->rpb_b_line;
UCHAR* const data = (UCHAR*) header + header_size; UCHAR* const data = (UCHAR*) header + header_size;
dcc.pack(new_rpb->rpb_address, data); dcc.pack(new_rpb->rpb_address, data);
if (fill) if (fill)
memset(data + size, 0, fill); memset(data + size, 0, fill);
#ifdef VIO_DEBUG
VIO_trace(DEBUG_WRITES_INFO,
" new record %" ULONGFORMAT":%d transaction %" ULONGFORMAT
" back %" ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n"
,
new_rpb->rpb_page, new_rpb->rpb_line, new_rpb->rpb_transaction_nr
,
new_rpb->rpb_b_page, new_rpb->rpb_b_line, new_rpb->rpb_f_page,
new_rpb->rpb_f_line, new_rpb->rpb_flags);
#endif
if (page->dpg_header.pag_flags & dpg_swept) if (page->dpg_header.pag_flags & dpg_swept)
{ {
page->dpg_header.pag_flags &= ~dpg_swept; page->dpg_header.pag_flags &= ~dpg_swept;
mark_full(tdbb, org_rpb); mark_full(tdbb, org_rpb);
} }
else else
CCH_RELEASE(tdbb, &org_rpb->getWindow(tdbb)); CCH_RELEASE(tdbb, &org_rpb->getWindow(tdbb));
return true; return true;
} }
skipping to change at line 614 skipping to change at line 656
while (page < end_page) while (page < end_page)
{ {
if (*page++) if (*page++)
pages++; pages++;
} }
if (ppage->ppg_header.pag_flags & ppg_eof) if (ppage->ppg_header.pag_flags & ppg_eof)
break; break;
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
tdbb->checkCancelState(true);
} }
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
relPages->rel_data_pages = pages; relPages->rel_data_pages = pages;
} }
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_TRACE_ALL, VIO_trace(DEBUG_TRACE_ALL,
" returned pages: %" ULONGFORMAT"\n", pages); " returned pages: %" ULONGFORMAT"\n", pages);
#endif #endif
skipping to change at line 649 skipping to change at line 693
* record header into the record parameter block before deleting * record header into the record parameter block before deleting
* it. If the record goes empty, release the page. Release the * it. If the record goes empty, release the page. Release the
* page when we're done. * page when we're done.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_delete (record_param %" QUADFORMAT", prior_page %" ULONGFORM AT")\n", "DPM_delete (record_param %" QUADFORMAT", prior_page %" ULONGFORM AT")\n",
rpb->rpb_number.getValue(), prior_page); rpb->rpb_number.getValue(), prior_page);
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back %" " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back %"
ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n", ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page, rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page,
rpb->rpb_f_line, rpb->rpb_flags); rpb->rpb_f_line, rpb->rpb_flags);
skipping to change at line 899 skipping to change at line 944
// Make sure that the pointer page is written after the data page. // Make sure that the pointer page is written after the data page.
// The resulting 'must-be-written-after' graph is: // The resulting 'must-be-written-after' graph is:
// pip --> pp --> deallocated page --> prior_page // pip --> pp --> deallocated page --> prior_page
for (i = 0; i < pages.getCount(); i++, s++) for (i = 0; i < pages.getCount(); i++, s++)
CCH_precedence(tdbb, &pwindow, pages[i]); CCH_precedence(tdbb, &pwindow, pages[i]);
CCH_MARK(tdbb, &pwindow); CCH_MARK(tdbb, &pwindow);
const ULONG dpSequence = ppage->ppg_sequence * dbb->dbb_dp_per_pp;
s = extent ? firstSlot : slot; s = extent ? firstSlot : slot;
for (i = 0; i < pages.getCount(); i++, s++) for (i = 0; i < pages.getCount(); i++, s++)
{
ppage->ppg_page[s] = 0; ppage->ppg_page[s] = 0;
if (relPages->rel_last_free_pri_dp == pages[i])
relPages->rel_last_free_pri_dp = 0;
relPages->setDPNumber(dpSequence + s, 0);
}
if (relPages->rel_data_pages) if (relPages->rel_data_pages)
relPages->rel_data_pages -= pages.getCount(); relPages->rel_data_pages -= pages.getCount();
const ULONG* ptr; const ULONG* ptr;
for (ptr = &ppage->ppg_page[ppage->ppg_count]; ptr > ppage->ppg_page; --p tr) for (ptr = &ppage->ppg_page[ppage->ppg_count]; ptr > ppage->ppg_page; --p tr)
{ {
if (ptr[-1]) if (ptr[-1])
break; break;
} }
skipping to change at line 975 skipping to change at line 1028
Jrd::RelationPages* relPages) Jrd::RelationPages* relPages)
{ {
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
WIN window(relPages->rel_pg_space_id, -1), data_window(relPages->rel_pg_s pace_id, -1); WIN window(relPages->rel_pg_space_id, -1), data_window(relPages->rel_pg_s pace_id, -1);
window.win_flags = data_window.win_flags = WIN_large_scan; window.win_flags = data_window.win_flags = WIN_large_scan;
window.win_scans = data_window.win_scans = 1; window.win_scans = data_window.win_scans = 1;
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_TRACE_ALL, VIO_trace(DEBUG_TRACE_ALL,
"DPM_delete_relation (relation %d)\n", relation->rel_id); "DPM_delete_relation_pages (relation %d, instance %" SQUADFORMAT"
)\n",
relation->rel_id, relPages->rel_instance_id);
#endif #endif
// Delete all data and pointer pages // Delete all data and pointer pages
SortedArray<ULONG, InlineStorage<ULONG, 256> > pages(*relation->rel_pool) ; SortedArray<ULONG, InlineStorage<ULONG, 256> > pages(*relation->rel_pool) ;
for (ULONG sequence = 0; true; sequence++) for (ULONG sequence = 0; true; sequence++)
{ {
const pointer_page* ppage = const pointer_page* ppage =
get_pointer_page(tdbb, relation, relPages, &window, seque nce, LCK_read); get_pointer_page(tdbb, relation, relPages, &window, seque nce, LCK_read);
skipping to change at line 1067 skipping to change at line 1121
* Fetch a particular record fragment from page and line numbers. * Fetch a particular record fragment from page and line numbers.
* Get various header stuff, but don't change the record number. * Get various header stuff, but don't change the record number.
* *
* return: true if the fragment is returned. * return: true if the fragment is returned.
* false if the fragment is not found. * false if the fragment is not found.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_fetch (record_param %" QUADFORMAT"d, lock %d)\n", "DPM_fetch (rel_id %u, record_param %" QUADFORMAT"d, lock %d)\n",
rpb->rpb_number.getValue(), lock); relation->rel_id, rpb->rpb_number.getValue(), lock);
VIO_trace(DEBUG_READS_INFO, VIO_trace(DEBUG_READS_INFO,
" record %" ULONGFORMAT":%d\n", rpb->rpb_page, rpb->rpb_line); " record %" ULONGFORMAT":%d\n", rpb->rpb_page, rpb->rpb_line);
#endif #endif
const RecordNumber number = rpb->rpb_number; const RecordNumber number = rpb->rpb_number;
RelationPages* relPages = rpb->rpb_relation->getPages(tdbb); RelationPages* relPages = rpb->rpb_relation->getPages(tdbb);
rpb->getWindow(tdbb).win_page = PageNumber(relPages->rel_pg_space_id, rpb ->rpb_page); rpb->getWindow(tdbb).win_page = PageNumber(relPages->rel_pg_space_id, rpb ->rpb_page);
CCH_FETCH(tdbb, &rpb->getWindow(tdbb), lock, pag_data); CCH_FETCH(tdbb, &rpb->getWindow(tdbb), lock, pag_data);
skipping to change at line 1128 skipping to change at line 1183
* true: fetch back was successful. * true: fetch back was successful.
* false: unsuccessful (only possible is latch_wait <> 1), * false: unsuccessful (only possible is latch_wait <> 1),
* The latch timed out. * The latch timed out.
* The latch on the fetched page is downgraded to shared. * The latch on the fetched page is downgraded to shared.
* The fetched page is unmarked. * The fetched page is unmarked.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_fetch_back (record_param %" QUADFORMAT"d, lock %d)\n", "DPM_fetch_back (rel_id %u, record_param %" QUADFORMAT"d, lock %d
rpb->rpb_number.getValue(), lock); )\n",
relation->rel_id, rpb->rpb_number.getValue(), lock);
VIO_trace(DEBUG_READS_INFO, VIO_trace(DEBUG_READS_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT
" back %" ULONGFORMAT":%d\n", " back %" ULONGFORMAT":%d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line); rpb->rpb_b_page, rpb->rpb_b_line);
#endif #endif
// Possibly allow a latch timeout to occur. Return error if that is the case. // Possibly allow a latch timeout to occur. Return error if that is the case.
skipping to change at line 1190 skipping to change at line 1246
* *
************************************** **************************************
* *
* Functional description * Functional description
* Chase a fragment pointer with a handoff. * Chase a fragment pointer with a handoff.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_fetch_fragment (record_param %" QUADFORMAT"d, lock %d)\n", "DPM_fetch_fragment (rel_id %u, record_param %" QUADFORMAT"d, loc
rpb->rpb_number.getValue(), lock); k %d)\n",
relation->rel_id, rpb->rpb_number.getValue(), lock);
VIO_trace(DEBUG_READS_INFO, VIO_trace(DEBUG_READS_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT
" back %" ULONGFORMAT":%d\n", " back %" ULONGFORMAT":%d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line); rpb->rpb_b_page, rpb->rpb_b_line);
#endif #endif
const RecordNumber number = rpb->rpb_number; const RecordNumber number = rpb->rpb_number;
rpb->rpb_page = rpb->rpb_f_page; rpb->rpb_page = rpb->rpb_f_page;
skipping to change at line 1302 skipping to change at line 1359
const SSHORT lock_mode = dbb->readOnly() ? LCK_read : LCK_write; const SSHORT lock_mode = dbb->readOnly() ? LCK_read : LCK_write;
generator_page* const page = (generator_page*) CCH_FETCH(tdbb, &window, l ock_mode, pag_ids); generator_page* const page = (generator_page*) CCH_FETCH(tdbb, &window, l ock_mode, pag_ids);
/* If we are in ODS >= 10, then we have a pointer to an int64 value in t he /* If we are in ODS >= 10, then we have a pointer to an int64 value in t he
* generator page: if earlier than 10, it's a pointer to a long value. * generator page: if earlier than 10, it's a pointer to a long value.
* Pick up the right kind of pointer, based on the ODS version. * Pick up the right kind of pointer, based on the ODS version.
* The conditions were commented out 1999-05-14 by ChrisJ, because we * The conditions were commented out 1999-05-14 by ChrisJ, because we
* decided that the V6 engine would only access an ODS-10 database. * decided that the V6 engine would only access an ODS-10 database.
* (and uncommented 2000-05-05, also by ChrisJ, when minds changed.) * (and uncommented 2000-05-05, also by ChrisJ, when minds changed.)
*
* ODS12.1 - take into account ODS 12.0 which may have wrong offset
(see CORE-5791)
*/ */
SINT64* const ptr = ((SINT64*) (page->gpg_values)) + offset; SINT64* ptr = Ods::getGpgValues(page, dbb->dbb_implementation, dbb->dbb_m
inor_version);
fb_assert(ptr);
ptr += offset;
if (val || initialize) if (val || initialize)
{ {
if (dbb->readOnly()) if (dbb->readOnly())
{ {
CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, &window);
ERR_post(Arg::Gds(isc_read_only_database)); ERR_post(Arg::Gds(isc_read_only_database));
} }
CCH_MARK_SYSTEM(tdbb, &window); CCH_MARK_SYSTEM(tdbb, &window);
skipping to change at line 1349 skipping to change at line 1410
* Functional description * Functional description
* Get a specific record in a relation. If it doesn't exit, * Get a specific record in a relation. If it doesn't exit,
* just return false. * just return false.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_get (record_param %" QUADFORMAT"d, lock type %d)\n", "DPM_get (rel_id %u, record_param %" QUADFORMAT"d, lock type %d)\
rpb->rpb_number.getValue(), lock_type); n",
relation->rel_id, rpb->rpb_number.getValue(), lock_type);
#endif #endif
WIN* window = &rpb->getWindow(tdbb); WIN* window = &rpb->getWindow(tdbb);
rpb->rpb_prior = NULL; rpb->rpb_prior = NULL;
// Find starting point // Find starting point
ULONG pp_sequence; ULONG pp_sequence;
USHORT slot, line; USHORT slot, line;
rpb->rpb_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, slot, pp_sequence); rpb->rpb_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, slot, pp_sequence);
skipping to change at line 1451 skipping to change at line 1513
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
record_param rpb; record_param rpb;
rpb.rpb_relation = blob->blb_relation; rpb.rpb_relation = blob->blb_relation;
rpb.getWindow(tdbb).win_flags = WIN_secondary; rpb.getWindow(tdbb).win_flags = WIN_secondary;
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = blob->blb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_get_blob (blob, record_number %" QUADFORMAT "DPM_get_blob (rel_id %u, blob, record_number %" QUADFORMAT
"d, delete_flag %d, prior_page %" ULONGFORMAT")\n", "d, delete_flag %d, prior_page %" ULONGFORMAT")\n",
record_number.getValue(), (int) delete_flag, prior_page); relation->rel_id, record_number.getValue(), (int)delete_flag, pri or_page);
#endif #endif
// Find starting point // Find starting point
ULONG pp_sequence; ULONG pp_sequence;
USHORT slot, line; USHORT slot, line;
record_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, s lot, pp_sequence); record_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, s lot, pp_sequence);
// Find the next pointer page, data page, and record. If the page or // Find the next pointer page, data page, and record. If the page or
// record doesn't exist, or the record isn't a blob, give up and // record doesn't exist, or the record isn't a blob, give up and
skipping to change at line 1569 skipping to change at line 1632
* *
* Functional description * Functional description
* Get the next record in a stream. * Get the next record in a stream.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_READS, VIO_trace(DEBUG_READS,
"DPM_next (record_param %" QUADFORMAT"d)\n", rpb->rpb_number.getV "DPM_next (rel_id %u, record_param %" QUADFORMAT"d)\n",
alue()); relation->rel_id, rpb->rpb_number.getValue());
#endif #endif
WIN* window = &rpb->getWindow(tdbb); WIN* window = &rpb->getWindow(tdbb);
RelationPages* relPages = rpb->rpb_relation->getPages(tdbb); RelationPages* relPages = rpb->rpb_relation->getPages(tdbb);
if (window->win_flags & WIN_large_scan) if (window->win_flags & WIN_large_scan)
{ {
// Try to account for staggered execution of large sequential sca ns. // Try to account for staggered execution of large sequential sca ns.
window->win_scans = rpb->rpb_relation->rel_scan_count - rpb->rpb_ org_scans; window->win_scans = rpb->rpb_relation->rel_scan_count - rpb->rpb_ org_scans;
skipping to change at line 1597 skipping to change at line 1662
// Find starting point // Find starting point
rpb->rpb_number.increment(); rpb->rpb_number.increment();
USHORT slot, line; USHORT slot, line;
ULONG pp_sequence; ULONG pp_sequence;
rpb->rpb_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, slot, pp_sequence); rpb->rpb_number.decompose(dbb->dbb_max_records, dbb->dbb_dp_per_pp, line, slot, pp_sequence);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_READS_INFO, VIO_trace(DEBUG_READS_INFO,
" pointer, slot, and line %d:%d%d\n", pp_sequence, slot, line ); " sequence, slot, and line %" ULONGFORMAT" %" ULONGFORMAT":%d\ n", pp_sequence, slot, line);
#endif #endif
// If I'm a sweeper I don't need to look at swept pages. Also I should // If I'm a sweeper I don't need to look at swept pages. Also I should
// check processed pages if they were swept. // check processed pages if they were swept.
const bool sweeper = (rpb->rpb_stream_flags & RPB_s_sweeper); const bool sweeper = (rpb->rpb_stream_flags & RPB_s_sweeper);
jrd_tra* transaction = tdbb->getTransaction(); jrd_tra* transaction = tdbb->getTransaction();
const TraNumber oldest = transaction ? transaction->tra_oldest : 0; const TraNumber oldest = transaction ? transaction->tra_oldest : 0;
if (sweeper && (pp_sequence || slot) && !line) if (sweeper && (pp_sequence || slot) && !line)
skipping to change at line 1782 skipping to change at line 1847
slot = 0; slot = 0;
line = 0; line = 0;
if (window->win_flags & WIN_large_scan) if (window->win_flags & WIN_large_scan)
CCH_RELEASE_TAIL(tdbb, window); CCH_RELEASE_TAIL(tdbb, window);
else else
CCH_RELEASE(tdbb, window); CCH_RELEASE(tdbb, window);
if (flags & ppg_eof || onepage) if (flags & ppg_eof || onepage)
return false; return false;
if (sweeper)
tdbb->checkCancelState(true);
} }
} }
void DPM_pages(thread_db* tdbb, SSHORT rel_id, int type, ULONG sequence, ULONG p age) void DPM_pages(thread_db* tdbb, SSHORT rel_id, int type, ULONG sequence, ULONG p age)
{ {
/************************************** /**************************************
* *
* D P M _ p a g e s * D P M _ p a g e s
* *
************************************** **************************************
skipping to change at line 1979 skipping to change at line 2047
* Functional description * Functional description
* Store a new record in a relation. If we can put it on a * Store a new record in a relation. If we can put it on a
* specific page, so much the better. * specific page, so much the better.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_store (record_param %" QUADFORMAT"d, stack, type %d)\n", "DPM_store (rel_id %u, record_param %" QUADFORMAT"d, stack, type
rpb->rpb_number.getValue(), type); %d)\n",
relation->rel_id, rpb->rpb_number.getValue(), type);
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record to store %" ULONGFORMAT":%d transaction %" ULONGFORMA T " record to store %" ULONGFORMAT":%d transaction %" ULONGFORMA T
" back %" ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n" , " back %" ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n" ,
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page, rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page,
rpb->rpb_f_line, rpb->rpb_flags); rpb->rpb_f_line, rpb->rpb_flags);
#endif #endif
const Compressor dcc(*tdbb->getDefaultPool(), rpb->rpb_length, rpb->rpb_a ddress); const Compressor dcc(*tdbb->getDefaultPool(), rpb->rpb_length, rpb->rpb_a ddress);
skipping to change at line 2063 skipping to change at line 2132
* *
* Functional description * Functional description
* Store a blob on a data page. Not so hard, all in all. * Store a blob on a data page. Not so hard, all in all.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = blob->blb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_store_blob (blob, record)\n"); "DPM_store_blob (rel_id %u, blob, record)\n",
relation->rel_id);
#endif #endif
// Figure out length of blob on page. Remember that blob can either // Figure out length of blob on page. Remember that blob can either
// be a clump of data or a vector of page pointers. // be a clump of data or a vector of page pointers.
USHORT length; USHORT length;
const UCHAR* q; const UCHAR* q;
PageStack stack; PageStack stack;
Firebird::Array<UCHAR> buffer; Firebird::Array<UCHAR> buffer;
blob->storeToPage(&length, buffer, &q, &stack); blob->storeToPage(&length, buffer, &q, &stack);
skipping to change at line 2130 skipping to change at line 2201
* Functional description * Functional description
* Re-write benign fields in record header. This is mostly used * Re-write benign fields in record header. This is mostly used
* to purge out old versions. * to purge out old versions.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_rewrite_header (record_param %" QUADFORMAT"d)\n", rpb->rpb_n "DPM_rewrite_header (rel_id %u, record_param %" QUADFORMAT"d)\n",
umber.getValue()); relation->rel_id, rpb->rpb_number.getValue());
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record %" ULONGFORMAT":%d\n", rpb->rpb_page, rpb->rpb_line) ; " record %" ULONGFORMAT":%d\n", rpb->rpb_page, rpb->rpb_line) ;
#endif #endif
WIN* window = &rpb->getWindow(tdbb); WIN* window = &rpb->getWindow(tdbb);
data_page* page = (data_page*) window->win_buffer; data_page* page = (data_page*) window->win_buffer;
rhd* header = (rhd*) ((SCHAR *) page + page->dpg_rpt[rpb->rpb_line].dpg_o ffset); rhd* header = (rhd*) ((SCHAR *) page + page->dpg_rpt[rpb->rpb_line].dpg_o ffset);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
skipping to change at line 2182 skipping to change at line 2255
* *
* Functional description * Functional description
* Replace an existing record. * Replace an existing record.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"DPM_update (record_param %" QUADFORMAT"d, stack, transaction %" "DPM_update (rel_id %u, record_param %" QUADFORMAT"d, stack, tran
ULONGFORMAT")\n", saction %" ULONGFORMAT")\n",
rpb->rpb_number.getValue(), transaction ? transaction->tra_number relation->rel_id, rpb->rpb_number.getValue(), transaction ? trans
: 0); action->tra_number : 0);
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back % " " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back % "
ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n", ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page, rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page,
rpb->rpb_f_line, rpb->rpb_flags); rpb->rpb_f_line, rpb->rpb_flags);
#endif #endif
// Mark the page as modified, then figure out the compressed length of th e // Mark the page as modified, then figure out the compressed length of th e
skipping to change at line 2470 skipping to change at line 2544
const ULONG* page1 = blob->blh_page; const ULONG* page1 = blob->blh_page;
const ULONG* const end1 = page1 + (length - BLH_SIZE) / sizeof(ULONG); const ULONG* const end1 = page1 + (length - BLH_SIZE) / sizeof(ULONG);
for (; page1 < end1; page1++) for (; page1 < end1; page1++)
{ {
if (blob->blh_level == 2) if (blob->blh_level == 2)
{ {
window.win_page = *page1; window.win_page = *page1;
blob_page* bpage = (blob_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_blob); blob_page* bpage = (blob_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_blob);
ULONG* page2 = bpage->blp_page; ULONG* page2 = bpage->blp_page;
const ULONG* const end2 = page2 + ((bpage->blp_length - B LP_SIZE) / sizeof(ULONG)); const ULONG* const end2 = page2 + ((bpage->blp_length) / sizeof(ULONG));
while (page2 < end2) while (page2 < end2)
PAG_release_page(tdbb, PageNumber(page_space, *pa ge2++), ZERO_PAGE_NUMBER); PAG_release_page(tdbb, PageNumber(page_space, *pa ge2++), ZERO_PAGE_NUMBER);
CCH_RELEASE_TAIL(tdbb, &window); CCH_RELEASE_TAIL(tdbb, &window);
} }
PAG_release_page(tdbb, PageNumber(page_space, *page1), ZERO_PAGE_ NUMBER); PAG_release_page(tdbb, PageNumber(page_space, *page1), ZERO_PAGE_ NUMBER);
} }
} }
skipping to change at line 2549 skipping to change at line 2623
* In all cases, once the tail is written and safe, we come back to * In all cases, once the tail is written and safe, we come back to
* the head, store the remaining data, fix up the record header and * the head, store the remaining data, fix up the record header and
* everything is done. * everything is done.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_WRITES, VIO_trace(DEBUG_WRITES,
"fragment (record_param %" QUADFORMAT "fragment (rel_id %u, record_param %" QUADFORMAT
"d, available_space %d, dcc, length %d, transaction %" ULONGFORMA T")\n", "d, available_space %d, dcc, length %d, transaction %" ULONGFORMA T")\n",
rpb->rpb_number.getValue(), available_space, length, relation->rel_id, rpb->rpb_number.getValue(), available_space, le ngth,
transaction ? transaction->tra_number : 0); transaction ? transaction->tra_number : 0);
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back % " " record %" ULONGFORMAT":%d transaction %" ULONGFORMAT" back % "
ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n", ULONGFORMAT":%d fragment %" ULONGFORMAT":%d flags %d\n",
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page, rpb->rpb_b_page, rpb->rpb_b_line, rpb->rpb_f_page,
rpb->rpb_f_line, rpb->rpb_flags); rpb->rpb_f_line, rpb->rpb_flags);
#endif #endif
skipping to change at line 2723 skipping to change at line 2798
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
RelationPages* relPages = relation->getPages(tdbb); RelationPages* relPages = relation->getPages(tdbb);
WIN pp_window(relPages->rel_pg_space_id, -1); WIN pp_window(relPages->rel_pg_space_id, -1);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" extend_relation (relation %d, window)\n", relation->rel_id) " extend_relation (relation %d, instance %" SQUADFORMAT", win
; dow)\n",
relation->rel_id, relPages->rel_instance_id);
#endif #endif
// Search pointer pages for an empty slot. // Search pointer pages for an empty slot.
// If we run out of pointer pages, allocate another one. Note that the code below // If we run out of pointer pages, allocate another one. Note that the code below
// is not careful in preventing deadlocks when it allocates a new pointe r page: // is not careful in preventing deadlocks when it allocates a new pointe r page:
// - the last already-existing pointer page is fetched with an exclusiv e latch, // - the last already-existing pointer page is fetched with an exclusiv e latch,
// - allocation of a new pointer page requires the fetching of the PIP page with // - allocation of a new pointer page requires the fetching of the PIP page with
// an exlusive latch. // an exlusive latch.
pointer_page* ppage = NULL; pointer_page* ppage = NULL;
skipping to change at line 3038 skipping to change at line 3114
rpb->rpb_page = window->win_page.getPageNum(); rpb->rpb_page = window->win_page.getPageNum();
rpb->rpb_line = line; rpb->rpb_line = line;
rpb->rpb_flags = header->rhdf_flags; rpb->rpb_flags = header->rhdf_flags;
if (!(rpb->rpb_flags & rpb_fragment)) if (!(rpb->rpb_flags & rpb_fragment))
{ {
rpb->rpb_b_page = header->rhdf_b_page; rpb->rpb_b_page = header->rhdf_b_page;
rpb->rpb_b_line = header->rhdf_b_line; rpb->rpb_b_line = header->rhdf_b_line;
rpb->rpb_transaction_nr = Ods::getTraNum(header); rpb->rpb_transaction_nr = Ods::getTraNum(header);
rpb->rpb_format_number = header->rhdf_format; rpb->rpb_format_number = header->rhdf_format;
if (rpb->rpb_relation->rel_id == 0 /*i.e.RDB$PAGES*/ && rpb->rpb_
transaction_nr != 0)
{
// RDB$PAGES relation should be modified only by system t
ransaction
thread_db* tdbb = JRD_get_thread_data();
CCH_unwind(tdbb, false);
ERR_post(Arg::Gds(isc_bad_db_format) << Arg::Str(tdbb->ge
tAttachment()->att_filename) <<
Arg::Gds(isc_random) << "RDB$PAGES written by non
-system transaction, DB appears damaged");
}
} }
FB_SIZE_T header_size; FB_SIZE_T header_size;
if (rpb->rpb_flags & rpb_incomplete) if (rpb->rpb_flags & rpb_incomplete)
{ {
rpb->rpb_f_page = header->rhdf_f_page; rpb->rpb_f_page = header->rhdf_f_page;
rpb->rpb_f_line = header->rhdf_f_line; rpb->rpb_f_line = header->rhdf_f_line;
header_size = RHDF_SIZE; header_size = RHDF_SIZE;
} }
skipping to change at line 3358 skipping to change at line 3443
* *
* Functional description * Functional description
* Mark a fetched page and its pointer page to indicate the page * Mark a fetched page and its pointer page to indicate the page
* is full. * is full.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
jrd_rel* relation = rpb->rpb_relation;
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_TRACE_ALL, VIO_trace(DEBUG_TRACE_ALL,
"mark_full ()\n"); "mark_full (rel_id %u)\n", relation->rel_id);
#endif #endif
// We need to access the pointer page for write. To avoid deadlocks, // We need to access the pointer page for write. To avoid deadlocks,
// we need to release the data page, fetch the pointer page for write, // we need to release the data page, fetch the pointer page for write,
// and re-fetch the data page. If the data page is still empty, set // and re-fetch the data page. If the data page is still empty, set
// it's "full" bit on the pointer page. // it's "full" bit on the pointer page.
data_page* dpage = (data_page*) rpb->getWindow(tdbb).win_buffer; data_page* dpage = (data_page*) rpb->getWindow(tdbb).win_buffer;
const ULONG sequence = dpage->dpg_sequence; const ULONG sequence = dpage->dpg_sequence;
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb)); CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
jrd_rel* relation = rpb->rpb_relation;
RelationPages* relPages = relation->getPages(tdbb); RelationPages* relPages = relation->getPages(tdbb);
WIN pp_window(relPages->rel_pg_space_id, -1); WIN pp_window(relPages->rel_pg_space_id, -1);
USHORT slot; USHORT slot;
ULONG pp_sequence; ULONG pp_sequence;
DECOMPOSE(sequence, dbb->dbb_dp_per_pp, pp_sequence, slot); DECOMPOSE(sequence, dbb->dbb_dp_per_pp, pp_sequence, slot);
// Fetch the pointer page, then the data page. Since this is a case of // Fetch the pointer page, then the data page. Since this is a case of
// fetching a second page after having fetched the first page with an // fetching a second page after having fetched the first page with an
// exclusive latch, care has to be taken to prevent a deadlock. This // exclusive latch, care has to be taken to prevent a deadlock. This
skipping to change at line 3516 skipping to change at line 3601
* *
* Functional description * Functional description
* Store a new record in a relation. * Store a new record in a relation.
* *
**************************************/ **************************************/
SET_TDBB(tdbb); SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb); CHECK_DBB(dbb);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
jrd_rel* relation = rpb->rpb_relation;
VIO_trace(DEBUG_TRACE_ALL, VIO_trace(DEBUG_TRACE_ALL,
"store_big_record ()\n"); "store_big_record (rel_id %u, record %" SQUADFORMAT")\n",
relation->rel_id, rpb->rpb_number.getValue());
#endif #endif
// Start compression from the end. // Start compression from the end.
const UCHAR* in = rpb->rpb_address + rpb->rpb_length; const UCHAR* in = rpb->rpb_address + rpb->rpb_length;
RelationPages* relPages = rpb->rpb_relation->getPages(tdbb); RelationPages* relPages = rpb->rpb_relation->getPages(tdbb);
PageNumber prior(relPages->rel_pg_space_id, 0); PageNumber prior(relPages->rel_pg_space_id, 0);
signed char count = 0; signed char count = 0;
const USHORT max_data = dbb->dbb_page_size - (static_cast<USHORT>(sizeof( data_page)) + RHDF_SIZE); const USHORT max_data = dbb->dbb_page_size - (static_cast<USHORT>(sizeof( data_page)) + RHDF_SIZE);
skipping to change at line 3593 skipping to change at line 3680
++size; ++size;
if (prior.getPageNum()) if (prior.getPageNum())
CCH_precedence(tdbb, &rpb->getWindow(tdbb), prior); CCH_precedence(tdbb, &rpb->getWindow(tdbb), prior);
#ifdef VIO_DEBUG #ifdef VIO_DEBUG
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" back portion\n"); " back portion\n");
VIO_trace(DEBUG_WRITES_INFO, VIO_trace(DEBUG_WRITES_INFO,
" getWindow(tdbb) page %" ULONGFORMAT " window page %" ULONGFORMAT
", max_data %d, \n\trhdf_flags %d, prior %" ULONGFORMAT"\ n", ", max_data %d, \n\trhdf_flags %d, prior %" ULONGFORMAT"\ n",
rpb->getWindow(tdbb).win_page.getPageNum(), max_data, hea der->rhdf_flags, rpb->getWindow(tdbb).win_page.getPageNum(), max_data, hea der->rhdf_flags,
prior.getPageNum()); prior.getPageNum());
#endif #endif
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb)); CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
prior = rpb->getWindow(tdbb).win_page; prior = rpb->getWindow(tdbb).win_page;
} }
// What's left fits on a page. Luckily, we don't have to store it oursel ves. // What's left fits on a page. Luckily, we don't have to store it oursel ves.
 End of changes. 59 change blocks. 
69 lines changed or deleted 169 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)