8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 18:43:02 +01:00
firebird-mirror/src/jrd/pag.h

333 lines
7.9 KiB
C
Raw Normal View History

2001-05-23 15:26:42 +02:00
/*
* PROGRAM: JRD Access Method
* MODULE: pag.h
* DESCRIPTION: Page interface definitions
*
* The contents of this file are subject to the Interbase 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.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, 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 Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
/*
* Modified by: Patrick J. P. Griffin
* Date: 11/29/2000
* Problem: Bug 116733 Too many generators corrupt database.
* DPM_gen_id was not calculating page and offset correctly.
* Change: Add pgc_gpg, number of generators per page,
* for use in DPM_gen_id.
*/
#ifndef JRD_PAG_H
#define JRD_PAG_H
2001-05-23 15:26:42 +02:00
2001-12-24 03:51:06 +01:00
#include "../include/fb_blk.h"
2006-05-22 00:07:35 +02:00
#include "../common/classes/array.h"
#include "../common/classes/locks.h"
#include "../jrd/ods.h"
#include "../jrd/lls.h"
2001-12-24 03:51:06 +01:00
namespace Jrd {
2008-12-05 01:56:15 +01:00
2009-11-27 09:34:34 +01:00
// Page control block -- used by PAG to keep track of critical constants
2006-05-22 00:07:35 +02:00
/**
class PageControl : public pool_alloc<type_pgc>
2001-12-24 03:51:06 +01:00
{
public:
2008-12-05 01:56:15 +01:00
SLONG pgc_high_water; // Lowest PIP with space
SLONG pgc_ppp; // Pages per pip
SLONG pgc_pip; // First pointer page
ULONG pgc_bytes; // Number of bytes of bit in PIP
ULONG pgc_tpt; // Transactions per TIP
ULONG pgc_gpg; // Generators per generator page
2006-05-22 00:07:35 +02:00
};
**/
2011-04-02 06:45:26 +02:00
// page spaces below TRANS_PAGE_SPACE contain regular database pages
// TEMP_PAGE_SPACE and page spaces above TEMP_PAGE_SPACE contain temporary pages
// TRANS_PAGE_SPACE is pseudo space to store transaction numbers in precedence stack
2011-04-02 06:45:26 +02:00
// INVALID_PAGE_SPACE is to ???
const USHORT INVALID_PAGE_SPACE = 0;
2006-05-22 00:07:35 +02:00
const USHORT DB_PAGE_SPACE = 1;
const USHORT TRANS_PAGE_SPACE = 255;
2008-12-05 01:56:15 +01:00
const USHORT TEMP_PAGE_SPACE = 256;
2006-05-22 00:07:35 +02:00
const USHORT PAGES_IN_EXTENT = 8;
2006-05-22 00:07:35 +02:00
class jrd_file;
class Database;
class thread_db;
class PageManager;
2006-05-22 00:07:35 +02:00
class PageSpace : public pool_alloc<type_PageSpace>
{
public:
2009-12-23 02:19:18 +01:00
explicit PageSpace(Database* aDbb, USHORT aPageSpaceID)
2006-05-22 00:07:35 +02:00
{
2006-05-24 05:03:52 +02:00
pageSpaceID = aPageSpaceID;
pipHighWater = 0;
pipWithExtent = 0;
pipFirst = 0;
scnFirst = 0;
2006-05-24 05:03:52 +02:00
file = 0;
dbb = aDbb;
maxPageNumber = 0;
pipMaxKnown = 0;
2006-05-22 00:07:35 +02:00
}
~PageSpace();
USHORT pageSpaceID;
Firebird::AtomicCounter pipHighWater; // Lowest PIP with space
Firebird::AtomicCounter pipWithExtent; // Lowest PIP with free extent
ULONG pipFirst; // First pointer page
ULONG scnFirst; // First SCN's page
2006-05-22 00:07:35 +02:00
jrd_file* file;
2013-12-11 11:19:13 +01:00
static inline bool isTemporary(USHORT aPageSpaceID)
{
return (aPageSpaceID >= TEMP_PAGE_SPACE);
}
2008-05-10 05:44:57 +02:00
inline bool isTemporary() const
{
2013-12-11 11:19:13 +01:00
return isTemporary(pageSpaceID);
2006-05-22 00:07:35 +02:00
}
static inline SLONG generate(const PageSpace* Item)
2008-05-10 05:44:57 +02:00
{
2006-05-24 05:03:52 +02:00
return Item->pageSpaceID;
}
// how many pages allocated
ULONG actAlloc();
2007-07-02 12:28:50 +02:00
static ULONG actAlloc(const Database* dbb);
// number of last allocated page
ULONG maxAlloc();
2007-07-02 12:28:50 +02:00
static ULONG maxAlloc(const Database* dbb);
// number of last used page
ULONG lastUsedPage();
static ULONG lastUsedPage(const Database* dbb);
// number of used pages
ULONG usedPages();
static ULONG usedPages(const Database* dbb);
// extend page space
bool extend(thread_db*, const ULONG, const bool);
// get SCN's page number
ULONG getSCNPageNum(ULONG sequence);
static ULONG getSCNPageNum(const Database* dbb, ULONG sequence);
// is pagespace on raw device
bool onRawDevice() const;
private:
ULONG maxPageNumber;
2009-12-23 02:19:18 +01:00
Database* dbb;
ULONG pipMaxKnown;
2006-05-22 00:07:35 +02:00
};
class PageManager : public pool_alloc<type_PageManager>
{
public:
2009-12-23 02:19:18 +01:00
explicit PageManager(Database* aDbb, Firebird::MemoryPool& aPool) :
dbb(aDbb),
2006-05-24 05:03:52 +02:00
pageSpaces(aPool),
pool(aPool)
2006-05-22 00:07:35 +02:00
{
2006-05-24 05:03:52 +02:00
pagesPerPIP = 0;
bytesBitPIP = 0;
transPerTIP = 0;
gensPerPage = 0;
pagesPerSCN = 0;
tempPageSpaceID = 0;
tempFileCreated = false;
2008-12-05 01:56:15 +01:00
addPageSpace(DB_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
}
~PageManager()
{
while (pageSpaces.hasData())
delete pageSpaces.pop();
2006-05-22 00:07:35 +02:00
}
2007-07-02 12:28:50 +02:00
PageSpace* findPageSpace(const USHORT pageSpaceID) const;
2006-05-22 00:07:35 +02:00
void initTempPageSpace(thread_db* tdbb);
2006-05-22 00:07:35 +02:00
USHORT getTempPageSpaceID(thread_db* tdbb);
void closeAll();
ULONG pagesPerPIP; // Pages per pip
2008-12-05 01:56:15 +01:00
ULONG bytesBitPIP; // Number of bytes of bit in PIP
ULONG transPerTIP; // Transactions per TIP
2008-12-05 01:56:15 +01:00
ULONG gensPerPage; // Generators per generator page
ULONG pagesPerSCN; // Slots per SCN's page
2006-05-22 00:07:35 +02:00
private:
2008-12-22 10:00:05 +01:00
typedef Firebird::SortedArray<PageSpace*, Firebird::EmptyStorage<PageSpace*>,
2006-05-22 00:07:35 +02:00
USHORT, PageSpace> PageSpaceArray;
PageSpace* addPageSpace(const USHORT pageSpaceID);
void delPageSpace(const USHORT pageSpaceID);
2009-12-23 02:19:18 +01:00
Database* dbb;
2006-05-22 00:07:35 +02:00
PageSpaceArray pageSpaces;
Firebird::MemoryPool& pool;
Firebird::Mutex initTmpMtx;
USHORT tempPageSpaceID;
bool tempFileCreated;
2001-12-24 03:51:06 +01:00
};
2001-05-23 15:26:42 +02:00
2006-05-22 00:07:35 +02:00
class PageNumber
{
public:
// CVC: To be completely in sync, the second param would have to be TraNumber
inline PageNumber(const USHORT aPageSpace, const ULONG aPageNum)
: pageNum(aPageNum), pageSpaceID(aPageSpace)
2008-05-10 05:44:57 +02:00
{
// Some asserts are commented cause 0 was also used as 'does not matter' pagespace
// fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
}
// Required to be able to keep it in Firebird::Stack
inline PageNumber()
: pageNum(0), pageSpaceID(INVALID_PAGE_SPACE)
{ }
2008-05-10 05:44:57 +02:00
inline PageNumber(const PageNumber& from)
: pageNum(from.pageNum), pageSpaceID(from.pageSpaceID)
{ }
2006-05-22 00:07:35 +02:00
inline ULONG getPageNum() const
2008-05-10 05:44:57 +02:00
{
// fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
return pageNum;
2008-12-22 10:00:05 +01:00
}
2006-05-22 00:07:35 +02:00
inline USHORT getPageSpaceID() const
2008-05-10 05:44:57 +02:00
{
fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
return pageSpaceID;
2008-12-05 01:56:15 +01:00
}
2006-05-22 00:07:35 +02:00
inline USHORT setPageSpaceID(const USHORT aPageSpaceID)
2008-05-10 05:44:57 +02:00
{
fb_assert(aPageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
pageSpaceID = aPageSpaceID;
return pageSpaceID;
2008-12-05 01:56:15 +01:00
}
2006-05-22 00:07:35 +02:00
2008-05-10 05:44:57 +02:00
inline bool isTemporary() const
{
fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2013-12-11 11:19:13 +01:00
return PageSpace::isTemporary(pageSpaceID);
2007-02-22 15:12:04 +01:00
}
inline static USHORT getLockLen()
2008-05-10 05:44:57 +02:00
{
return 2 * sizeof(ULONG);
2006-05-22 00:07:35 +02:00
}
2008-05-10 05:44:57 +02:00
inline void getLockStr(UCHAR* str) const
{
fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
memcpy(str, &pageNum, sizeof(ULONG));
str += sizeof(ULONG);
2007-09-07 09:41:07 +02:00
const ULONG val = pageSpaceID;
memcpy(str, &val, sizeof(ULONG));
2006-05-22 00:07:35 +02:00
}
2008-05-10 05:44:57 +02:00
inline PageNumber& operator=(const PageNumber& from)
{
2006-05-22 00:07:35 +02:00
pageSpaceID = from.pageSpaceID;
// fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
pageNum = from.pageNum;
return *this;
}
inline ULONG operator=(const ULONG from)
2008-05-10 05:44:57 +02:00
{
// fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
pageNum = from;
return pageNum;
}
2008-05-10 05:44:57 +02:00
inline bool operator==(const PageNumber& other) const
{
2010-02-26 03:16:31 +01:00
return (pageNum == other.pageNum) && (pageSpaceID == other.pageSpaceID);
2006-05-22 00:07:35 +02:00
}
2008-05-10 05:44:57 +02:00
inline bool operator!=(const PageNumber& other) const
{
2006-05-22 00:07:35 +02:00
return !(*this == other);
}
2008-05-10 05:44:57 +02:00
inline bool operator>(const PageNumber& other) const
{
fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
fb_assert(other.pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
return (pageSpaceID > other.pageSpaceID) ||
2015-02-03 01:43:30 +01:00
((pageSpaceID == other.pageSpaceID) && (pageNum > other.pageNum));
2006-05-22 00:07:35 +02:00
}
2008-05-10 05:44:57 +02:00
inline bool operator>=(const PageNumber& other) const
{
fb_assert(pageSpaceID != INVALID_PAGE_SPACE);
fb_assert(other.pageSpaceID != INVALID_PAGE_SPACE);
2006-05-22 00:07:35 +02:00
return (pageSpaceID > other.pageSpaceID) ||
2015-02-03 01:43:30 +01:00
((pageSpaceID == other.pageSpaceID) && (pageNum >= other.pageNum));
2006-05-22 00:07:35 +02:00
}
2008-05-10 05:44:57 +02:00
inline bool operator<(const PageNumber& other) const
{
2006-05-22 00:07:35 +02:00
return !(*this >= other);
}
2008-05-10 05:44:57 +02:00
inline bool operator<=(const PageNumber& other) const
{
2006-05-22 00:07:35 +02:00
return !(*this > other);
}
2006-05-24 05:03:52 +02:00
/*
inline operator ULONG() const
2008-05-10 05:44:57 +02:00
{
2006-05-22 00:07:35 +02:00
return pageNum;
}
2006-05-24 05:03:52 +02:00
*/
2011-01-22 18:15:52 +01:00
2006-05-22 00:07:35 +02:00
private:
ULONG pageNum;
2006-05-22 00:07:35 +02:00
USHORT pageSpaceID;
};
const PageNumber ZERO_PAGE_NUMBER(DB_PAGE_SPACE, 0);
2006-05-22 00:07:35 +02:00
const PageNumber HEADER_PAGE_NUMBER(DB_PAGE_SPACE, HEADER_PAGE);
typedef Firebird::Stack<PageNumber> PageStack;
} //namespace Jrd
2009-11-27 09:34:34 +01:00
#endif // JRD_PAG_H