8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 06:43:04 +01:00
firebird-mirror/src/jrd/ods.cpp
asfernandes c642ddca82 Misc.
2014-10-12 02:25:02 +00:00

172 lines
4.6 KiB
C++

/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Dmitry Yemanov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2005 Dmitry Yemanov <dimitr@users.sf.net>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../jrd/ods.h"
#include "../jrd/ods_proto.h"
namespace Ods {
bool isSupported(USHORT majorVersion, USHORT minorVersion)
{
const bool isFirebird = (majorVersion & ODS_FIREBIRD_FLAG);
majorVersion &= ~ODS_FIREBIRD_FLAG;
if (!isFirebird)
return false;
#ifdef ODS_8_TO_CURRENT
// Obsolete: Support InterBase major ODS numbers from 8 to 10
/*
if (!isFirebird)
{
return (majorVersion >= ODS_VERSION8 &&
majorVersion <= ODS_VERSION10);
}
*/
// This is for future ODS versions
if (majorVersion > ODS_VERSION10 &&
majorVersion < ODS_VERSION)
{
return true;
}
#endif
// Support current ODS of the engine
if (majorVersion == ODS_VERSION &&
minorVersion >= ODS_RELEASED &&
minorVersion <= ODS_CURRENT)
{
return true;
}
// Do not support anything else
return false;
}
ULONG bytesBitPIP(ULONG page_size)
{
return static_cast<ULONG>(page_size - offsetof(page_inv_page, pip_bits[0]));
}
ULONG pagesPerPIP(ULONG page_size)
{
return bytesBitPIP(page_size) * 8;
}
ULONG pagesPerSCN(ULONG page_size)
{
return pagesPerPIP(page_size) / BITS_PER_LONG;
}
// We must ensure that pagesPerSCN items can fit into scns_page::scn_pages array.
// We can't use fb_assert() here in ods.h so it is placed at pag.cpp
ULONG maxPagesPerSCN(ULONG page_size)
{
return static_cast<ULONG>((page_size - offsetof(scns_page, scn_pages[0])) / sizeof(((scns_page*)NULL)->scn_pages));
}
ULONG transPerTIP(ULONG page_size)
{
return static_cast<ULONG>((page_size - offsetof(tx_inv_page, tip_transactions[0])) * 4);
}
ULONG gensPerPage(ULONG page_size)
{
return static_cast<ULONG>((page_size - offsetof(generator_page, gpg_values[0])) /
sizeof(((generator_page*) NULL)->gpg_values));
}
ULONG dataPagesPerPP(ULONG page_size)
{
// Compute the number of data pages per pointer page. Each data page requires
// a 32 bit pointer (BITS_PER_LONG) and a 8 bit control field (PPG_DP_BITS_NUM).
// Also, don't allow extent of data pages (8 pages) to cross PP boundary to
// simplify code a bit.
ULONG ret = static_cast<ULONG>((page_size - offsetof(pointer_page, ppg_page[0])) * 8 / (BITS_PER_LONG + PPG_DP_BITS_NUM));
return ret & (~7);
}
ULONG maxRecsPerDP(ULONG page_size)
{
// Compute the number of records that can fit on a page using the
// size of the record index (dpb_repeat) and a record header. This
// gives an artificially high number, reducing the density of db_keys.
ULONG max_records = static_cast<ULONG>(
(page_size - sizeof(data_page)) / (sizeof(data_page::dpg_repeat) + offsetof(rhd, rhd_data[0])));
// Artificially reduce density of records to test high bits of record number
// max_records = 32000;
// Optimize record numbers for new 64-bit sparse bitmap implementation
// We need to measure if it is beneficial from performance point of view.
// Price is slightly reduced density of record numbers, but for
// ODS11 it doesn't matter because record numbers are 40-bit.
// Benefit is ~1.5 times smaller sparse bitmaps on average and faster bitmap iteration.
//max_records = FB_ALIGN(max_records, 64);
return max_records;
}
ULONG maxIndices(ULONG page_size)
{
// Compute the number of index roots that will fit on an index root page,
// assuming that each index has only one key
return static_cast<ULONG>((page_size - offsetof(index_root_page, irt_rpt[0])) /
(sizeof(index_root_page::irt_repeat) + sizeof(irtd)));
}
Firebird::string pagtype(UCHAR type)
{
// Print pretty name for database page type
const char* nameArray[pag_max + 1] = {
"purposely undefined",
"database header",
"page inventory",
"transaction inventory",
"pointer",
"data",
"index root",
"index B-tree",
"blob",
"generators",
"SCN inventory"
};
Firebird::string rc;
if (type < FB_NELEM(nameArray))
rc = nameArray[type];
else
rc.printf("unknown (%d)", type);
return rc;
}
} // namespace