Skip to content

Commit

Permalink
Frontported CORE-3295: Estimate the actual record compression ratio i…
Browse files Browse the repository at this point in the history
…n the optimizer. It was somehow forgotten and never found its way into newer versions :-(
  • Loading branch information
dyemanov committed Nov 28, 2017
1 parent 576b134 commit b5dc562
Showing 1 changed file with 59 additions and 29 deletions.
88 changes: 59 additions & 29 deletions src/jrd/dpm.epp
Expand Up @@ -232,53 +232,83 @@ double DPM_cardinality(thread_db* tdbb, jrd_rel* relation, const Format* format)
*
**************************************/
SET_TDBB(tdbb);
Database* 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)
Database* const dbb = tdbb->getDatabase();

USHORT minRecordSize = static_cast<USHORT>(sizeof(Ods::data_page::dpg_repeat) + 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);

// AB: If we have only 1 data-page then the cardinality calculation
// is to worse to be useful, therefore rely on the record count
// from the data-page.
// Calculate record count and total compressed record length
// on the first 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);
vcl* vector = relPages->rel_pages;
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);
if (!ppage)
{
BUGCHECK(243);
// msg 243 missing pointer page in DPM_data_pages
}

const ULONG* page = ppage->ppg_page;
const ULONG* const end_page = page + ppage->ppg_count;
while (page < end_page)
{
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 ULONG* page = ppage->ppg_page;
if (*page)
{
Ods::data_page* dpage =
(Ods::data_page*) CCH_HANDOFF(tdbb, &window, *page, LCK_read, pag_data);
recordCount = dpage->dpg_count;

const data_page::dpg_repeat* index = dpage->dpg_rpt;
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);
return (double) recordCount;
page++;
}

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)
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) /
(minRecordSize + (format->fmt_length * 0.5));
return (double) dataPages * (dbb->dbb_page_size - DPG_SIZE) / recordSize;
}


Expand Down

0 comments on commit b5dc562

Please sign in to comment.