mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 03:23:03 +01:00
Style.
This commit is contained in:
parent
bd93c6b125
commit
bb2544fb47
292
src/jrd/dpm.epp
292
src/jrd/dpm.epp
@ -109,7 +109,8 @@ PAG DPM_allocate(thread_db* tdbb, WIN* window)
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf("DPM_allocate (window page %"SLONGFORMAT")\n",
|
||||
window ? window->win_page.getPageNum() : 0);
|
||||
}
|
||||
@ -141,7 +142,8 @@ void DPM_backout( thread_db* tdbb, record_param* rpb)
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
printf("DPM_backout (record_param %"QUADFORMAT"d)\n", rpb->rpb_number.getValue());
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT" back %"
|
||||
SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -162,7 +164,8 @@ void DPM_backout( thread_db* tdbb, record_param* rpb)
|
||||
header->rhd_flags &= ~(rhd_chain | rhd_gc_active);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" old record %"SLONGFORMAT":%d, new record %"SLONGFORMAT
|
||||
":%d, old dpg_count %d, ",
|
||||
@ -173,7 +176,8 @@ void DPM_backout( thread_db* tdbb, record_param* rpb)
|
||||
|
||||
/* Check to see if the index got shorter */
|
||||
USHORT n;
|
||||
for (n = page->dpg_count; --n;) {
|
||||
for (n = page->dpg_count; --n;)
|
||||
{
|
||||
if (page->dpg_rpt[n].dpg_length)
|
||||
break;
|
||||
}
|
||||
@ -218,20 +222,22 @@ double DPM_cardinality(thread_db* tdbb, jrd_rel* relation, const Format* format)
|
||||
SLONG dataPages = DPM_data_pages(tdbb, relation);
|
||||
|
||||
// AB: If we have only 1 data-page then the cardinality calculation
|
||||
// is to worse to be usefull, therefore rely on the record count
|
||||
// is to worse to be useful, therefore rely on the record count
|
||||
// from the data-page.
|
||||
|
||||
if (dataPages == 1)
|
||||
{
|
||||
RelationPages* relPages = relation->getPages(tdbb);
|
||||
vcl* vector = relPages->rel_pages;
|
||||
if (vector) {
|
||||
if (vector)
|
||||
{
|
||||
WIN window(relPages->rel_pg_space_id, (*vector)[0]);
|
||||
Ods::pointer_page* ppage =
|
||||
(Ods::pointer_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_pointer);
|
||||
USHORT recordCount = 0;
|
||||
const SLONG* page = ppage->ppg_page;
|
||||
if (*page) {
|
||||
if (*page)
|
||||
{
|
||||
Ods::data_page* dpage =
|
||||
(Ods::data_page*) CCH_HANDOFF(tdbb, &window, *page, LCK_read, pag_data);
|
||||
recordCount = dpage->dpg_count;
|
||||
@ -277,12 +283,14 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES) {
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
printf("DPM_chain (org_rpb %"QUADFORMAT"d, new_rpb %"
|
||||
QUADFORMAT"d)\n", org_rpb->rpb_number.getValue(),
|
||||
new_rpb ? new_rpb->rpb_number.getValue() : 0);
|
||||
}
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" org record %"SLONGFORMAT":%d transaction %"SLONGFORMAT
|
||||
" back %"SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -290,7 +298,8 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
org_rpb->rpb_b_page, org_rpb->rpb_b_line, org_rpb->rpb_f_page,
|
||||
org_rpb->rpb_f_line, org_rpb->rpb_flags);
|
||||
|
||||
if (new_rpb) {
|
||||
if (new_rpb)
|
||||
{
|
||||
printf(" new record length %d transaction %"SLONGFORMAT
|
||||
" flags %d\n",
|
||||
new_rpb->rpb_length, new_rpb->rpb_transaction_nr,
|
||||
@ -303,7 +312,8 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
DataComprControl dcc(*tdbb->getDefaultPool());
|
||||
const USHORT size = SQZ_length((SCHAR*) new_rpb->rpb_address, (int) new_rpb->rpb_length, &dcc);
|
||||
|
||||
if (!DPM_get(tdbb, org_rpb, LCK_write)) {
|
||||
if (!DPM_get(tdbb, org_rpb, LCK_write))
|
||||
{
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
printf(" record not found in DPM_chain\n");
|
||||
@ -329,7 +339,8 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
if ((org_rpb->rpb_flags & rpb_delta) && temp.rpb_prior) {
|
||||
org_rpb->rpb_prior = temp.rpb_prior;
|
||||
}
|
||||
else if (org_rpb->rpb_flags & rpb_delta) {
|
||||
else if (org_rpb->rpb_flags & rpb_delta)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &org_rpb->getWindow(tdbb));
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
@ -342,7 +353,8 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
|
||||
/* If the record obviously isn't going to fit, don't even try */
|
||||
|
||||
if (size > dbb->dbb_page_size - (sizeof(data_page) + RHD_SIZE)) {
|
||||
if (size > dbb->dbb_page_size - (sizeof(data_page) + RHD_SIZE))
|
||||
{
|
||||
CCH_RELEASE(tdbb, &org_rpb->getWindow(tdbb));
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
@ -378,20 +390,23 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
slot = n;
|
||||
}
|
||||
SSHORT offset;
|
||||
if (index->dpg_length && (offset = index->dpg_offset)) {
|
||||
if (index->dpg_length && (offset = index->dpg_offset))
|
||||
{
|
||||
available -= ROUNDUP(index->dpg_length, ODS_ALIGNMENT);
|
||||
space = MIN(space, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == page->dpg_count) {
|
||||
if (slot == page->dpg_count)
|
||||
{
|
||||
top += sizeof(data_page::dpg_repeat);
|
||||
available -= sizeof(data_page::dpg_repeat);
|
||||
}
|
||||
|
||||
/* If the record doesn't fit, punt */
|
||||
|
||||
if (length > available) {
|
||||
if (length > available)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &org_rpb->getWindow(tdbb));
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
@ -414,8 +429,7 @@ bool DPM_chain( thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
|
||||
++page->dpg_count;
|
||||
}
|
||||
|
||||
/* Swap the old record into the new slot and the new record into
|
||||
the old slot */
|
||||
/* Swap the old record into the new slot and the new record into the old slot */
|
||||
|
||||
new_rpb->rpb_b_page = new_rpb->rpb_page = org_rpb->rpb_page;
|
||||
new_rpb->rpb_b_line = slot;
|
||||
@ -549,7 +563,8 @@ void DPM_create_relation_pages(thread_db* tdbb, jrd_rel* relation, RelationPages
|
||||
|
||||
/* If this is relation 0 (RDB$PAGES), update the header */
|
||||
|
||||
if (relation->rel_id == 0) {
|
||||
if (relation->rel_id == 0)
|
||||
{
|
||||
WIN root_window(HEADER_PAGE_NUMBER);
|
||||
header_page* header = (header_page*) CCH_FETCH(tdbb, &root_window, LCK_write, pag_header);
|
||||
CCH_MARK(tdbb, &root_window);
|
||||
@ -560,7 +575,8 @@ void DPM_create_relation_pages(thread_db* tdbb, jrd_rel* relation, RelationPages
|
||||
|
||||
/* Keep track in memory of the first pointer page */
|
||||
|
||||
if (!relPages->rel_pages) {
|
||||
if (!relPages->rel_pages)
|
||||
{
|
||||
vcl* vector = vcl::newVector(*dbb->dbb_permanent, 1);
|
||||
relPages->rel_pages = vector;
|
||||
}
|
||||
@ -609,13 +625,15 @@ SLONG DPM_data_pages(thread_db* tdbb, jrd_rel* relation)
|
||||
{
|
||||
const pointer_page* ppage =
|
||||
get_pointer_page(tdbb, relation, relPages, &window, sequence, LCK_read);
|
||||
if (!ppage) {
|
||||
if (!ppage)
|
||||
{
|
||||
BUGCHECK(243);
|
||||
/* msg 243 missing pointer page in DPM_data_pages */
|
||||
}
|
||||
const SLONG* page = ppage->ppg_page;
|
||||
const SLONG* const end_page = page + ppage->ppg_count;
|
||||
while (page < end_page) {
|
||||
while (page < end_page)
|
||||
{
|
||||
if (*page++) {
|
||||
pages++;
|
||||
}
|
||||
@ -662,11 +680,13 @@ void DPM_delete( thread_db* tdbb, record_param* rpb, SLONG prior_page)
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES) {
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
printf("DPM_delete (record_param %"QUADFORMAT", prior_page %"SLONGFORMAT")\n",
|
||||
rpb->rpb_number.getValue(), prior_page);
|
||||
}
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT" back %"
|
||||
SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -682,15 +702,15 @@ void DPM_delete( thread_db* tdbb, record_param* rpb, SLONG prior_page)
|
||||
data_page::dpg_repeat* index = &page->dpg_rpt[rpb->rpb_line];
|
||||
const RecordNumber number = rpb->rpb_number;
|
||||
|
||||
if (!get_header(window, rpb->rpb_line, rpb)) {
|
||||
if (!get_header(window, rpb->rpb_line, rpb))
|
||||
{
|
||||
CCH_RELEASE(tdbb, window);
|
||||
BUGCHECK(244); /* msg 244 Fragment does not exist */
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
printf(" record length as stored in record header: %d\n",
|
||||
rpb->rpb_length);
|
||||
printf(" record length as stored in record header: %d\n", rpb->rpb_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -715,7 +735,8 @@ void DPM_delete( thread_db* tdbb, record_param* rpb, SLONG prior_page)
|
||||
/* If the page is not empty and used to be marked as full, change the
|
||||
state of both the page and the appropriate pointer page. */
|
||||
|
||||
if (count && (page->dpg_header.pag_flags & dpg_full)) {
|
||||
if (count && (page->dpg_header.pag_flags & dpg_full))
|
||||
{
|
||||
DEBUG
|
||||
page->dpg_header.pag_flags &= ~dpg_full;
|
||||
mark_full(tdbb, rpb);
|
||||
@ -735,7 +756,8 @@ void DPM_delete( thread_db* tdbb, record_param* rpb, SLONG prior_page)
|
||||
if (count)
|
||||
return;
|
||||
|
||||
if (flags & dpg_orphan) {
|
||||
if (flags & dpg_orphan)
|
||||
{
|
||||
/* The page inventory page will be written after the page being
|
||||
released, which will be written after the pages from which earlier
|
||||
fragments were deleted, which will be written after the page from
|
||||
@ -775,11 +797,13 @@ retry_after_latch_timeout:
|
||||
exclusive access, put a timeout on this fetch to be able to recover from
|
||||
possible deadlocks. */
|
||||
page = (data_page*) CCH_FETCH_TIMEOUT(tdbb, window, LCK_write, pag_data, -1);
|
||||
if (!page) {
|
||||
if (!page)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &pwindow);
|
||||
goto retry_after_latch_timeout;
|
||||
}
|
||||
if (page->dpg_count) {
|
||||
if (page->dpg_count)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &pwindow);
|
||||
CCH_RELEASE(tdbb, window);
|
||||
return;
|
||||
@ -789,7 +813,8 @@ retry_after_latch_timeout:
|
||||
pointer to the data page then release the page. */
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
("\tDPM_delete: page %"SLONGFORMAT
|
||||
" is empty and about to be released from relation %d\n",
|
||||
@ -970,13 +995,15 @@ bool DPM_fetch(thread_db* tdbb, record_param* rpb, USHORT lock)
|
||||
rpb->getWindow(tdbb).win_page = PageNumber(relPages->rel_pg_space_id, rpb->rpb_page);
|
||||
CCH_FETCH(tdbb, &rpb->getWindow(tdbb), lock, pag_data);
|
||||
|
||||
if (!get_header(&rpb->getWindow(tdbb), rpb->rpb_line, rpb)) {
|
||||
if (!get_header(&rpb->getWindow(tdbb), rpb->rpb_line, rpb))
|
||||
{
|
||||
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_READS_INFO) {
|
||||
if (debug_flag > DEBUG_READS_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT" back %"
|
||||
SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -1093,7 +1120,8 @@ void DPM_fetch_fragment( thread_db* tdbb, record_param* rpb, USHORT lock)
|
||||
if (debug_flag > DEBUG_READS)
|
||||
printf("DPM_fetch_fragment (record_param %"QUADFORMAT"d, lock %d)\n",
|
||||
rpb->rpb_number.getValue(), lock);
|
||||
if (debug_flag > DEBUG_READS_INFO) {
|
||||
if (debug_flag > DEBUG_READS_INFO)
|
||||
{
|
||||
printf(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT
|
||||
" back %"SLONGFORMAT":%d\n",
|
||||
rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr,
|
||||
@ -1106,13 +1134,15 @@ void DPM_fetch_fragment( thread_db* tdbb, record_param* rpb, USHORT lock)
|
||||
rpb->rpb_line = rpb->rpb_f_line;
|
||||
CCH_HANDOFF(tdbb, &rpb->getWindow(tdbb), rpb->rpb_page, lock, pag_data);
|
||||
|
||||
if (!get_header(&rpb->getWindow(tdbb), rpb->rpb_line, rpb)) {
|
||||
if (!get_header(&rpb->getWindow(tdbb), rpb->rpb_line, rpb))
|
||||
{
|
||||
CCH_RELEASE(tdbb, &rpb->getWindow(tdbb));
|
||||
BUGCHECK(248); /* msg 248 cannot find record fragment */
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_READS_INFO) {
|
||||
if (debug_flag > DEBUG_READS_INFO)
|
||||
{
|
||||
printf
|
||||
(" record fetched %"SLONGFORMAT":%d transaction %"SLONGFORMAT
|
||||
" back %"SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -1144,9 +1174,9 @@ SINT64 DPM_gen_id(thread_db* tdbb, SLONG generator, bool initialize, SINT64 val)
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_TRACE_ALL) {
|
||||
printf("DPM_gen_id (generator %"SLONGFORMAT", val %" QUADFORMAT "d)\n",
|
||||
generator, val);
|
||||
if (debug_flag > DEBUG_TRACE_ALL)
|
||||
{
|
||||
printf("DPM_gen_id (generator %"SLONGFORMAT", val %" QUADFORMAT "d)\n", generator, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1201,7 +1231,8 @@ SINT64 DPM_gen_id(thread_db* tdbb, SLONG generator, bool initialize, SINT64 val)
|
||||
|
||||
if (val || initialize)
|
||||
{
|
||||
if (dbb->dbb_flags & DBB_read_only) {
|
||||
if (dbb->dbb_flags & DBB_read_only)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &window);
|
||||
ERR_post(Arg::Gds(isc_read_only_database));
|
||||
}
|
||||
@ -1213,7 +1244,8 @@ SINT64 DPM_gen_id(thread_db* tdbb, SLONG generator, bool initialize, SINT64 val)
|
||||
* decided that the V6 engine would only access an ODS-10 database.
|
||||
* (and uncommented 2000-05-05, also by ChrisJ, when minds changed.)
|
||||
*/
|
||||
if (dbb->dbb_ods_version >= ODS_VERSION10) {
|
||||
if (dbb->dbb_ods_version >= ODS_VERSION10)
|
||||
{
|
||||
if (initialize) {
|
||||
*ptr = val;
|
||||
}
|
||||
@ -1273,7 +1305,8 @@ bool DPM_get( thread_db* tdbb, record_param* rpb, SSHORT lock_type)
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_READS) {
|
||||
if (debug_flag > DEBUG_READS)
|
||||
{
|
||||
printf("DPM_get (record_param %"QUADFORMAT"d, lock type %d)\n",
|
||||
rpb->rpb_number.getValue(), lock_type);
|
||||
}
|
||||
@ -1305,7 +1338,8 @@ bool DPM_get( thread_db* tdbb, record_param* rpb, SSHORT lock_type)
|
||||
#endif
|
||||
|
||||
const SLONG page_number = page->ppg_page[slot];
|
||||
if (page_number) {
|
||||
if (page_number)
|
||||
{
|
||||
CCH_HANDOFF(tdbb, window, page_number, lock_type, pag_data);
|
||||
if (get_header(window, line, rpb) &&
|
||||
!(rpb->rpb_flags & (rpb_blob | rpb_chained | rpb_fragment)))
|
||||
@ -1348,7 +1382,8 @@ ULONG DPM_get_blob(thread_db* tdbb,
|
||||
rpb.getWindow(tdbb).win_flags = WIN_secondary;
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_READS) {
|
||||
if (debug_flag > DEBUG_READS)
|
||||
{
|
||||
printf
|
||||
("DPM_get_blob (blob, record_number %"QUADFORMAT
|
||||
"d, delete_flag %d, prior_page %"SLONGFORMAT")\n",
|
||||
@ -1368,7 +1403,8 @@ ULONG DPM_get_blob(thread_db* tdbb,
|
||||
|
||||
pointer_page* ppage = get_pointer_page(tdbb, blob->blb_relation,
|
||||
blob->blb_relation->getPages(tdbb), &rpb.getWindow(tdbb), pp_sequence, LCK_read);
|
||||
if (!ppage) {
|
||||
if (!ppage)
|
||||
{
|
||||
blob->blb_flags |= BLB_damaged;
|
||||
return 0UL;
|
||||
}
|
||||
@ -1446,12 +1482,14 @@ ULONG DPM_get_blob(thread_db* tdbb,
|
||||
const USHORT length = index->dpg_length - BLH_SIZE;
|
||||
const UCHAR* q = (UCHAR *) header->blh_page;
|
||||
|
||||
if (blob->blb_level == 0) {
|
||||
if (blob->blb_level == 0)
|
||||
{
|
||||
blob->blb_space_remaining = length;
|
||||
if (length)
|
||||
memcpy(blob->getBuffer(), q, length);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
vcl* vector = blob->blb_pages;
|
||||
if (!vector) {
|
||||
vector = blob->blb_pages = vcl::newVector(*blob->blb_transaction->tra_pool, 0);
|
||||
@ -1460,7 +1498,8 @@ ULONG DPM_get_blob(thread_db* tdbb,
|
||||
memcpy(vector->memPtr(), q, length);
|
||||
}
|
||||
|
||||
if (!delete_flag) {
|
||||
if (!delete_flag)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &rpb.getWindow(tdbb));
|
||||
return 0UL;
|
||||
}
|
||||
@ -1511,7 +1550,8 @@ bool DPM_next(thread_db* tdbb,
|
||||
WIN* window = &rpb->getWindow(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 scans. */
|
||||
|
||||
window->win_scans = rpb->rpb_relation->rel_scan_count - rpb->rpb_org_scans;
|
||||
@ -1536,11 +1576,11 @@ bool DPM_next(thread_db* tdbb,
|
||||
{
|
||||
/* if the stream was just opened, assume we want to start
|
||||
at the end of the stream, so compute the last theoretically
|
||||
possible rpb_number and go down from there */
|
||||
/** for now, we must force a scan to make sure that we get
|
||||
possible rpb_number and go down from there.
|
||||
For now, we must force a scan to make sure that we get
|
||||
the last pointer page: this should be changed to use
|
||||
a coordination mechanism (probably using a shared lock)
|
||||
to keep apprised of when a pointer page gets added **/
|
||||
to keep apprised of when a pointer page gets added */
|
||||
|
||||
DPM_scan_pages(tdbb);
|
||||
const vcl* vector = relPages->rel_pages;
|
||||
@ -1564,8 +1604,7 @@ bool DPM_next(thread_db* tdbb,
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_READS_INFO) {
|
||||
printf(" pointer, slot, and line %d:%d%d\n", pp_sequence, slot,
|
||||
line);
|
||||
printf(" pointer, slot, and line %d:%d%d\n", pp_sequence, slot, line);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1670,13 +1709,15 @@ bool DPM_next(thread_db* tdbb,
|
||||
}
|
||||
}
|
||||
|
||||
if (onepage) {
|
||||
if (onepage)
|
||||
{
|
||||
CCH_RELEASE(tdbb, window);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SCROLLABLE_CURSORS
|
||||
if (backwards) {
|
||||
if (backwards)
|
||||
{
|
||||
slot--;
|
||||
line = dbb->dbb_max_records - 1;
|
||||
}
|
||||
@ -1690,7 +1731,8 @@ bool DPM_next(thread_db* tdbb,
|
||||
|
||||
const UCHAR flags = ppage->ppg_header.pag_flags;
|
||||
#ifdef SCROLLABLE_CURSORS
|
||||
if (backwards) {
|
||||
if (backwards)
|
||||
{
|
||||
pp_sequence--;
|
||||
slot = ppage->ppg_count - 1;
|
||||
line = dbb->dbb_max_records - 1;
|
||||
@ -1732,10 +1774,10 @@ void DPM_pages(thread_db* tdbb, SSHORT rel_id, int type, ULONG sequence, SLONG p
|
||||
Database* dbb = tdbb->getDatabase();
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_TRACE_ALL) {
|
||||
printf("DPM_pages (rel_id %d, type %d, sequence %"ULONGFORMAT
|
||||
", page %"SLONGFORMAT")\n", rel_id, type, sequence
|
||||
, page);
|
||||
if (debug_flag > DEBUG_TRACE_ALL)
|
||||
{
|
||||
printf("DPM_pages (rel_id %d, type %d, sequence %"ULONGFORMAT", page %"SLONGFORMAT")\n",
|
||||
rel_id, type, sequence, page);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1796,7 +1838,8 @@ SLONG DPM_prefetch_bitmap(thread_db* tdbb, jrd_rel* relation, PageBitmap* bitmap
|
||||
DECOMPOSE(dp_sequence, dbb->dbb_dp_per_pp, pp_sequence, slot);
|
||||
|
||||
const pointer_page* ppage = get_pointer_page(tdbb, relation, &window, pp_sequence, LCK_read);
|
||||
if (!ppage) {
|
||||
if (!ppage)
|
||||
{
|
||||
BUGCHECK(249);
|
||||
/* msg 249 pointer page vanished from DPM_prefetch_bitmap */
|
||||
}
|
||||
@ -1851,7 +1894,8 @@ void DPM_scan_pages( thread_db* tdbb)
|
||||
WIN window(relPages->rel_pg_space_id, (*vector)[sequence]);
|
||||
pointer_page* ppage = (pointer_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_pointer);
|
||||
|
||||
while (ppage->ppg_next) {
|
||||
while (ppage->ppg_next)
|
||||
{
|
||||
++sequence;
|
||||
vector->resize(sequence + 1);
|
||||
(*vector)[sequence] = ppage->ppg_next;
|
||||
@ -1917,11 +1961,13 @@ void DPM_store( thread_db* tdbb, record_param* rpb, PageStack& stack, USHORT typ
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES) {
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
printf("DPM_store (record_param %"QUADFORMAT"d, stack, type %d)\n",
|
||||
rpb->rpb_number.getValue(), type);
|
||||
}
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record to store %"SLONGFORMAT":%d transaction %"SLONGFORMAT
|
||||
" back %"SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -1937,7 +1983,8 @@ void DPM_store( thread_db* tdbb, record_param* rpb, PageStack& stack, USHORT typ
|
||||
/* If the record isn't going to fit on a page, even if fragmented,
|
||||
handle it a little differently. */
|
||||
|
||||
if (size > dbb->dbb_page_size - (sizeof(data_page) + RHD_SIZE)) {
|
||||
if (size > dbb->dbb_page_size - (sizeof(data_page) + RHD_SIZE))
|
||||
{
|
||||
store_big_record(tdbb, rpb, stack, &dcc, size);
|
||||
return;
|
||||
}
|
||||
@ -1960,7 +2007,8 @@ void DPM_store( thread_db* tdbb, record_param* rpb, PageStack& stack, USHORT typ
|
||||
SQZ_fast(&dcc, (SCHAR*) rpb->rpb_address, (SCHAR*) header->rhd_data);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d, length %"SLONGFORMAT
|
||||
", rpb_flags %d, f_page %"SLONGFORMAT":%d, b_page %"SLONGFORMAT
|
||||
@ -2077,7 +2125,8 @@ RecordNumber DPM_store_blob(thread_db* tdbb, blb* blob, Record* record)
|
||||
memcpy(header->blh_page, q, length);
|
||||
|
||||
data_page* page = (data_page*) rpb.getWindow(tdbb).win_buffer;
|
||||
if (blob->blb_level && !(page->dpg_header.pag_flags & dpg_large)) {
|
||||
if (blob->blb_level && !(page->dpg_header.pag_flags & dpg_large))
|
||||
{
|
||||
page->dpg_header.pag_flags |= dpg_large;
|
||||
mark_full(tdbb, &rpb);
|
||||
}
|
||||
@ -2118,7 +2167,8 @@ void DPM_rewrite_header( thread_db* tdbb, record_param* rpb)
|
||||
rhd* header = (rhd*) ((SCHAR *) page + page->dpg_rpt[rpb->rpb_line].dpg_offset);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" old flags %d, old transaction %"SLONGFORMAT
|
||||
", old format %d, old back record %"SLONGFORMAT":%d\n",
|
||||
@ -2158,11 +2208,13 @@ void DPM_update( thread_db* tdbb, record_param* rpb, PageStack* stack,
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES) {
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
printf("DPM_update (record_param %"QUADFORMAT"d, stack, transaction %"SLONGFORMAT")\n",
|
||||
rpb->rpb_number.getValue(), transaction ? transaction->tra_number : 0);
|
||||
}
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT" back %"
|
||||
SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -2213,13 +2265,15 @@ void DPM_update( thread_db* tdbb, record_param* rpb, PageStack* stack,
|
||||
for (const data_page::dpg_repeat* const end = index + page->dpg_count; index < end; index++)
|
||||
{
|
||||
const SSHORT offset = index->dpg_offset;
|
||||
if (offset) {
|
||||
if (offset)
|
||||
{
|
||||
available -= ROUNDUP(index->dpg_length, ODS_ALIGNMENT);
|
||||
space = MIN(space, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (length > available) {
|
||||
if (length > available)
|
||||
{
|
||||
fragment(tdbb, rpb, available, &dcc, old_length, transaction);
|
||||
return;
|
||||
}
|
||||
@ -2242,7 +2296,8 @@ void DPM_update( thread_db* tdbb, record_param* rpb, PageStack* stack,
|
||||
SQZ_fast(&dcc, (SCHAR*) rpb->rpb_address, (SCHAR*) header->rhd_data);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT
|
||||
":%d, dpg_length %d, rpb_flags %d, rpb_f record %"SLONGFORMAT
|
||||
@ -2279,7 +2334,8 @@ static void delete_tail(thread_db* tdbb, rhdf* header, const USHORT page_space,
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
printf("delete_tail (header, length)\n");
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" transaction %"SLONGFORMAT" flags %d fragment %"
|
||||
SLONGFORMAT":%d back %"SLONGFORMAT":%d\n",
|
||||
header->rhdf_transaction, header->rhdf_flags,
|
||||
@ -2403,7 +2459,8 @@ static void fragment(thread_db* tdbb,
|
||||
CHECK_DBB(dbb);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES) {
|
||||
if (debug_flag > DEBUG_WRITES)
|
||||
{
|
||||
printf
|
||||
("fragment (record_param %"QUADFORMAT
|
||||
"d, available_space %d, dcc, length %d, transaction %"
|
||||
@ -2411,7 +2468,8 @@ static void fragment(thread_db* tdbb,
|
||||
rpb->rpb_number.getValue(), available_space, length,
|
||||
transaction ? transaction->tra_number : 0);
|
||||
}
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" record %"SLONGFORMAT":%d transaction %"SLONGFORMAT" back %"
|
||||
SLONGFORMAT":%d fragment %"SLONGFORMAT":%d flags %d\n",
|
||||
@ -2443,12 +2501,14 @@ static void fragment(thread_db* tdbb,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rpb->rpb_flags & rpb_delta) {
|
||||
if (rpb->rpb_flags & rpb_delta)
|
||||
{
|
||||
header = (rhdf*) ((SCHAR *) page + page->dpg_rpt[line].dpg_offset);
|
||||
header->rhdf_flags |= rpb_delta;
|
||||
page->dpg_rpt[line].dpg_length = available_space = length;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
const SSHORT space = DPM_compress(tdbb, page) - available_space;
|
||||
header = (rhdf*) ((SCHAR *) page + space);
|
||||
header->rhdf_flags = rhd_deleted;
|
||||
@ -2462,7 +2522,8 @@ static void fragment(thread_db* tdbb,
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf
|
||||
(" rhdf_transaction %"SLONGFORMAT", window record %"SLONGFORMAT
|
||||
":%d, available_space %d, rhdf_flags %d, rhdf_f record %"
|
||||
@ -2514,7 +2575,8 @@ static void fragment(thread_db* tdbb,
|
||||
header->rhdf_f_page = tail_rpb.rpb_page;
|
||||
header->rhdf_f_line = tail_rpb.rpb_line;
|
||||
|
||||
if (transaction->tra_number != rpb->rpb_transaction_nr) {
|
||||
if (transaction->tra_number != rpb->rpb_transaction_nr)
|
||||
{
|
||||
header->rhdf_b_page = rpb->rpb_b_page;
|
||||
header->rhdf_b_line = rpb->rpb_b_line;
|
||||
}
|
||||
@ -2525,7 +2587,8 @@ static void fragment(thread_db* tdbb,
|
||||
(int) (available_space - RHDF_SIZE));
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" fragment head \n");
|
||||
printf
|
||||
(" rhdf_trans %"SLONGFORMAT", window record %"SLONGFORMAT
|
||||
@ -2538,7 +2601,8 @@ static void fragment(thread_db* tdbb,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pre_header_length != post_header_length) {
|
||||
if (pre_header_length != post_header_length)
|
||||
{
|
||||
CCH_RELEASE(tdbb, window);
|
||||
BUGCHECK(252); /* msg 252 header fragment length changed */
|
||||
}
|
||||
@ -2571,8 +2635,7 @@ static void extend_relation( thread_db* tdbb, jrd_rel* relation, WIN * window)
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
printf(" extend_relation (relation %d, window)\n",
|
||||
relation->rel_id);
|
||||
printf(" extend_relation (relation %d, window)\n", relation->rel_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2605,7 +2668,8 @@ static void extend_relation( thread_db* tdbb, jrd_rel* relation, WIN * window)
|
||||
BUGCHECK(253); /* msg 253 pointer page vanished from extend_relation */
|
||||
}
|
||||
SLONG* slots = ppage->ppg_page;
|
||||
for (slot = 0; slot < ppage->ppg_count; slot++, slots++) {
|
||||
for (slot = 0; slot < ppage->ppg_count; slot++, slots++)
|
||||
{
|
||||
if (*slots == 0) {
|
||||
break;
|
||||
}
|
||||
@ -2667,7 +2731,8 @@ static void extend_relation( thread_db* tdbb, jrd_rel* relation, WIN * window)
|
||||
|
||||
/* In the case of a timeout, retry the whole thing. */
|
||||
|
||||
if (!dpage) {
|
||||
if (!dpage)
|
||||
{
|
||||
CCH_RELEASE(tdbb, &pp_window);
|
||||
goto retry_after_latch_timeout;
|
||||
}
|
||||
@ -2696,7 +2761,8 @@ static void extend_relation( thread_db* tdbb, jrd_rel* relation, WIN * window)
|
||||
CCH_HANDOFF(tdbb, window, ppage->ppg_page[slot], LCK_write, pag_data);
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" extended_relation (relation %d, window_page %"SLONGFORMAT")\n",
|
||||
relation->rel_id, window->win_page.getPageNum());
|
||||
}
|
||||
@ -2772,7 +2838,8 @@ static UCHAR* find_space(thread_db* tdbb,
|
||||
|
||||
/* If there isn't space, give up */
|
||||
|
||||
if (aligned_size > (int) dbb->dbb_page_size - used) {
|
||||
if (aligned_size > (int) dbb->dbb_page_size - used)
|
||||
{
|
||||
CCH_MARK(tdbb, &rpb->getWindow(tdbb));
|
||||
page->dpg_header.pag_flags |= dpg_full;
|
||||
mark_full(tdbb, rpb);
|
||||
@ -2842,20 +2909,23 @@ static bool get_header( WIN * window, SSHORT line, record_param* rpb)
|
||||
rpb->rpb_line = line;
|
||||
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_line = header->rhdf_b_line;
|
||||
rpb->rpb_transaction_nr = header->rhdf_transaction;
|
||||
rpb->rpb_format_number = header->rhdf_format;
|
||||
}
|
||||
|
||||
if (rpb->rpb_flags & rpb_incomplete) {
|
||||
if (rpb->rpb_flags & rpb_incomplete)
|
||||
{
|
||||
rpb->rpb_f_page = header->rhdf_f_page;
|
||||
rpb->rpb_f_line = header->rhdf_f_line;
|
||||
rpb->rpb_address = header->rhdf_data;
|
||||
rpb->rpb_length = index->dpg_length - RHDF_SIZE;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
rpb->rpb_address = ((rhd*) header)->rhd_data;
|
||||
rpb->rpb_length = index->dpg_length - RHD_SIZE;
|
||||
}
|
||||
@ -2977,7 +3047,8 @@ static rhd* locate_space(thread_db* tdbb,
|
||||
relPages->rel_data_space = pp_sequence;
|
||||
const pointer_page* ppage =
|
||||
get_pointer_page(tdbb, relation, relPages, window, pp_sequence, LCK_read);
|
||||
if (!ppage) {
|
||||
if (!ppage)
|
||||
{
|
||||
BUGCHECK(254);
|
||||
/* msg 254 pointer page vanished from relation list in locate_space */
|
||||
}
|
||||
@ -3027,7 +3098,8 @@ static rhd* locate_space(thread_db* tdbb,
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" extended relation %d with page %"SLONGFORMAT" to get %d bytes\n",
|
||||
relation->rel_id, window->win_page.getPageNum(), size);
|
||||
}
|
||||
@ -3087,8 +3159,7 @@ static void mark_full( thread_db* tdbb, record_param* rpb)
|
||||
if (!ppage)
|
||||
BUGCHECK(256); /* msg 256 pointer page vanished from mark_full */
|
||||
|
||||
/* If data page has been deleted from relation then there's nothing
|
||||
left to do. */
|
||||
/* If data page has been deleted from relation then there's nothing left to do. */
|
||||
if (slot >= ppage->ppg_count ||
|
||||
rpb->getWindow(tdbb).win_page.getPageNum() != ppage->ppg_page[slot])
|
||||
{
|
||||
@ -3115,11 +3186,13 @@ static void mark_full( thread_db* tdbb, record_param* rpb)
|
||||
UCHAR bit = 1 << ((slot & 3) << 1);
|
||||
UCHAR* byte = (UCHAR *) (&ppage->ppg_page[dbb->dbb_dp_per_pp]) + (slot >> 2);
|
||||
|
||||
if (flags & dpg_full) {
|
||||
if (flags & dpg_full)
|
||||
{
|
||||
*byte |= bit;
|
||||
ppage->ppg_min_space = MAX(slot + 1, ppage->ppg_min_space);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
*byte &= ~bit;
|
||||
ppage->ppg_min_space = MIN(slot, ppage->ppg_min_space);
|
||||
relPages->rel_data_space = MIN(pp_sequence, relPages->rel_data_space);
|
||||
@ -3172,8 +3245,7 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
SCHAR count = 0;
|
||||
const USHORT max_data = dbb->dbb_page_size - (sizeof(data_page) + RHDF_SIZE);
|
||||
|
||||
/* Fill up data pages tail first until what's left fits on a single
|
||||
page. */
|
||||
/* Fill up data pages tail first until what's left fits on a single page. */
|
||||
|
||||
while (size > max_data)
|
||||
{
|
||||
@ -3211,7 +3283,8 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((count = *--control) < 0) {
|
||||
if ((count = *--control) < 0)
|
||||
{
|
||||
*--out = in[-1];
|
||||
*--out = count;
|
||||
in += count;
|
||||
@ -3221,7 +3294,8 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
|
||||
/* Page is full. If there is an odd byte left, fudge it. */
|
||||
|
||||
if (length) {
|
||||
if (length)
|
||||
{
|
||||
*--out = 0;
|
||||
++size;
|
||||
}
|
||||
@ -3233,7 +3307,8 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
}
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" back portion\n");
|
||||
printf
|
||||
(" getWindow(tdbb) page %"SLONGFORMAT
|
||||
@ -3247,8 +3322,7 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
prior = rpb->getWindow(tdbb).win_page;
|
||||
}
|
||||
|
||||
/* What's left fits on a page. Luckily, we don't have to store it
|
||||
ourselves. */
|
||||
/* What's left fits on a page. Luckily, we don't have to store it ourselves. */
|
||||
|
||||
size = SQZ_length((SCHAR*) rpb->rpb_address, in - (SCHAR*) rpb->rpb_address, dcc);
|
||||
rhdf* header = (rhdf*)locate_space(tdbb, rpb, (SSHORT)(RHDF_SIZE + size), stack, NULL, DPM_other);
|
||||
@ -3265,7 +3339,8 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
data_page* page = (data_page*) rpb->getWindow(tdbb).win_buffer;
|
||||
|
||||
#ifdef VIO_DEBUG
|
||||
if (debug_flag > DEBUG_WRITES_INFO) {
|
||||
if (debug_flag > DEBUG_WRITES_INFO)
|
||||
{
|
||||
printf(" front part\n");
|
||||
printf
|
||||
(" rhdf_trans %"SLONGFORMAT", rpb_window record %"SLONGFORMAT
|
||||
@ -3278,7 +3353,8 @@ static void store_big_record(thread_db* tdbb, record_param* rpb,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(page->dpg_header.pag_flags & dpg_large)) {
|
||||
if (!(page->dpg_header.pag_flags & dpg_large))
|
||||
{
|
||||
page->dpg_header.pag_flags |= dpg_large;
|
||||
mark_full(tdbb, rpb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user