mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 11:31:51 +01:00
Merge perch.ndb.mysql.com:/home/jonas/src/51-ndb
into perch.ndb.mysql.com:/home/jonas/src/mysql-5.1-new
This commit is contained in:
commit
ecaf439e63
52 changed files with 3028 additions and 992 deletions
|
@ -150,10 +150,4 @@
|
||||||
*/
|
*/
|
||||||
#define LCP_RESTORE_BUFFER (4*32)
|
#define LCP_RESTORE_BUFFER (4*32)
|
||||||
|
|
||||||
/*
|
|
||||||
* Log buffer pages
|
|
||||||
* 8M
|
|
||||||
*/
|
|
||||||
#define LGMAN_LOG_BUFFER (8*32)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,9 +60,10 @@ public:
|
||||||
fsFormatArrayOfPages=1,
|
fsFormatArrayOfPages=1,
|
||||||
fsFormatListOfMemPages=2,
|
fsFormatListOfMemPages=2,
|
||||||
fsFormatGlobalPage=3,
|
fsFormatGlobalPage=3,
|
||||||
|
fsFormatSharedPage=4,
|
||||||
fsFormatMax
|
fsFormatMax
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of signal
|
* Length of signal
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -88,11 +88,12 @@
|
||||||
#define CFG_DB_STRING_MEMORY 161 /* used from 5.1 */
|
#define CFG_DB_STRING_MEMORY 161 /* used from 5.1 */
|
||||||
#define CFG_DB_INITIAL_OPEN_FILES 162 /* used from 5.1 */
|
#define CFG_DB_INITIAL_OPEN_FILES 162 /* used from 5.1 */
|
||||||
|
|
||||||
#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */
|
|
||||||
|
|
||||||
#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160
|
#define CFG_DB_DISK_PAGE_BUFFER_MEMORY 160
|
||||||
#define CFG_DB_STRING_MEMORY 161
|
#define CFG_DB_STRING_MEMORY 161
|
||||||
|
|
||||||
|
#define CFG_DB_SGA 198 /* super pool mem */
|
||||||
|
#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */
|
||||||
|
|
||||||
#define CFG_NODE_ARBIT_RANK 200
|
#define CFG_NODE_ARBIT_RANK 200
|
||||||
#define CFG_NODE_ARBIT_DELAY 201
|
#define CFG_NODE_ARBIT_DELAY 201
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ printFSREADWRITEREQ(FILE * output, const Uint32 * theData,
|
||||||
break;
|
break;
|
||||||
case FsReadWriteReq::fsFormatGlobalPage:
|
case FsReadWriteReq::fsFormatGlobalPage:
|
||||||
fprintf(output, "List of global pages)\n");
|
fprintf(output, "List of global pages)\n");
|
||||||
|
case FsReadWriteReq::fsFormatSharedPage:
|
||||||
|
fprintf(output, "List of shared pages)\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(output, "fsFormatMax not handled\n");
|
fprintf(output, "fsFormatMax not handled\n");
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
#include "SimBlockList.hpp"
|
#include "SimBlockList.hpp"
|
||||||
|
#include <Emulator.hpp>
|
||||||
#include <SimulatedBlock.hpp>
|
#include <SimulatedBlock.hpp>
|
||||||
#include <Cmvmi.hpp>
|
#include <Cmvmi.hpp>
|
||||||
#include <Ndbfs.hpp>
|
#include <Ndbfs.hpp>
|
||||||
|
@ -69,7 +70,7 @@ void * operator new (size_t sz, SIMBLOCKLIST_DUMMY dummy){
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
SimBlockList::load(Configuration & conf){
|
SimBlockList::load(EmulatorData& data){
|
||||||
noOfBlocks = NO_OF_BLOCKS;
|
noOfBlocks = NO_OF_BLOCKS;
|
||||||
theList = new SimulatedBlock * [noOfBlocks];
|
theList = new SimulatedBlock * [noOfBlocks];
|
||||||
Dbdict* dbdict = 0;
|
Dbdict* dbdict = 0;
|
||||||
|
@ -78,12 +79,13 @@ SimBlockList::load(Configuration & conf){
|
||||||
Lgman* lg = 0;
|
Lgman* lg = 0;
|
||||||
Tsman* ts = 0;
|
Tsman* ts = 0;
|
||||||
|
|
||||||
Block_context ctx(conf, * (Ndbd_mem_manager*)0);
|
Block_context ctx(*data.theConfiguration, *data.m_mem_manager);
|
||||||
|
|
||||||
SimulatedBlock * fs = 0;
|
SimulatedBlock * fs = 0;
|
||||||
{
|
{
|
||||||
Uint32 dl;
|
Uint32 dl;
|
||||||
const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
|
const ndb_mgm_configuration_iterator * p =
|
||||||
|
ctx.m_config.getOwnConfigIterator();
|
||||||
if(p && !ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl){
|
if(p && !ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl){
|
||||||
fs = NEW_BLOCK(VoidFs)(ctx);
|
fs = NEW_BLOCK(VoidFs)(ctx);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2675,7 +2675,7 @@ Backup::openFilesReply(Signal* signal,
|
||||||
|
|
||||||
const Uint32 sz =
|
const Uint32 sz =
|
||||||
(sizeof(BackupFormat::CtlFile::TableList) >> 2) +
|
(sizeof(BackupFormat::CtlFile::TableList) >> 2) +
|
||||||
ptr.p->tables.noOfElements() - 1;
|
ptr.p->tables.count() - 1;
|
||||||
|
|
||||||
Uint32 * dst;
|
Uint32 * dst;
|
||||||
ndbrequire(sz < buf.getMaxWrite());
|
ndbrequire(sz < buf.getMaxWrite());
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <SLList.hpp>
|
#include <SLList.hpp>
|
||||||
#include <DLFifoList.hpp>
|
#include <DLFifoList.hpp>
|
||||||
|
#include <DLCFifoList.hpp>
|
||||||
#include <SignalCounter.hpp>
|
#include <SignalCounter.hpp>
|
||||||
#include <blocks/mutexes.hpp>
|
#include <blocks/mutexes.hpp>
|
||||||
|
|
||||||
|
@ -439,7 +440,7 @@ public:
|
||||||
Uint32 startGCP;
|
Uint32 startGCP;
|
||||||
Uint32 currGCP;
|
Uint32 currGCP;
|
||||||
Uint32 stopGCP;
|
Uint32 stopGCP;
|
||||||
DLList<Table> tables;
|
DLCFifoList<Table> tables;
|
||||||
SLList<TriggerRecord> triggers;
|
SLList<TriggerRecord> triggers;
|
||||||
|
|
||||||
SLList<BackupFile> files;
|
SLList<BackupFile> files;
|
||||||
|
|
|
@ -131,6 +131,7 @@ Cmvmi::Cmvmi(Block_context& ctx) :
|
||||||
|
|
||||||
Cmvmi::~Cmvmi()
|
Cmvmi::~Cmvmi()
|
||||||
{
|
{
|
||||||
|
m_shared_page_pool.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,13 +325,28 @@ Cmvmi::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
Uint64 page_buffer = 64*1024*1024;
|
Uint64 page_buffer = 64*1024*1024;
|
||||||
ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
|
ndb_mgm_get_int64_parameter(p, CFG_DB_DISK_PAGE_BUFFER_MEMORY, &page_buffer);
|
||||||
|
|
||||||
page_buffer /= GLOBAL_PAGE_SIZE; // in pages
|
Uint32 pages = 0;
|
||||||
if (page_buffer > 0)
|
pages += page_buffer / GLOBAL_PAGE_SIZE; // in pages
|
||||||
|
pages += LCP_RESTORE_BUFFER;
|
||||||
|
m_global_page_pool.setSize(pages + 64, true);
|
||||||
|
|
||||||
|
Uint64 shared_mem = 8*1024*1024;
|
||||||
|
ndb_mgm_get_int64_parameter(p, CFG_DB_SGA, &shared_mem);
|
||||||
|
shared_mem /= GLOBAL_PAGE_SIZE;
|
||||||
|
if (shared_mem)
|
||||||
{
|
{
|
||||||
page_buffer += LGMAN_LOG_BUFFER;
|
Resource_limit rl;
|
||||||
|
rl.m_min = 0;
|
||||||
|
rl.m_max = shared_mem;
|
||||||
|
rl.m_resource_id = 0;
|
||||||
|
m_ctx.m_mm.set_resource_limit(rl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ndbrequire(m_ctx.m_mm.init());
|
||||||
|
{
|
||||||
|
void* ptr = m_ctx.m_mm.get_memroot();
|
||||||
|
m_shared_page_pool.set((GlobalPage*)ptr, ~0);
|
||||||
}
|
}
|
||||||
page_buffer += LCP_RESTORE_BUFFER;
|
|
||||||
m_global_page_pool.setSize(page_buffer + 64, true);
|
|
||||||
|
|
||||||
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
||||||
conf->senderRef = reference();
|
conf->senderRef = reference();
|
||||||
|
@ -1083,6 +1099,37 @@ Cmvmi::execDUMP_STATE_ORD(Signal* signal)
|
||||||
g_sectionSegmentPool.getSize(),
|
g_sectionSegmentPool.getSize(),
|
||||||
g_sectionSegmentPool.getNoOfFree());
|
g_sectionSegmentPool.getNoOfFree());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dumpState->args[0] == 1000)
|
||||||
|
{
|
||||||
|
Uint32 len = signal->getLength();
|
||||||
|
if (signal->getLength() == 1)
|
||||||
|
{
|
||||||
|
signal->theData[1] = 0;
|
||||||
|
signal->theData[2] = ~0;
|
||||||
|
sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Uint32 id = signal->theData[1];
|
||||||
|
Resource_limit rl;
|
||||||
|
if (!m_ctx.m_mm.get_resource_limit(id, rl))
|
||||||
|
len = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rl.m_min || rl.m_curr || rl.m_max)
|
||||||
|
infoEvent("Resource %d min: %d max: %d curr: %d",
|
||||||
|
id, rl.m_min, rl.m_max, rl.m_curr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 3)
|
||||||
|
{
|
||||||
|
signal->theData[0] = 1000;
|
||||||
|
signal->theData[1] = id+1;
|
||||||
|
signal->theData[2] = ~0;
|
||||||
|
sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 3, JBB);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (dumpState->args[0] == DumpStateOrd::CmvmiSetRestartOnErrorInsert){
|
if (dumpState->args[0] == DumpStateOrd::CmvmiSetRestartOnErrorInsert){
|
||||||
if(signal->getLength() == 1)
|
if(signal->getLength() == 1)
|
||||||
|
|
|
@ -281,8 +281,6 @@ Dbdict::execDUMP_STATE_ORD(Signal* signal)
|
||||||
#define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree())
|
#define MEMINFO(x, y) infoEvent(x ": %d %d", y.getSize(), y.getNoOfFree())
|
||||||
if(signal->theData[0] == 1226){
|
if(signal->theData[0] == 1226){
|
||||||
MEMINFO("c_obj_pool", c_obj_pool);
|
MEMINFO("c_obj_pool", c_obj_pool);
|
||||||
MEMINFO("c_file_pool", c_file_pool);
|
|
||||||
MEMINFO("c_filegroup_pool", c_filegroup_pool);
|
|
||||||
MEMINFO("c_opRecordPool", c_opRecordPool);
|
MEMINFO("c_opRecordPool", c_opRecordPool);
|
||||||
MEMINFO("c_rope_pool", c_rope_pool);
|
MEMINFO("c_rope_pool", c_rope_pool);
|
||||||
}
|
}
|
||||||
|
@ -2037,10 +2035,14 @@ void Dbdict::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers);
|
c_obj_pool.setSize(tablerecSize+c_maxNoOfTriggers);
|
||||||
c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
|
c_obj_hash.setSize((tablerecSize+c_maxNoOfTriggers+1)/2);
|
||||||
|
|
||||||
c_file_pool.setSize(10);
|
Pool_context pc;
|
||||||
|
pc.m_block = this;
|
||||||
|
|
||||||
c_file_hash.setSize(16);
|
c_file_hash.setSize(16);
|
||||||
c_filegroup_pool.setSize(10);
|
|
||||||
c_filegroup_hash.setSize(16);
|
c_filegroup_hash.setSize(16);
|
||||||
|
|
||||||
|
c_file_pool.init(RT_DBDICT_FILE, pc);
|
||||||
|
c_filegroup_pool.init(RT_DBDICT_FILEGROUP, pc);
|
||||||
|
|
||||||
c_opRecordPool.setSize(256); // XXX need config params
|
c_opRecordPool.setSize(256); // XXX need config params
|
||||||
c_opCreateTable.setSize(8);
|
c_opCreateTable.setSize(8);
|
||||||
|
@ -2121,22 +2123,6 @@ void Dbdict::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
new (ptr.p) DictObject();
|
new (ptr.p) DictObject();
|
||||||
objs.release();
|
objs.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
Ptr<File> ptr;
|
|
||||||
SLList<File> objs(c_file_pool);
|
|
||||||
while(objs.seize(ptr))
|
|
||||||
new (ptr.p) File();
|
|
||||||
objs.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Ptr<Filegroup> ptr;
|
|
||||||
SLList<Filegroup> objs(c_filegroup_pool);
|
|
||||||
while(objs.seize(ptr))
|
|
||||||
new (ptr.p) Filegroup();
|
|
||||||
objs.release();
|
|
||||||
}
|
|
||||||
}//execSIZEALT_REP()
|
}//execSIZEALT_REP()
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
@ -14835,6 +14821,8 @@ Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new (fg_ptr.p) Filegroup();
|
||||||
|
|
||||||
{
|
{
|
||||||
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
||||||
if(!name.assign(fg.FilegroupName, len, hash)){
|
if(!name.assign(fg.FilegroupName, len, hash)){
|
||||||
|
@ -15074,6 +15062,8 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new (filePtr.p) File();
|
||||||
|
|
||||||
{
|
{
|
||||||
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
Rope name(c_rope_pool, obj_ptr.p->m_name);
|
||||||
if(!name.assign(f.FileName, len, hash)){
|
if(!name.assign(f.FileName, len, hash)){
|
||||||
|
@ -15088,7 +15078,7 @@ Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
|
||||||
break;
|
break;
|
||||||
case DictTabInfo::LogfileGroup:
|
case DictTabInfo::LogfileGroup:
|
||||||
{
|
{
|
||||||
LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
||||||
list.add(filePtr);
|
list.add(filePtr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -15314,7 +15304,7 @@ Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
|
||||||
break;
|
break;
|
||||||
case DictTabInfo::LogfileGroup:
|
case DictTabInfo::LogfileGroup:
|
||||||
{
|
{
|
||||||
LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
||||||
list.remove(f_ptr);
|
list.remove(f_ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -15329,8 +15319,6 @@ Dbdict::create_file_abort_complete(Signal* signal, SchemaOp* op)
|
||||||
execute(signal, op->m_callback, 0);
|
execute(signal, op->m_callback, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CArray<KeyDescriptor> g_key_descriptor_pool;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
|
Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
|
||||||
{
|
{
|
||||||
|
@ -15517,7 +15505,7 @@ Dbdict::drop_fg_commit_start(Signal* signal, SchemaOp* op)
|
||||||
* Mark all undofiles as dropped
|
* Mark all undofiles as dropped
|
||||||
*/
|
*/
|
||||||
Ptr<File> filePtr;
|
Ptr<File> filePtr;
|
||||||
LocalDLList<File> list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
|
||||||
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
|
XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
|
||||||
for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
|
for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -534,6 +534,7 @@ public:
|
||||||
File() {}
|
File() {}
|
||||||
|
|
||||||
Uint32 key;
|
Uint32 key;
|
||||||
|
Uint32 m_magic;
|
||||||
Uint32 m_obj_ptr_i;
|
Uint32 m_obj_ptr_i;
|
||||||
Uint32 m_filegroup_id;
|
Uint32 m_filegroup_id;
|
||||||
Uint32 m_type;
|
Uint32 m_type;
|
||||||
|
@ -552,12 +553,17 @@ public:
|
||||||
bool equal(const File& obj) const { return key == obj.key;}
|
bool equal(const File& obj) const { return key == obj.key;}
|
||||||
};
|
};
|
||||||
typedef Ptr<File> FilePtr;
|
typedef Ptr<File> FilePtr;
|
||||||
|
typedef RecordPool<File, RWPool> File_pool;
|
||||||
|
typedef DLListImpl<File_pool, File> File_list;
|
||||||
|
typedef LocalDLListImpl<File_pool, File> Local_file_list;
|
||||||
|
typedef KeyTableImpl<File_pool, File> File_hash;
|
||||||
|
|
||||||
struct Filegroup {
|
struct Filegroup {
|
||||||
Filegroup(){}
|
Filegroup(){}
|
||||||
|
|
||||||
Uint32 key;
|
Uint32 key;
|
||||||
Uint32 m_obj_ptr_i;
|
Uint32 m_obj_ptr_i;
|
||||||
|
Uint32 m_magic;
|
||||||
|
|
||||||
Uint32 m_type;
|
Uint32 m_type;
|
||||||
Uint32 m_version;
|
Uint32 m_version;
|
||||||
|
@ -571,7 +577,7 @@ public:
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Uint32 m_undo_buffer_size;
|
Uint32 m_undo_buffer_size;
|
||||||
DLList<File>::HeadPOD m_files;
|
File_list::HeadPOD m_files;
|
||||||
} m_logfilegroup;
|
} m_logfilegroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -586,11 +592,13 @@ public:
|
||||||
bool equal(const Filegroup& obj) const { return key == obj.key;}
|
bool equal(const Filegroup& obj) const { return key == obj.key;}
|
||||||
};
|
};
|
||||||
typedef Ptr<Filegroup> FilegroupPtr;
|
typedef Ptr<Filegroup> FilegroupPtr;
|
||||||
|
typedef RecordPool<Filegroup, RWPool> Filegroup_pool;
|
||||||
|
typedef KeyTableImpl<Filegroup_pool, Filegroup> Filegroup_hash;
|
||||||
|
|
||||||
ArrayPool<File> c_file_pool;
|
File_pool c_file_pool;
|
||||||
KeyTable<File> c_file_hash;
|
Filegroup_pool c_filegroup_pool;
|
||||||
ArrayPool<Filegroup> c_filegroup_pool;
|
File_hash c_file_hash;
|
||||||
KeyTable<Filegroup> c_filegroup_hash;
|
Filegroup_hash c_filegroup_hash;
|
||||||
|
|
||||||
RopePool c_rope_pool;
|
RopePool c_rope_pool;
|
||||||
|
|
||||||
|
|
|
@ -2366,8 +2366,9 @@ Dblqh::execREMOVE_MARKER_ORD(Signal* signal)
|
||||||
jamEntry();
|
jamEntry();
|
||||||
|
|
||||||
CommitAckMarkerPtr removedPtr;
|
CommitAckMarkerPtr removedPtr;
|
||||||
m_commitAckMarkerHash.release(removedPtr, key);
|
m_commitAckMarkerHash.remove(removedPtr, key);
|
||||||
ndbrequire(removedPtr.i != RNIL);
|
ndbrequire(removedPtr.i != RNIL);
|
||||||
|
m_commitAckMarkerPool.release(removedPtr);
|
||||||
#ifdef MARKER_TRACE
|
#ifdef MARKER_TRACE
|
||||||
ndbout_c("Rem marker[%.8x %.8x]", key.transid1, key.transid2);
|
ndbout_c("Rem marker[%.8x %.8x]", key.transid1, key.transid2);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4785,13 +4785,14 @@ Dbtc::execTC_COMMIT_ACK(Signal* signal){
|
||||||
key.transid2 = signal->theData[1];
|
key.transid2 = signal->theData[1];
|
||||||
|
|
||||||
CommitAckMarkerPtr removedMarker;
|
CommitAckMarkerPtr removedMarker;
|
||||||
m_commitAckMarkerHash.release(removedMarker, key);
|
m_commitAckMarkerHash.remove(removedMarker, key);
|
||||||
if (removedMarker.i == RNIL) {
|
if (removedMarker.i == RNIL) {
|
||||||
jam();
|
jam();
|
||||||
warningHandlerLab(signal, __LINE__);
|
warningHandlerLab(signal, __LINE__);
|
||||||
return;
|
return;
|
||||||
}//if
|
}//if
|
||||||
sendRemoveMarkers(signal, removedMarker.p);
|
sendRemoveMarkers(signal, removedMarker.p);
|
||||||
|
m_commitAckMarkerPool.release(removedMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -12381,7 +12382,7 @@ void Dbtc::executeTriggers(Signal* signal, ApiConnectRecordPtr* transPtr)
|
||||||
tmp2.release();
|
tmp2.release();
|
||||||
LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
|
LocalDataBuffer<11> tmp3(pool, trigPtr.p->afterValues);
|
||||||
tmp3.release();
|
tmp3.release();
|
||||||
regApiPtr->theFiredTriggers.release(trigPtr.i);
|
regApiPtr->theFiredTriggers.release(trigPtr);
|
||||||
}
|
}
|
||||||
trigPtr = nextTrigPtr;
|
trigPtr = nextTrigPtr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,20 +469,21 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
|
|
||||||
struct Page_request
|
struct Page_request
|
||||||
{
|
{
|
||||||
Page_request() {}
|
|
||||||
Local_key m_key;
|
Local_key m_key;
|
||||||
Uint16 m_estimated_free_space; // in bytes/records
|
|
||||||
Uint16 m_list_index; // in Disk_alloc_info.m_page_requests
|
|
||||||
Uint32 m_frag_ptr_i;
|
Uint32 m_frag_ptr_i;
|
||||||
Uint32 m_extent_info_ptr;
|
Uint32 m_extent_info_ptr;
|
||||||
Uint16 m_ref_count; // Waiters for page
|
Uint16 m_estimated_free_space; // in bytes/records
|
||||||
|
Uint16 m_list_index; // in Disk_alloc_info.m_page_requests
|
||||||
|
Uint16 m_ref_count; // Waiters for page
|
||||||
Uint16 m_uncommitted_used_space;
|
Uint16 m_uncommitted_used_space;
|
||||||
union {
|
Uint32 nextList;
|
||||||
Uint32 nextList;
|
|
||||||
Uint32 nextPool;
|
|
||||||
};
|
|
||||||
Uint32 prevList;
|
Uint32 prevList;
|
||||||
|
Uint32 m_magic;
|
||||||
}; // 32 bytes
|
}; // 32 bytes
|
||||||
|
|
||||||
|
typedef RecordPool<Page_request, WOPool> Page_request_pool;
|
||||||
|
typedef DLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
|
||||||
|
typedef LocalDLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
|
||||||
|
|
||||||
STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
|
STATIC_CONST( EXTENT_SEARCH_MATRIX_COLS = 4 ); // Guarantee size
|
||||||
STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
|
STATIC_CONST( EXTENT_SEARCH_MATRIX_ROWS = 5 ); // Total size
|
||||||
|
@ -495,6 +496,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
|
|
||||||
struct Extent_info : public Extent_list_t
|
struct Extent_info : public Extent_list_t
|
||||||
{
|
{
|
||||||
|
Uint32 m_magic;
|
||||||
Uint32 m_first_page_no;
|
Uint32 m_first_page_no;
|
||||||
Local_key m_key;
|
Local_key m_key;
|
||||||
Uint32 m_free_space;
|
Uint32 m_free_space;
|
||||||
|
@ -516,10 +518,13 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
m_key.m_page_idx == rec.m_key.m_page_idx;
|
m_key.m_page_idx == rec.m_key.m_page_idx;
|
||||||
}
|
}
|
||||||
}; // 40 bytes
|
}; // 40 bytes
|
||||||
|
|
||||||
typedef LocalDLList<Extent_info> Extent_list;
|
|
||||||
typedef LocalDLList<Page_request> Page_request_list;
|
|
||||||
|
|
||||||
|
typedef RecordPool<Extent_info, RWPool> Extent_info_pool;
|
||||||
|
typedef DLListImpl<Extent_info_pool, Extent_info> Extent_info_list;
|
||||||
|
typedef LocalDLListImpl<Extent_info_pool, Extent_info> Local_extent_info_list;
|
||||||
|
typedef DLHashTableImpl<Extent_info_pool, Extent_info> Extent_info_hash;
|
||||||
|
typedef SLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Fragment_extent_list;
|
||||||
|
typedef LocalSLListImpl<Extent_info_pool, Extent_info, Extent_list_t> Local_fragment_extent_list;
|
||||||
struct Tablerec;
|
struct Tablerec;
|
||||||
struct Disk_alloc_info
|
struct Disk_alloc_info
|
||||||
{
|
{
|
||||||
|
@ -553,7 +558,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
* Requests (for update) that have sufficient space left after request
|
* Requests (for update) that have sufficient space left after request
|
||||||
* these are currently being "mapped"
|
* these are currently being "mapped"
|
||||||
*/
|
*/
|
||||||
DLList<Page_request>::Head m_page_requests[MAX_FREE_LIST];
|
Page_request_list::Head m_page_requests[MAX_FREE_LIST];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current extent
|
* Current extent
|
||||||
|
@ -564,7 +569,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
|
STATIC_CONST( SZ = EXTENT_SEARCH_MATRIX_SIZE );
|
||||||
DLList<Extent_info>::Head m_free_extents[SZ];
|
Extent_info_list::Head m_free_extents[SZ];
|
||||||
Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
|
Uint32 m_total_extent_free_space_thresholds[EXTENT_SEARCH_MATRIX_ROWS];
|
||||||
Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
|
Uint32 m_page_free_bits_map[EXTENT_SEARCH_MATRIX_COLS];
|
||||||
|
|
||||||
|
@ -588,7 +593,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
|
||||||
return EXTENT_SEARCH_MATRIX_COLS - 1;
|
return EXTENT_SEARCH_MATRIX_COLS - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLList<Extent_info, Extent_list_t>::Head m_extent_list;
|
Fragment_extent_list::Head m_extent_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
void dump_disk_alloc(Disk_alloc_info&);
|
void dump_disk_alloc(Disk_alloc_info&);
|
||||||
|
@ -1009,9 +1014,9 @@ ArrayPool<TupTriggerData> c_triggerPool;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
ArrayPool<Extent_info> c_extent_pool;
|
Extent_info_pool c_extent_pool;
|
||||||
ArrayPool<Page_request> c_page_request_pool;
|
Extent_info_hash c_extent_hash;
|
||||||
DLHashTable<Extent_info> c_extent_hash;
|
Page_request_pool c_page_request_pool;
|
||||||
|
|
||||||
typedef Ptr<Tablerec> TablerecPtr;
|
typedef Ptr<Tablerec> TablerecPtr;
|
||||||
|
|
||||||
|
@ -2609,13 +2614,6 @@ private:
|
||||||
void disk_page_free(Signal*,
|
void disk_page_free(Signal*,
|
||||||
Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
|
Tablerec*, Fragrecord*, Local_key*, PagePtr, Uint32);
|
||||||
|
|
||||||
void disk_page_update_free_space(Fragrecord*, Ptr<Page_request>,
|
|
||||||
DLList<Page_request>::Head list[],
|
|
||||||
Uint32 i, Uint32 sz);
|
|
||||||
void disk_page_update_free_space(Fragrecord*, PagePtr, Uint32 i,
|
|
||||||
Int32 uncommitted_delta,
|
|
||||||
Int32 extent_delta);
|
|
||||||
|
|
||||||
void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
|
void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
|
||||||
|
|
||||||
void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
|
void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
|
||||||
|
@ -2632,6 +2630,7 @@ private:
|
||||||
Uint32 gci, Uint32 logfile_group_id);
|
Uint32 gci, Uint32 logfile_group_id);
|
||||||
|
|
||||||
void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
|
void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
|
||||||
|
void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
|
||||||
|
|
||||||
void disk_page_set_dirty(Ptr<Page>);
|
void disk_page_set_dirty(Ptr<Page>);
|
||||||
void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
|
void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
|
||||||
|
|
|
@ -89,8 +89,8 @@ Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc)
|
||||||
{
|
{
|
||||||
printf(" %d : ", i);
|
printf(" %d : ", i);
|
||||||
Ptr<Page_request> ptr;
|
Ptr<Page_request> ptr;
|
||||||
LocalDLList<Page_request> list(c_page_request_pool,
|
Local_page_request_list list(c_page_request_pool,
|
||||||
alloc.m_page_requests[i]);
|
alloc.m_page_requests[i]);
|
||||||
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
||||||
{
|
{
|
||||||
ndbout << ptr << " ";
|
ndbout << ptr << " ";
|
||||||
|
@ -103,7 +103,7 @@ Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc)
|
||||||
{
|
{
|
||||||
printf(" %d : ", i);
|
printf(" %d : ", i);
|
||||||
Ptr<Extent_info> ptr;
|
Ptr<Extent_info> ptr;
|
||||||
LocalDLList<Extent_info> list(c_extent_pool, alloc.m_free_extents[i]);
|
Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[i]);
|
||||||
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
||||||
{
|
{
|
||||||
ndbout << ptr << " ";
|
ndbout << ptr << " ";
|
||||||
|
@ -248,8 +248,8 @@ Dbtup::update_extent_pos(Disk_alloc_info& alloc,
|
||||||
if (old != pos)
|
if (old != pos)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
Extent_list old_list(c_extent_pool, alloc.m_free_extents[old]);
|
Local_extent_info_list old_list(c_extent_pool, alloc.m_free_extents[old]);
|
||||||
Extent_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
|
Local_extent_info_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
|
||||||
old_list.remove(extentPtr);
|
old_list.remove(extentPtr);
|
||||||
new_list.add(extentPtr);
|
new_list.add(extentPtr);
|
||||||
extentPtr.p->m_free_matrix_pos= pos;
|
extentPtr.p->m_free_matrix_pos= pos;
|
||||||
|
@ -388,8 +388,6 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||||
return -err;
|
return -err;
|
||||||
}
|
}
|
||||||
|
|
||||||
new (req.p) Page_request();
|
|
||||||
|
|
||||||
req.p->m_ref_count= 1;
|
req.p->m_ref_count= 1;
|
||||||
req.p->m_frag_ptr_i= fragPtr.i;
|
req.p->m_frag_ptr_i= fragPtr.i;
|
||||||
req.p->m_uncommitted_used_space= sz;
|
req.p->m_uncommitted_used_space= sz;
|
||||||
|
@ -422,7 +420,7 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||||
alloc.m_curr_extent_info_ptr_i = RNIL;
|
alloc.m_curr_extent_info_ptr_i = RNIL;
|
||||||
Uint32 pos= alloc.calc_extent_pos(ext.p);
|
Uint32 pos= alloc.calc_extent_pos(ext.p);
|
||||||
ext.p->m_free_matrix_pos = pos;
|
ext.p->m_free_matrix_pos = pos;
|
||||||
LocalDLList<Extent_info> list(c_extent_pool, alloc.m_free_extents[pos]);
|
Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[pos]);
|
||||||
list.add(ext);
|
list.add(ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +431,7 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||||
if ((pos= alloc.find_extent(sz)) != RNIL)
|
if ((pos= alloc.find_extent(sz)) != RNIL)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLList<Extent_info> list(c_extent_pool, alloc.m_free_extents[pos]);
|
Local_extent_info_list list(c_extent_pool, alloc.m_free_extents[pos]);
|
||||||
list.first(ext);
|
list.first(ext);
|
||||||
list.remove(ext);
|
list.remove(ext);
|
||||||
}
|
}
|
||||||
|
@ -467,8 +465,7 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||||
ext.p->m_free_page_count[0]= pages; // All pages are "free"-est
|
ext.p->m_free_page_count[0]= pages; // All pages are "free"-est
|
||||||
c_extent_hash.add(ext);
|
c_extent_hash.add(ext);
|
||||||
|
|
||||||
LocalSLList<Extent_info, Extent_list_t>
|
Local_fragment_extent_list list1(c_extent_pool, alloc.m_extent_list);
|
||||||
list1(c_extent_pool, alloc.m_extent_list);
|
|
||||||
list1.add(ext);
|
list1.add(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,8 +507,8 @@ Dbtup::disk_page_prealloc(Signal* signal,
|
||||||
// And put page request in correct free list
|
// And put page request in correct free list
|
||||||
idx= alloc.calc_page_free_bits(new_size);
|
idx= alloc.calc_page_free_bits(new_size);
|
||||||
{
|
{
|
||||||
LocalDLList<Page_request> list(c_page_request_pool,
|
Local_page_request_list list(c_page_request_pool,
|
||||||
alloc.m_page_requests[idx]);
|
alloc.m_page_requests[idx]);
|
||||||
|
|
||||||
list.add(req);
|
list.add(req);
|
||||||
}
|
}
|
||||||
|
@ -605,9 +602,9 @@ Dbtup::disk_page_prealloc_transit_page(Disk_alloc_info& alloc,
|
||||||
|
|
||||||
if (old_idx != new_idx)
|
if (old_idx != new_idx)
|
||||||
{
|
{
|
||||||
DLList<Page_request>::Head *lists = alloc.m_page_requests;
|
Page_request_list::Head *lists = alloc.m_page_requests;
|
||||||
LocalDLList<Page_request> old_list(c_page_request_pool, lists[old_idx]);
|
Local_page_request_list old_list(c_page_request_pool, lists[old_idx]);
|
||||||
LocalDLList<Page_request> new_list(c_page_request_pool, lists[new_idx]);
|
Local_page_request_list new_list(c_page_request_pool, lists[new_idx]);
|
||||||
old_list.remove(req);
|
old_list.remove(req);
|
||||||
new_list.add(req);
|
new_list.add(req);
|
||||||
|
|
||||||
|
@ -761,8 +758,8 @@ Dbtup::disk_page_prealloc_callback_common(Signal* signal,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Page_request_list list(c_page_request_pool,
|
Local_page_request_list list(c_page_request_pool,
|
||||||
alloc.m_page_requests[old_idx]);
|
alloc.m_page_requests[old_idx]);
|
||||||
list.release(req);
|
list.release(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1522,7 +1519,7 @@ Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
|
||||||
c_extent_pool.getPtr(old, alloc.m_curr_extent_info_ptr_i);
|
c_extent_pool.getPtr(old, alloc.m_curr_extent_info_ptr_i);
|
||||||
ndbassert(old.p->m_free_matrix_pos == RNIL);
|
ndbassert(old.p->m_free_matrix_pos == RNIL);
|
||||||
Uint32 pos= alloc.calc_extent_pos(old.p);
|
Uint32 pos= alloc.calc_extent_pos(old.p);
|
||||||
Extent_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
|
Local_extent_info_list new_list(c_extent_pool, alloc.m_free_extents[pos]);
|
||||||
new_list.add(old);
|
new_list.add(old);
|
||||||
old.p->m_free_matrix_pos= pos;
|
old.p->m_free_matrix_pos= pos;
|
||||||
}
|
}
|
||||||
|
@ -1531,8 +1528,7 @@ Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
|
||||||
ext.p->m_free_matrix_pos = RNIL;
|
ext.p->m_free_matrix_pos = RNIL;
|
||||||
c_extent_hash.add(ext);
|
c_extent_hash.add(ext);
|
||||||
|
|
||||||
LocalSLList<Extent_info, Extent_list_t>
|
Local_fragment_extent_list list1(c_extent_pool, alloc.m_extent_list);
|
||||||
list1(c_extent_pool, alloc.m_extent_list);
|
|
||||||
list1.add(ext);
|
list1.add(ext);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,9 +307,12 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
c_buildIndexPool.setSize(c_noOfBuildIndexRec);
|
c_buildIndexPool.setSize(c_noOfBuildIndexRec);
|
||||||
c_triggerPool.setSize(noOfTriggers);
|
c_triggerPool.setSize(noOfTriggers);
|
||||||
|
|
||||||
c_extent_pool.setSize(8192);
|
|
||||||
c_extent_hash.setSize(1024); // 4k
|
c_extent_hash.setSize(1024); // 4k
|
||||||
c_page_request_pool.setSize(1000);
|
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = this;
|
||||||
|
c_page_request_pool.wo_pool_init(RT_DBTUP_PAGE_REQUEST, pc);
|
||||||
|
c_extent_pool.init(RT_DBTUP_EXTENT_INFO, pc);
|
||||||
|
|
||||||
Uint32 nScanOp; // use TUX config for now
|
Uint32 nScanOp; // use TUX config for now
|
||||||
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
|
ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUX_SCAN_OP, &nScanOp));
|
||||||
|
|
|
@ -548,8 +548,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
|
||||||
if (regTabPtr.p->m_no_of_disk_attributes)
|
if (regTabPtr.p->m_no_of_disk_attributes)
|
||||||
{
|
{
|
||||||
ljam();
|
ljam();
|
||||||
if(!(getNodeState().getSystemRestartInProgress() &&
|
if(!(getNodeState().startLevel == NodeState::SL_STARTING &&
|
||||||
getNodeState().startLevel == NodeState::SL_STARTING &&
|
|
||||||
getNodeState().starting.startPhase <= 4))
|
getNodeState().starting.startPhase <= 4))
|
||||||
{
|
{
|
||||||
Callback cb;
|
Callback cb;
|
||||||
|
@ -605,7 +604,7 @@ Dbtup::undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused)
|
||||||
getFragmentrec(regFragPtr, fragOperPtr.p->fragidFrag, regTabPtr.p);
|
getFragmentrec(regFragPtr, fragOperPtr.p->fragidFrag, regTabPtr.p);
|
||||||
ndbrequire(regFragPtr.i != RNIL);
|
ndbrequire(regFragPtr.i != RNIL);
|
||||||
|
|
||||||
Logfile_client lsman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
|
Logfile_client lgman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
|
||||||
|
|
||||||
Disk_undo::Create create;
|
Disk_undo::Create create;
|
||||||
create.m_type_length= Disk_undo::UNDO_CREATE << 16 | (sizeof(create) >> 2);
|
create.m_type_length= Disk_undo::UNDO_CREATE << 16 | (sizeof(create) >> 2);
|
||||||
|
@ -613,14 +612,39 @@ Dbtup::undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused)
|
||||||
|
|
||||||
Logfile_client::Change c[1] = {{ &create, sizeof(create) >> 2 } };
|
Logfile_client::Change c[1] = {{ &create, sizeof(create) >> 2 } };
|
||||||
|
|
||||||
Uint64 lsn= lsman.add_entry(c, 1);
|
Uint64 lsn= lgman.add_entry(c, 1);
|
||||||
|
|
||||||
|
Logfile_client::Request req;
|
||||||
|
req.m_callback.m_callbackData= fragOperPtr.i;
|
||||||
|
req.m_callback.m_callbackFunction =
|
||||||
|
safe_cast(&Dbtup::undo_createtable_logsync_callback);
|
||||||
|
|
||||||
|
int ret = lgman.sync_lsn(signal, lsn, &req, 0);
|
||||||
|
switch(ret){
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
ndbout_c("ret: %d", ret);
|
||||||
|
ndbrequire(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Dbtup::undo_createtable_logsync_callback(Signal* signal, Uint32 ptrI,
|
||||||
|
Uint32 res)
|
||||||
|
{
|
||||||
|
jamEntry();
|
||||||
|
FragoperrecPtr fragOperPtr;
|
||||||
|
fragOperPtr.i= ptrI;
|
||||||
|
ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec);
|
||||||
|
|
||||||
signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
|
signal->theData[0] = fragOperPtr.p->lqhPtrFrag;
|
||||||
signal->theData[1] = 1;
|
signal->theData[1] = 1;
|
||||||
sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
|
sendSignal(fragOperPtr.p->lqhBlockrefFrag, GSN_TUP_ADD_ATTCONF,
|
||||||
signal, 2, JBB);
|
signal, 2, JBB);
|
||||||
|
|
||||||
releaseFragoperrec(fragOperPtr);
|
releaseFragoperrec(fragOperPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -904,7 +928,7 @@ Dbtup::drop_fragment_unmap_pages(Signal *signal,
|
||||||
{
|
{
|
||||||
if(alloc_info.m_curr_extent_info_ptr_i != RNIL)
|
if(alloc_info.m_curr_extent_info_ptr_i != RNIL)
|
||||||
{
|
{
|
||||||
LocalDLList<Extent_info>
|
Local_extent_info_list
|
||||||
list(c_extent_pool, alloc_info.m_free_extents[0]);
|
list(c_extent_pool, alloc_info.m_free_extents[0]);
|
||||||
Ptr<Extent_info> ext_ptr;
|
Ptr<Extent_info> ext_ptr;
|
||||||
c_extent_pool.getPtr(ext_ptr, alloc_info.m_curr_extent_info_ptr_i);
|
c_extent_pool.getPtr(ext_ptr, alloc_info.m_curr_extent_info_ptr_i);
|
||||||
|
@ -991,7 +1015,7 @@ Dbtup::drop_fragment_free_exent(Signal *signal,
|
||||||
if(!alloc_info.m_free_extents[pos].isEmpty())
|
if(!alloc_info.m_free_extents[pos].isEmpty())
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLList<Extent_info>
|
Local_extent_info_list
|
||||||
list(c_extent_pool, alloc_info.m_free_extents[pos]);
|
list(c_extent_pool, alloc_info.m_free_extents[pos]);
|
||||||
Ptr<Extent_info> ext_ptr;
|
Ptr<Extent_info> ext_ptr;
|
||||||
list.first(ext_ptr);
|
list.first(ext_ptr);
|
||||||
|
|
|
@ -661,8 +661,7 @@ Dbtup::scanNext(Signal* signal, ScanOpPtr scanPtr)
|
||||||
jam();
|
jam();
|
||||||
{
|
{
|
||||||
Disk_alloc_info& alloc = frag.m_disk_alloc_info;
|
Disk_alloc_info& alloc = frag.m_disk_alloc_info;
|
||||||
LocalSLList<Extent_info, Extent_list_t>
|
Local_fragment_extent_list list(c_extent_pool, alloc.m_extent_list);
|
||||||
list(c_extent_pool, alloc.m_extent_list);
|
|
||||||
Ptr<Extent_info> ext_ptr;
|
Ptr<Extent_info> ext_ptr;
|
||||||
c_extent_pool.getPtr(ext_ptr, pos.m_extent_info_ptr_i);
|
c_extent_pool.getPtr(ext_ptr, pos.m_extent_info_ptr_i);
|
||||||
Extent_info* ext = ext_ptr.p;
|
Extent_info* ext = ext_ptr.p;
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <EventLogger.hpp>
|
#include <EventLogger.hpp>
|
||||||
extern EventLogger g_eventLogger;
|
extern EventLogger g_eventLogger;
|
||||||
|
|
||||||
|
#include <record_types.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ---<a>-----<b>-----<c>-----<d>---> (time)
|
* ---<a>-----<b>-----<c>-----<d>---> (time)
|
||||||
*
|
*
|
||||||
|
@ -90,12 +92,8 @@ Lgman::Lgman(Block_context & ctx) :
|
||||||
|
|
||||||
addRecSignal(GSN_GET_TABINFOREQ, &Lgman::execGET_TABINFOREQ);
|
addRecSignal(GSN_GET_TABINFOREQ, &Lgman::execGET_TABINFOREQ);
|
||||||
|
|
||||||
m_last_lsn = 0;
|
m_last_lsn = 1;
|
||||||
m_logfile_group_pool.setSize(10);
|
|
||||||
m_logfile_group_hash.setSize(10);
|
m_logfile_group_hash.setSize(10);
|
||||||
m_file_pool.setSize(10);
|
|
||||||
m_data_buffer_pool.setSize(10);
|
|
||||||
m_log_waiter_pool.setSize(10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Lgman::~Lgman()
|
Lgman::~Lgman()
|
||||||
|
@ -118,6 +116,13 @@ Lgman::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
m_ctx.m_config.getOwnConfigIterator();
|
m_ctx.m_config.getOwnConfigIterator();
|
||||||
ndbrequire(p != 0);
|
ndbrequire(p != 0);
|
||||||
|
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = this;
|
||||||
|
m_log_waiter_pool.wo_pool_init(RT_LGMAN_LOG_WAITER, pc);
|
||||||
|
m_file_pool.init(RT_LGMAN_FILE, pc);
|
||||||
|
m_logfile_group_pool.init(RT_LGMAN_FILEGROUP, pc);
|
||||||
|
m_data_buffer_pool.setSize(10);
|
||||||
|
|
||||||
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
||||||
conf->senderRef = reference();
|
conf->senderRef = reference();
|
||||||
conf->senderData = senderData;
|
conf->senderData = senderData;
|
||||||
|
@ -271,9 +276,9 @@ Lgman::execDUMP_STATE_ORD(Signal* signal){
|
||||||
if (!ptr.p->m_log_buffer_waiters.isEmpty())
|
if (!ptr.p->m_log_buffer_waiters.isEmpty())
|
||||||
{
|
{
|
||||||
Uint32 free_buffer= ptr.p->m_free_buffer_words;
|
Uint32 free_buffer= ptr.p->m_free_buffer_words;
|
||||||
LocalDLFifoList<Log_waiter>
|
|
||||||
list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
|
||||||
Ptr<Log_waiter> waiter;
|
Ptr<Log_waiter> waiter;
|
||||||
|
Local_log_waiter_list
|
||||||
|
list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
||||||
list.first(waiter);
|
list.first(waiter);
|
||||||
infoEvent(" free_buffer_words: %d head(waiters).sz: %d %d",
|
infoEvent(" free_buffer_words: %d head(waiters).sz: %d %d",
|
||||||
ptr.p->m_free_buffer_words,
|
ptr.p->m_free_buffer_words,
|
||||||
|
@ -282,13 +287,21 @@ Lgman::execDUMP_STATE_ORD(Signal* signal){
|
||||||
}
|
}
|
||||||
if (!ptr.p->m_log_sync_waiters.isEmpty())
|
if (!ptr.p->m_log_sync_waiters.isEmpty())
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Log_waiter>
|
|
||||||
list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
|
||||||
Ptr<Log_waiter> waiter;
|
Ptr<Log_waiter> waiter;
|
||||||
|
Local_log_waiter_list
|
||||||
|
list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
||||||
list.first(waiter);
|
list.first(waiter);
|
||||||
infoEvent(" m_last_synced_lsn: %lld: %d head(waiters).m_sync_lsn: %lld",
|
infoEvent(" m_last_synced_lsn: %lld head(waiters %x).m_sync_lsn: %lld",
|
||||||
ptr.p->m_last_synced_lsn,
|
ptr.p->m_last_synced_lsn,
|
||||||
|
waiter.i,
|
||||||
waiter.p->m_sync_lsn);
|
waiter.p->m_sync_lsn);
|
||||||
|
|
||||||
|
while(!waiter.isNull())
|
||||||
|
{
|
||||||
|
ndbout_c("ptr: %x %p lsn: %lld next: %x",
|
||||||
|
waiter.i, waiter.p, waiter.p->m_sync_lsn, waiter.p->nextList);
|
||||||
|
list.next(waiter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_logfile_group_list.next(ptr);
|
m_logfile_group_list.next(ptr);
|
||||||
}
|
}
|
||||||
|
@ -425,7 +438,7 @@ Lgman::drop_filegroup_drop_files(Signal* signal,
|
||||||
ndbrequire(ptr.p->m_meta_files.isEmpty());
|
ndbrequire(ptr.p->m_meta_files.isEmpty());
|
||||||
ndbrequire(ptr.p->m_outstanding_fs == 0);
|
ndbrequire(ptr.p->m_outstanding_fs == 0);
|
||||||
|
|
||||||
LocalDLFifoList<Undofile> list(m_file_pool, ptr.p->m_files);
|
Local_undofile_list list(m_file_pool, ptr.p->m_files);
|
||||||
Ptr<Undofile> file_ptr;
|
Ptr<Undofile> file_ptr;
|
||||||
|
|
||||||
if (list.first(file_ptr))
|
if (list.first(file_ptr))
|
||||||
|
@ -516,7 +529,8 @@ Lgman::execCREATE_FILE_REQ(Signal* signal){
|
||||||
}
|
}
|
||||||
|
|
||||||
new (file_ptr.p) Undofile(req, ptr.i);
|
new (file_ptr.p) Undofile(req, ptr.i);
|
||||||
LocalDLFifoList<Undofile> tmp(m_file_pool, ptr.p->m_meta_files);
|
|
||||||
|
Local_undofile_list tmp(m_file_pool, ptr.p->m_meta_files);
|
||||||
tmp.add(file_ptr);
|
tmp.add(file_ptr);
|
||||||
|
|
||||||
open_file(signal, file_ptr, req->requestInfo);
|
open_file(signal, file_ptr, req->requestInfo);
|
||||||
|
@ -636,7 +650,7 @@ Lgman::execFSOPENREF(Signal* signal)
|
||||||
CreateFileImplRef::SignalLength, JBB);
|
CreateFileImplRef::SignalLength, JBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDLFifoList<Undofile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
meta.release(ptr);
|
meta.release(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,9 +684,9 @@ Lgman::execFSOPENCONF(Signal* signal)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Lgman::find_file_by_id(Ptr<Undofile>& ptr,
|
Lgman::find_file_by_id(Ptr<Undofile>& ptr,
|
||||||
DLFifoList<Undofile>::Head& head, Uint32 id)
|
Local_undofile_list::Head& head, Uint32 id)
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Undofile> list(m_file_pool, head);
|
Local_undofile_list list(m_file_pool, head);
|
||||||
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
||||||
if(ptr.p->m_file_id == id)
|
if(ptr.p->m_file_id == id)
|
||||||
return true;
|
return true;
|
||||||
|
@ -691,8 +705,8 @@ Lgman::create_file_commit(Signal* signal,
|
||||||
if(ptr.p->m_state == Undofile::FS_CREATING)
|
if(ptr.p->m_state == Undofile::FS_CREATING)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLFifoList<Undofile> free(m_file_pool, lg_ptr.p->m_files);
|
Local_undofile_list free(m_file_pool, lg_ptr.p->m_files);
|
||||||
LocalDLFifoList<Undofile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
first= free.isEmpty();
|
first= free.isEmpty();
|
||||||
meta.remove(ptr);
|
meta.remove(ptr);
|
||||||
if(!first)
|
if(!first)
|
||||||
|
@ -799,7 +813,7 @@ Lgman::execFSCLOSECONF(Signal* signal)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Undofile> list(m_file_pool, lg_ptr.p->m_files);
|
Local_undofile_list list(m_file_pool, lg_ptr.p->m_files);
|
||||||
list.release(ptr);
|
list.release(ptr);
|
||||||
}
|
}
|
||||||
drop_filegroup_drop_files(signal, lg_ptr, senderRef, senderData);
|
drop_filegroup_drop_files(signal, lg_ptr, senderRef, senderData);
|
||||||
|
@ -807,7 +821,7 @@ Lgman::execFSCLOSECONF(Signal* signal)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLFifoList<Undofile> list(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_undofile_list list(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
list.release(ptr);
|
list.release(ptr);
|
||||||
|
|
||||||
CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
|
CreateFileImplConf* conf= (CreateFileImplConf*)signal->getDataPtr();
|
||||||
|
@ -859,9 +873,6 @@ Lgman::Logfile_group::Logfile_group(const CreateFilegroupImplReq* req)
|
||||||
bool
|
bool
|
||||||
Lgman::alloc_logbuffer_memory(Ptr<Logfile_group> ptr, Uint32 bytes)
|
Lgman::alloc_logbuffer_memory(Ptr<Logfile_group> ptr, Uint32 bytes)
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* TODO use buddy allocator
|
|
||||||
*/
|
|
||||||
Uint32 pages= (((bytes + 3) >> 2) + File_formats::NDB_PAGE_SIZE_WORDS - 1)
|
Uint32 pages= (((bytes + 3) >> 2) + File_formats::NDB_PAGE_SIZE_WORDS - 1)
|
||||||
/ File_formats::NDB_PAGE_SIZE_WORDS;
|
/ File_formats::NDB_PAGE_SIZE_WORDS;
|
||||||
Uint32 requested= pages;
|
Uint32 requested= pages;
|
||||||
|
@ -869,14 +880,14 @@ Lgman::alloc_logbuffer_memory(Ptr<Logfile_group> ptr, Uint32 bytes)
|
||||||
Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
|
Page_map map(m_data_buffer_pool, ptr.p->m_buffer_pages);
|
||||||
while(pages)
|
while(pages)
|
||||||
{
|
{
|
||||||
Ptr<GlobalPage> page;
|
Uint32 ptrI;
|
||||||
if(m_global_page_pool.seize(page))
|
Uint32 cnt = pages > 64 ? 64 : pages;
|
||||||
|
m_ctx.m_mm.alloc(&ptrI, &cnt, 1);
|
||||||
|
if (cnt)
|
||||||
{
|
{
|
||||||
Buffer_idx range;
|
Buffer_idx range;
|
||||||
range.m_ptr_i= page.i;
|
range.m_ptr_i= ptrI;
|
||||||
range.m_idx = 1;
|
range.m_idx = cnt;
|
||||||
while(pages >range.m_idx && m_global_page_pool.seizeId(page, page.i+1))
|
|
||||||
range.m_idx++;
|
|
||||||
|
|
||||||
ndbrequire(map.append((Uint32*)&range, 2));
|
ndbrequire(map.append((Uint32*)&range, 2));
|
||||||
pages -= range.m_idx;
|
pages -= range.m_idx;
|
||||||
|
@ -957,7 +968,7 @@ Lgman::compute_free_file_pages(Ptr<Logfile_group> ptr)
|
||||||
{
|
{
|
||||||
Ptr<Undofile> file;
|
Ptr<Undofile> file;
|
||||||
m_file_pool.getPtr(file, head.m_ptr_i);
|
m_file_pool.getPtr(file, head.m_ptr_i);
|
||||||
LocalDLFifoList<Undofile> list(m_file_pool, ptr.p->m_files);
|
Local_undofile_list list(m_file_pool, ptr.p->m_files);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -989,12 +1000,8 @@ Lgman::free_logbuffer_memory(Ptr<Logfile_group> ptr)
|
||||||
tmp[0] = *it.data;
|
tmp[0] = *it.data;
|
||||||
ndbrequire(map.next(it));
|
ndbrequire(map.next(it));
|
||||||
tmp[1] = *it.data;
|
tmp[1] = *it.data;
|
||||||
while(range.m_idx)
|
|
||||||
{
|
m_ctx.m_mm.release(range.m_ptr_i, range.m_idx);
|
||||||
m_global_page_pool.release(range.m_ptr_i);
|
|
||||||
range.m_ptr_i++;
|
|
||||||
range.m_idx--;
|
|
||||||
}
|
|
||||||
map.next(it);
|
map.next(it);
|
||||||
}
|
}
|
||||||
map.release();
|
map.release();
|
||||||
|
@ -1039,7 +1046,7 @@ Logfile_client::sync_lsn(Signal* signal,
|
||||||
bool empty= false;
|
bool empty= false;
|
||||||
Ptr<Lgman::Log_waiter> wait;
|
Ptr<Lgman::Log_waiter> wait;
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Lgman::Log_waiter>
|
Lgman::Local_log_waiter_list
|
||||||
list(m_lgman->m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
list(m_lgman->m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
||||||
|
|
||||||
empty= list.isEmpty();
|
empty= list.isEmpty();
|
||||||
|
@ -1076,8 +1083,7 @@ Lgman::force_log_sync(Signal* signal,
|
||||||
Ptr<Logfile_group> ptr,
|
Ptr<Logfile_group> ptr,
|
||||||
Uint32 lsn_hi, Uint32 lsn_lo)
|
Uint32 lsn_hi, Uint32 lsn_lo)
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Lgman::Log_waiter>
|
Local_log_waiter_list list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
||||||
list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
|
||||||
Uint64 force_lsn = lsn_hi; force_lsn <<= 32; force_lsn += lsn_lo;
|
Uint64 force_lsn = lsn_hi; force_lsn <<= 32; force_lsn += lsn_lo;
|
||||||
|
|
||||||
if(ptr.p->m_last_sync_req_lsn < force_lsn)
|
if(ptr.p->m_last_sync_req_lsn < force_lsn)
|
||||||
|
@ -1086,7 +1092,7 @@ Lgman::force_log_sync(Signal* signal,
|
||||||
* Do force
|
* Do force
|
||||||
*/
|
*/
|
||||||
Buffer_idx pos= ptr.p->m_pos[PRODUCER].m_current_pos;
|
Buffer_idx pos= ptr.p->m_pos[PRODUCER].m_current_pos;
|
||||||
GlobalPage *page = m_global_page_pool.getPtr(pos.m_ptr_i);
|
GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
|
||||||
|
|
||||||
Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
|
Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
|
||||||
if(pos.m_idx) // don't flush empty page...
|
if(pos.m_idx) // don't flush empty page...
|
||||||
|
@ -1136,7 +1142,7 @@ Lgman::force_log_sync(Signal* signal,
|
||||||
void
|
void
|
||||||
Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Log_waiter>
|
Local_log_waiter_list
|
||||||
list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
list(m_log_waiter_pool, ptr.p->m_log_sync_waiters);
|
||||||
|
|
||||||
if(list.isEmpty())
|
if(list.isEmpty())
|
||||||
|
@ -1155,7 +1161,7 @@ Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
SimulatedBlock* b = globalData.getBlock(block);
|
SimulatedBlock* b = globalData.getBlock(block);
|
||||||
b->execute(signal, waiter.p->m_callback, 0);
|
b->execute(signal, waiter.p->m_callback, 0);
|
||||||
|
|
||||||
list.release(waiter);
|
list.releaseFirst(waiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(removed && !list.isEmpty())
|
if(removed && !list.isEmpty())
|
||||||
|
@ -1176,7 +1182,7 @@ Uint32*
|
||||||
Lgman::get_log_buffer(Ptr<Logfile_group> ptr, Uint32 sz)
|
Lgman::get_log_buffer(Ptr<Logfile_group> ptr, Uint32 sz)
|
||||||
{
|
{
|
||||||
GlobalPage *page;
|
GlobalPage *page;
|
||||||
page=m_global_page_pool.getPtr(ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i);
|
page=m_shared_page_pool.getPtr(ptr.p->m_pos[PRODUCER].m_current_pos.m_ptr_i);
|
||||||
|
|
||||||
Uint32 total_free= ptr.p->m_free_buffer_words;
|
Uint32 total_free= ptr.p->m_free_buffer_words;
|
||||||
assert(total_free >= sz);
|
assert(total_free >= sz);
|
||||||
|
@ -1214,7 +1220,7 @@ next:
|
||||||
pos= 0;
|
pos= 0;
|
||||||
assert(total_free >= free);
|
assert(total_free >= free);
|
||||||
total_free -= free;
|
total_free -= free;
|
||||||
page= m_global_page_pool.getPtr(next_page(ptr.p, PRODUCER));
|
page= m_shared_page_pool.getPtr(next_page(ptr.p, PRODUCER));
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1271,7 +1277,7 @@ Logfile_client::get_log_buffer(Signal* signal, Uint32 sz,
|
||||||
bool empty= false;
|
bool empty= false;
|
||||||
{
|
{
|
||||||
Ptr<Lgman::Log_waiter> wait;
|
Ptr<Lgman::Log_waiter> wait;
|
||||||
LocalDLFifoList<Lgman::Log_waiter>
|
Lgman::Local_log_waiter_list
|
||||||
list(m_lgman->m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
list(m_lgman->m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
||||||
|
|
||||||
empty= list.isEmpty();
|
empty= list.isEmpty();
|
||||||
|
@ -1352,7 +1358,7 @@ Lgman::flush_log(Signal* signal, Ptr<Logfile_group> ptr, Uint32 force)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Buffer_idx pos= producer.m_current_pos;
|
Buffer_idx pos= producer.m_current_pos;
|
||||||
GlobalPage *page = m_global_page_pool.getPtr(pos.m_ptr_i);
|
GlobalPage *page = m_shared_page_pool.getPtr(pos.m_ptr_i);
|
||||||
|
|
||||||
Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
|
Uint32 free= File_formats::UNDO_PAGE_WORDS - pos.m_idx;
|
||||||
|
|
||||||
|
@ -1497,7 +1503,7 @@ void
|
||||||
Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
{
|
{
|
||||||
Uint32 free_buffer= ptr.p->m_free_buffer_words;
|
Uint32 free_buffer= ptr.p->m_free_buffer_words;
|
||||||
LocalDLFifoList<Log_waiter>
|
Local_log_waiter_list
|
||||||
list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
list(m_log_waiter_pool, ptr.p->m_log_buffer_waiters);
|
||||||
|
|
||||||
if(list.isEmpty())
|
if(list.isEmpty())
|
||||||
|
@ -1516,7 +1522,7 @@ Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
SimulatedBlock* b = globalData.getBlock(block);
|
SimulatedBlock* b = globalData.getBlock(block);
|
||||||
b->execute(signal, waiter.p->m_callback, 0);
|
b->execute(signal, waiter.p->m_callback, 0);
|
||||||
|
|
||||||
list.release(waiter);
|
list.releaseFirst(waiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(removed && !list.isEmpty())
|
if(removed && !list.isEmpty())
|
||||||
|
@ -1571,7 +1577,7 @@ Lgman::write_log_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
req->data.pageData[0] = pageId;
|
req->data.pageData[0] = pageId;
|
||||||
req->operationFlag = 0;
|
req->operationFlag = 0;
|
||||||
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
||||||
FsReadWriteReq::fsFormatGlobalPage);
|
FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
|
||||||
if(max > pages)
|
if(max > pages)
|
||||||
{
|
{
|
||||||
|
@ -1592,7 +1598,7 @@ Lgman::write_log_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
|
filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
|
||||||
|
|
||||||
File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
|
File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
|
||||||
m_global_page_pool.getPtr(pageId + max - 1);
|
m_shared_page_pool.getPtr(pageId + max - 1);
|
||||||
Uint64 lsn = 0;
|
Uint64 lsn = 0;
|
||||||
lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
|
lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
|
||||||
lsn += page->m_page_header.m_page_lsn_lo;
|
lsn += page->m_page_header.m_page_lsn_lo;
|
||||||
|
@ -1618,7 +1624,7 @@ Lgman::write_log_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
|
filePtr.p->m_state |= Undofile::FS_OUTSTANDING;
|
||||||
|
|
||||||
File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
|
File_formats::Undofile::Undo_page *page= (File_formats::Undofile::Undo_page*)
|
||||||
m_global_page_pool.getPtr(pageId + max - 1);
|
m_shared_page_pool.getPtr(pageId + max - 1);
|
||||||
Uint64 lsn = 0;
|
Uint64 lsn = 0;
|
||||||
lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
|
lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
|
||||||
lsn += page->m_page_header.m_page_lsn_lo;
|
lsn += page->m_page_header.m_page_lsn_lo;
|
||||||
|
@ -1627,7 +1633,7 @@ Lgman::write_log_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
ptr.p->m_last_sync_req_lsn = lsn; // And logfile_group
|
ptr.p->m_last_sync_req_lsn = lsn; // And logfile_group
|
||||||
|
|
||||||
Ptr<Undofile> next = filePtr;
|
Ptr<Undofile> next = filePtr;
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, ptr.p->m_files);
|
||||||
if(!files.next(next))
|
if(!files.next(next))
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
|
@ -1678,7 +1684,7 @@ Lgman::execFSWRITECONF(Signal* signal)
|
||||||
Uint32 tot= 0;
|
Uint32 tot= 0;
|
||||||
Uint64 lsn = 0;
|
Uint64 lsn = 0;
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, lg_ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
|
||||||
while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
|
while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
|
||||||
{
|
{
|
||||||
Uint32 state= ptr.p->m_state;
|
Uint32 state= ptr.p->m_state;
|
||||||
|
@ -1883,7 +1889,7 @@ Lgman::cut_log_tail(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
ptr.p->m_free_file_words += free * File_formats::UNDO_PAGE_WORDS;
|
||||||
|
|
||||||
Ptr<Undofile> next = filePtr;
|
Ptr<Undofile> next = filePtr;
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, ptr.p->m_files);
|
||||||
while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
|
while(files.next(next) && (next.p->m_state & Undofile::FS_EMPTY))
|
||||||
ndbrequire(next.i != filePtr.i);
|
ndbrequire(next.i != filePtr.i);
|
||||||
if(next.isNull())
|
if(next.isNull())
|
||||||
|
@ -2078,7 +2084,7 @@ Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
/**
|
/**
|
||||||
* Read first page from each undofile (1 file at a time...)
|
* Read first page from each undofile (1 file at a time...)
|
||||||
*/
|
*/
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_meta_files);
|
Local_undofile_list files(m_file_pool, ptr.p->m_meta_files);
|
||||||
Ptr<Undofile> file_ptr;
|
Ptr<Undofile> file_ptr;
|
||||||
files.first(file_ptr);
|
files.first(file_ptr);
|
||||||
|
|
||||||
|
@ -2099,7 +2105,7 @@ Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
req->data.pageData[0] = page_id;
|
req->data.pageData[0] = page_id;
|
||||||
req->operationFlag = 0;
|
req->operationFlag = 0;
|
||||||
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
||||||
FsReadWriteReq::fsFormatGlobalPage);
|
FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
|
||||||
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
||||||
FsReadWriteReq::FixedLength + 1, JBA);
|
FsReadWriteReq::FixedLength + 1, JBA);
|
||||||
|
@ -2115,7 +2121,7 @@ Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
* and m_files is sorted acording to lsn
|
* and m_files is sorted acording to lsn
|
||||||
*/
|
*/
|
||||||
ndbrequire(!ptr.p->m_files.isEmpty());
|
ndbrequire(!ptr.p->m_files.isEmpty());
|
||||||
LocalDLFifoList<Undofile> read_files(m_file_pool, ptr.p->m_files);
|
Local_undofile_list read_files(m_file_pool, ptr.p->m_files);
|
||||||
read_files.last(file_ptr);
|
read_files.last(file_ptr);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2140,7 +2146,7 @@ Lgman::find_log_head(Signal* signal, Ptr<Logfile_group> ptr)
|
||||||
req->data.pageData[0] = page_id;
|
req->data.pageData[0] = page_id;
|
||||||
req->operationFlag = 0;
|
req->operationFlag = 0;
|
||||||
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
||||||
FsReadWriteReq::fsFormatGlobalPage);
|
FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
|
||||||
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
||||||
FsReadWriteReq::FixedLength + 1, JBA);
|
FsReadWriteReq::FixedLength + 1, JBA);
|
||||||
|
@ -2176,7 +2182,7 @@ Lgman::execFSREADCONF(Signal* signal)
|
||||||
if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
|
if(lg_ptr.p->m_next_reply_ptr_i == ptr.i)
|
||||||
{
|
{
|
||||||
Uint32 tot= 0;
|
Uint32 tot= 0;
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, lg_ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
|
||||||
while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
|
while(cnt && ! (ptr.p->m_state & Undofile::FS_OUTSTANDING))
|
||||||
{
|
{
|
||||||
Uint32 state= ptr.p->m_state;
|
Uint32 state= ptr.p->m_state;
|
||||||
|
@ -2201,7 +2207,7 @@ Lgman::execFSREADCONF(Signal* signal)
|
||||||
lg_ptr.p->m_outstanding_fs = cnt - 1;
|
lg_ptr.p->m_outstanding_fs = cnt - 1;
|
||||||
|
|
||||||
Ptr<GlobalPage> page_ptr;
|
Ptr<GlobalPage> page_ptr;
|
||||||
m_global_page_pool.getPtr(page_ptr, ptr.p->m_online.m_outstanding);
|
m_shared_page_pool.getPtr(page_ptr, ptr.p->m_online.m_outstanding);
|
||||||
ptr.p->m_online.m_outstanding= 0;
|
ptr.p->m_online.m_outstanding= 0;
|
||||||
|
|
||||||
File_formats::Undofile::Undo_page* page =
|
File_formats::Undofile::Undo_page* page =
|
||||||
|
@ -2240,8 +2246,8 @@ Lgman::execFSREADCONF(Signal* signal)
|
||||||
* Insert into m_files
|
* Insert into m_files
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Undofile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_undofile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, lg_ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, lg_ptr.p->m_files);
|
||||||
meta.remove(ptr);
|
meta.remove(ptr);
|
||||||
|
|
||||||
Ptr<Undofile> loop;
|
Ptr<Undofile> loop;
|
||||||
|
@ -2333,7 +2339,7 @@ Lgman::find_log_head_in_file(Signal* signal,
|
||||||
req->data.pageData[0] = page_id;
|
req->data.pageData[0] = page_id;
|
||||||
req->operationFlag = 0;
|
req->operationFlag = 0;
|
||||||
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
||||||
FsReadWriteReq::fsFormatGlobalPage);
|
FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
|
||||||
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
sendSignal(NDBFS_REF, GSN_FSREADREQ, signal,
|
||||||
FsReadWriteReq::FixedLength + 1, JBA);
|
FsReadWriteReq::FixedLength + 1, JBA);
|
||||||
|
@ -2365,7 +2371,7 @@ Lgman::find_log_head_in_file(Signal* signal,
|
||||||
ptr.p->m_next_reply_ptr_i = file_ptr.i;
|
ptr.p->m_next_reply_ptr_i = file_ptr.i;
|
||||||
|
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, ptr.p->m_files);
|
||||||
if(tail == 1)
|
if(tail == 1)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -2418,8 +2424,8 @@ Lgman::init_run_undo_log(Signal* signal)
|
||||||
* Perform initial sorting of logfile groups
|
* Perform initial sorting of logfile groups
|
||||||
*/
|
*/
|
||||||
Ptr<Logfile_group> group;
|
Ptr<Logfile_group> group;
|
||||||
DLFifoList<Logfile_group>& list= m_logfile_group_list;
|
Logfile_group_list& list= m_logfile_group_list;
|
||||||
DLFifoList<Logfile_group> tmp(m_logfile_group_pool);
|
Logfile_group_list tmp(m_logfile_group_pool);
|
||||||
|
|
||||||
list.first(group);
|
list.first(group);
|
||||||
while(!group.isNull())
|
while(!group.isNull())
|
||||||
|
@ -2438,7 +2444,7 @@ Lgman::init_run_undo_log(Signal* signal)
|
||||||
|
|
||||||
Uint32 page = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
|
Uint32 page = ptr.p->m_pos[CONSUMER].m_current_pos.m_ptr_i;
|
||||||
File_formats::Undofile::Undo_page* pageP =
|
File_formats::Undofile::Undo_page* pageP =
|
||||||
(File_formats::Undofile::Undo_page*)m_global_page_pool.getPtr(page);
|
(File_formats::Undofile::Undo_page*)m_shared_page_pool.getPtr(page);
|
||||||
|
|
||||||
ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = pageP->m_words_used;
|
ptr.p->m_pos[CONSUMER].m_current_pos.m_idx = pageP->m_words_used;
|
||||||
ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 1;
|
ptr.p->m_pos[PRODUCER].m_current_pos.m_idx = 1;
|
||||||
|
@ -2578,7 +2584,7 @@ Lgman::read_undo_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
req->userPointer = filePtr.i;
|
req->userPointer = filePtr.i;
|
||||||
req->operationFlag = 0;
|
req->operationFlag = 0;
|
||||||
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
FsReadWriteReq::setFormatFlag(req->operationFlag,
|
||||||
FsReadWriteReq::fsFormatGlobalPage);
|
FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
|
||||||
|
|
||||||
if(max > pages)
|
if(max > pages)
|
||||||
|
@ -2626,11 +2632,13 @@ Lgman::read_undo_pages(Signal* signal, Ptr<Logfile_group> ptr,
|
||||||
filePtr.p->m_state |= Undofile::FS_OUTSTANDING | Undofile::FS_MOVE_NEXT;
|
filePtr.p->m_state |= Undofile::FS_OUTSTANDING | Undofile::FS_MOVE_NEXT;
|
||||||
|
|
||||||
Ptr<Undofile> prev = filePtr;
|
Ptr<Undofile> prev = filePtr;
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
|
||||||
if(!files.prev(prev))
|
|
||||||
{
|
{
|
||||||
jam();
|
Local_undofile_list files(m_file_pool, ptr.p->m_files);
|
||||||
files.last(prev);
|
if(!files.prev(prev))
|
||||||
|
{
|
||||||
|
jam();
|
||||||
|
files.last(prev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(DEBUG_UNDO_EXECUTION)
|
if(DEBUG_UNDO_EXECUTION)
|
||||||
ndbout_c("changing file from %d to %d", filePtr.i, prev.i);
|
ndbout_c("changing file from %d to %d", filePtr.i, prev.i);
|
||||||
|
@ -2717,7 +2725,7 @@ Lgman::get_next_undo_record(Uint64 * this_lsn)
|
||||||
Uint32 page = consumer.m_current_pos.m_ptr_i;
|
Uint32 page = consumer.m_current_pos.m_ptr_i;
|
||||||
|
|
||||||
File_formats::Undofile::Undo_page* pageP=(File_formats::Undofile::Undo_page*)
|
File_formats::Undofile::Undo_page* pageP=(File_formats::Undofile::Undo_page*)
|
||||||
m_global_page_pool.getPtr(page);
|
m_shared_page_pool.getPtr(page);
|
||||||
|
|
||||||
if(pos == 0)
|
if(pos == 0)
|
||||||
{
|
{
|
||||||
|
@ -2795,7 +2803,7 @@ Lgman::get_next_undo_record(Uint64 * this_lsn)
|
||||||
ndbout_c("reading from %d", consumer.m_current_pos.m_ptr_i);
|
ndbout_c("reading from %d", consumer.m_current_pos.m_ptr_i);
|
||||||
|
|
||||||
pageP=(File_formats::Undofile::Undo_page*)
|
pageP=(File_formats::Undofile::Undo_page*)
|
||||||
m_global_page_pool.getPtr(consumer.m_current_pos.m_ptr_i);
|
m_shared_page_pool.getPtr(consumer.m_current_pos.m_ptr_i);
|
||||||
|
|
||||||
pos= consumer.m_current_pos.m_idx= pageP->m_words_used;
|
pos= consumer.m_current_pos.m_idx= pageP->m_words_used;
|
||||||
|
|
||||||
|
@ -2885,7 +2893,7 @@ Lgman::stop_run_undo_log(Signal* signal)
|
||||||
if(pages >= diff)
|
if(pages >= diff)
|
||||||
{
|
{
|
||||||
pages -= diff;
|
pages -= diff;
|
||||||
LocalDLFifoList<Undofile> files(m_file_pool, ptr.p->m_files);
|
Local_undofile_list files(m_file_pool, ptr.p->m_files);
|
||||||
if(!files.next(file))
|
if(!files.next(file))
|
||||||
files.first(file);
|
files.first(file);
|
||||||
tail.m_idx = 1;
|
tail.m_idx = 1;
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#include "diskpage.hpp"
|
#include "diskpage.hpp"
|
||||||
#include <signaldata/GetTabInfo.hpp>
|
#include <signaldata/GetTabInfo.hpp>
|
||||||
|
|
||||||
|
#include <WOPool.hpp>
|
||||||
|
#include <SLFifoList.hpp>
|
||||||
|
|
||||||
class Lgman : public SimulatedBlock
|
class Lgman : public SimulatedBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -77,24 +80,26 @@ protected:
|
||||||
public:
|
public:
|
||||||
struct Log_waiter
|
struct Log_waiter
|
||||||
{
|
{
|
||||||
|
Callback m_callback;
|
||||||
union {
|
union {
|
||||||
Uint32 m_size;
|
Uint32 m_size;
|
||||||
Uint64 m_sync_lsn;
|
Uint64 m_sync_lsn;
|
||||||
};
|
};
|
||||||
Uint32 m_block;
|
Uint32 m_block;
|
||||||
Callback m_callback;
|
Uint32 nextList;
|
||||||
union {
|
Uint32 m_magic;
|
||||||
Uint32 nextPool;
|
|
||||||
Uint32 nextList;
|
|
||||||
};
|
|
||||||
Uint32 prevList;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Log_waiter, WOPool> Log_waiter_pool;
|
||||||
|
typedef SLFifoListImpl<Log_waiter_pool, Log_waiter> Log_waiter_list;
|
||||||
|
typedef LocalSLFifoListImpl<Log_waiter_pool, Log_waiter> Local_log_waiter_list;
|
||||||
|
|
||||||
struct Undofile
|
struct Undofile
|
||||||
{
|
{
|
||||||
Undofile(){}
|
Undofile(){}
|
||||||
Undofile(const struct CreateFileImplReq*, Uint32 lg_ptr_i);
|
Undofile(const struct CreateFileImplReq*, Uint32 lg_ptr_i);
|
||||||
|
|
||||||
|
Uint32 m_magic;
|
||||||
Uint32 m_file_id; // Dict obj id
|
Uint32 m_file_id; // Dict obj id
|
||||||
Uint32 m_logfile_group_ptr_i;
|
Uint32 m_logfile_group_ptr_i;
|
||||||
|
|
||||||
|
@ -136,6 +141,9 @@ public:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Undofile, RWPool> Undofile_pool;
|
||||||
|
typedef DLFifoListImpl<Undofile_pool, Undofile> Undofile_list;
|
||||||
|
typedef LocalDLFifoListImpl<Undofile_pool, Undofile> Local_undofile_list;
|
||||||
typedef LocalDataBuffer<15> Page_map;
|
typedef LocalDataBuffer<15> Page_map;
|
||||||
|
|
||||||
struct Buffer_idx
|
struct Buffer_idx
|
||||||
|
@ -152,6 +160,7 @@ public:
|
||||||
Logfile_group(){}
|
Logfile_group(){}
|
||||||
Logfile_group(const struct CreateFilegroupImplReq*);
|
Logfile_group(const struct CreateFilegroupImplReq*);
|
||||||
|
|
||||||
|
Uint32 m_magic;
|
||||||
union {
|
union {
|
||||||
Uint32 key;
|
Uint32 key;
|
||||||
Uint32 m_logfile_group_id;
|
Uint32 m_logfile_group_id;
|
||||||
|
@ -190,17 +199,17 @@ public:
|
||||||
Uint64 m_last_read_lsn;
|
Uint64 m_last_read_lsn;
|
||||||
Uint64 m_last_lcp_lsn;
|
Uint64 m_last_lcp_lsn;
|
||||||
};
|
};
|
||||||
DLFifoList<Log_waiter>::Head m_log_sync_waiters;
|
Log_waiter_list::Head m_log_sync_waiters;
|
||||||
|
|
||||||
Buffer_idx m_tail_pos[3]; // 0 is cut, 1 is saved, 2 is current
|
Buffer_idx m_tail_pos[3]; // 0 is cut, 1 is saved, 2 is current
|
||||||
Buffer_idx m_file_pos[2]; // 0 tail, 1 head = { file_ptr_i, page_no }
|
Buffer_idx m_file_pos[2]; // 0 tail, 1 head = { file_ptr_i, page_no }
|
||||||
Uint64 m_free_file_words; // Free words in logfile group
|
Uint64 m_free_file_words; // Free words in logfile group
|
||||||
|
|
||||||
DLFifoList<Undofile>::Head m_files; // Files in log
|
Undofile_list::Head m_files; // Files in log
|
||||||
DLFifoList<Undofile>::Head m_meta_files;// Files being created or dropped
|
Undofile_list::Head m_meta_files;// Files being created or dropped
|
||||||
|
|
||||||
Uint32 m_free_buffer_words; // Free buffer page words
|
Uint32 m_free_buffer_words; // Free buffer page words
|
||||||
DLFifoList<Log_waiter>::Head m_log_buffer_waiters;
|
Log_waiter_list::Head m_log_buffer_waiters;
|
||||||
Page_map::Head m_buffer_pages; // Pairs of { ptr.i, count }
|
Page_map::Head m_buffer_pages; // Pairs of { ptr.i, count }
|
||||||
struct Position {
|
struct Position {
|
||||||
Buffer_idx m_current_page; // { m_buffer_pages.i, left in range }
|
Buffer_idx m_current_page; // { m_buffer_pages.i, left in range }
|
||||||
|
@ -222,6 +231,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Logfile_group, RWPool> Logfile_group_pool;
|
||||||
|
typedef DLFifoListImpl<Logfile_group_pool, Logfile_group> Logfile_group_list;
|
||||||
|
typedef LocalDLFifoListImpl<Logfile_group_pool, Logfile_group> Local_logfile_group_list;
|
||||||
|
typedef KeyTableImpl<Logfile_group_pool, Logfile_group> Logfile_group_hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alloc/free space in log
|
* Alloc/free space in log
|
||||||
* Alloction will be removed at either/or
|
* Alloction will be removed at either/or
|
||||||
|
@ -233,16 +247,17 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Logfile_client;
|
friend class Logfile_client;
|
||||||
ArrayPool<Undofile> m_file_pool;
|
|
||||||
ArrayPool<Logfile_group> m_logfile_group_pool;
|
Undofile_pool m_file_pool;
|
||||||
ArrayPool<Log_waiter> m_log_waiter_pool;
|
Logfile_group_pool m_logfile_group_pool;
|
||||||
|
Log_waiter_pool m_log_waiter_pool;
|
||||||
|
|
||||||
Page_map::DataBufferPool m_data_buffer_pool;
|
Page_map::DataBufferPool m_data_buffer_pool;
|
||||||
|
|
||||||
Uint64 m_last_lsn;
|
Uint64 m_last_lsn;
|
||||||
Uint32 m_latest_lcp;
|
Uint32 m_latest_lcp;
|
||||||
DLFifoList<Logfile_group> m_logfile_group_list;
|
Logfile_group_list m_logfile_group_list;
|
||||||
KeyTable<Logfile_group> m_logfile_group_hash;
|
Logfile_group_hash m_logfile_group_hash;
|
||||||
|
|
||||||
bool alloc_logbuffer_memory(Ptr<Logfile_group>, Uint32 pages);
|
bool alloc_logbuffer_memory(Ptr<Logfile_group>, Uint32 pages);
|
||||||
void init_logbuffer_pointers(Ptr<Logfile_group>);
|
void init_logbuffer_pointers(Ptr<Logfile_group>);
|
||||||
|
@ -276,7 +291,7 @@ private:
|
||||||
void stop_run_undo_log(Signal* signal);
|
void stop_run_undo_log(Signal* signal);
|
||||||
void init_tail_ptr(Signal* signal, Ptr<Logfile_group> ptr);
|
void init_tail_ptr(Signal* signal, Ptr<Logfile_group> ptr);
|
||||||
|
|
||||||
bool find_file_by_id(Ptr<Undofile>&, DLFifoList<Undofile>::Head&, Uint32 id);
|
bool find_file_by_id(Ptr<Undofile>&, Undofile_list::Head&, Uint32 id);
|
||||||
void create_file_commit(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
|
void create_file_commit(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
|
||||||
void create_file_abort(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
|
void create_file_abort(Signal* signal, Ptr<Logfile_group>, Ptr<Undofile>);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ static BlockInfo ALL_BLOCKS[] = {
|
||||||
static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo);
|
static const Uint32 ALL_BLOCKS_SZ = sizeof(ALL_BLOCKS)/sizeof(BlockInfo);
|
||||||
|
|
||||||
static BlockReference readConfigOrder[ALL_BLOCKS_SZ] = {
|
static BlockReference readConfigOrder[ALL_BLOCKS_SZ] = {
|
||||||
|
CMVMI_REF,
|
||||||
DBTUP_REF,
|
DBTUP_REF,
|
||||||
DBACC_REF,
|
DBACC_REF,
|
||||||
DBTC_REF,
|
DBTC_REF,
|
||||||
|
@ -100,7 +101,6 @@ static BlockReference readConfigOrder[ALL_BLOCKS_SZ] = {
|
||||||
NDBFS_REF,
|
NDBFS_REF,
|
||||||
NDBCNTR_REF,
|
NDBCNTR_REF,
|
||||||
QMGR_REF,
|
QMGR_REF,
|
||||||
CMVMI_REF,
|
|
||||||
TRIX_REF,
|
TRIX_REF,
|
||||||
BACKUP_REF,
|
BACKUP_REF,
|
||||||
DBUTIL_REF,
|
DBUTIL_REF,
|
||||||
|
|
|
@ -325,14 +325,17 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
||||||
request->action = (Request::Action) action;
|
request->action = (Request::Action) action;
|
||||||
request->theTrace = signal->getTrace();
|
request->theTrace = signal->getTrace();
|
||||||
|
|
||||||
|
Uint32 format = fsRWReq->getFormatFlag(fsRWReq->operationFlag);
|
||||||
|
|
||||||
if (fsRWReq->numberOfPages == 0) { //Zero pages not allowed
|
if (fsRWReq->numberOfPages == 0) { //Zero pages not allowed
|
||||||
jam();
|
jam();
|
||||||
errorCode = FsRef::fsErrInvalidParameters;
|
errorCode = FsRef::fsErrInvalidParameters;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fsRWReq->getFormatFlag(fsRWReq->operationFlag) !=
|
if(format != FsReadWriteReq::fsFormatGlobalPage &&
|
||||||
FsReadWriteReq::fsFormatGlobalPage){
|
format != FsReadWriteReq::fsFormatSharedPage)
|
||||||
|
{
|
||||||
if (fsRWReq->varIndex >= getBatSize(blockNumber)) {
|
if (fsRWReq->varIndex >= getBatSize(blockNumber)) {
|
||||||
jam();// Ensure that a valid variable is used
|
jam();// Ensure that a valid variable is used
|
||||||
errorCode = FsRef::fsErrInvalidParameters;
|
errorCode = FsRef::fsErrInvalidParameters;
|
||||||
|
@ -353,7 +356,7 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
||||||
tNRR = myBaseAddrRef->nrr;
|
tNRR = myBaseAddrRef->nrr;
|
||||||
tWA = (char*)myBaseAddrRef->WA;
|
tWA = (char*)myBaseAddrRef->WA;
|
||||||
|
|
||||||
switch (fsRWReq->getFormatFlag(fsRWReq->operationFlag)) {
|
switch (format) {
|
||||||
|
|
||||||
// List of memory and file pages pairs
|
// List of memory and file pages pairs
|
||||||
case FsReadWriteReq::fsFormatListOfPairs: {
|
case FsReadWriteReq::fsFormatListOfPairs: {
|
||||||
|
@ -422,7 +425,9 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
||||||
goto error;
|
goto error;
|
||||||
}//default
|
}//default
|
||||||
}//switch
|
}//switch
|
||||||
} else {
|
}
|
||||||
|
else if (format == FsReadWriteReq::fsFormatGlobalPage)
|
||||||
|
{
|
||||||
Ptr<GlobalPage> ptr;
|
Ptr<GlobalPage> ptr;
|
||||||
m_global_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
|
m_global_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
|
||||||
request->par.readWrite.pages[0].buf = (char*)ptr.p;
|
request->par.readWrite.pages[0].buf = (char*)ptr.p;
|
||||||
|
@ -430,10 +435,20 @@ Ndbfs::readWriteRequest(int action, Signal * signal)
|
||||||
request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
|
request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
|
||||||
request->par.readWrite.numberOfPages = 1;
|
request->par.readWrite.numberOfPages = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ndbrequire(format == FsReadWriteReq::fsFormatSharedPage);
|
||||||
|
Ptr<GlobalPage> ptr;
|
||||||
|
m_shared_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
|
||||||
|
request->par.readWrite.pages[0].buf = (char*)ptr.p;
|
||||||
|
request->par.readWrite.pages[0].size = ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->numberOfPages;
|
||||||
|
request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
|
||||||
|
request->par.readWrite.numberOfPages = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ndbrequire(forward(openFile, request));
|
ndbrequire(forward(openFile, request));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
theRequestPool->put(request);
|
theRequestPool->put(request);
|
||||||
FsRef * const fsRef = (FsRef *)&signal->theData[0];
|
FsRef * const fsRef = (FsRef *)&signal->theData[0];
|
||||||
|
|
|
@ -89,7 +89,7 @@ Pgman::Pgman(Block_context& ctx) :
|
||||||
m_cleanup_ptr.i = RNIL;
|
m_cleanup_ptr.i = RNIL;
|
||||||
|
|
||||||
// should be a factor larger than number of pool pages
|
// should be a factor larger than number of pool pages
|
||||||
m_data_buffer_pool.setSize(1);
|
m_data_buffer_pool.setSize(16);
|
||||||
m_page_hashlist.setSize(512);
|
m_page_hashlist.setSize(512);
|
||||||
|
|
||||||
for (Uint32 k = 0; k < Page_entry::SUBLIST_COUNT; k++)
|
for (Uint32 k = 0; k < Page_entry::SUBLIST_COUNT; k++)
|
||||||
|
@ -125,10 +125,13 @@ Pgman::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
{
|
{
|
||||||
page_buffer /= GLOBAL_PAGE_SIZE; // in pages
|
page_buffer /= GLOBAL_PAGE_SIZE; // in pages
|
||||||
m_page_entry_pool.setSize(100*page_buffer);
|
m_page_entry_pool.setSize(100*page_buffer);
|
||||||
m_page_request_pool.setSize(10000);
|
|
||||||
m_param.m_max_pages = page_buffer;
|
m_param.m_max_pages = page_buffer;
|
||||||
m_param.m_max_hot_pages = (page_buffer * 9) / 10;
|
m_param.m_max_hot_pages = (page_buffer * 9) / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = this;
|
||||||
|
m_page_request_pool.wo_pool_init(RT_PGMAN_PAGE_REQUEST, pc);
|
||||||
|
|
||||||
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
||||||
conf->senderRef = reference();
|
conf->senderRef = reference();
|
||||||
|
@ -977,8 +980,7 @@ Pgman::process_callback(Signal* signal, Ptr<Page_entry> ptr)
|
||||||
* Make sure list is in own scope if callback will access this
|
* Make sure list is in own scope if callback will access this
|
||||||
* list again (destructor restores list head).
|
* list again (destructor restores list head).
|
||||||
*/
|
*/
|
||||||
LocalDLFifoList<Page_request>
|
Local_page_request_list req_list(m_page_request_pool, ptr.p->m_requests);
|
||||||
req_list(m_page_request_pool, ptr.p->m_requests);
|
|
||||||
Ptr<Page_request> req_ptr;
|
Ptr<Page_request> req_ptr;
|
||||||
|
|
||||||
req_list.first(req_ptr);
|
req_list.first(req_ptr);
|
||||||
|
@ -988,8 +990,6 @@ Pgman::process_callback(Signal* signal, Ptr<Page_entry> ptr)
|
||||||
b = globalData.getBlock(req_ptr.p->m_block);
|
b = globalData.getBlock(req_ptr.p->m_block);
|
||||||
callback = req_ptr.p->m_callback;
|
callback = req_ptr.p->m_callback;
|
||||||
|
|
||||||
req_list.release(req_ptr);
|
|
||||||
|
|
||||||
if (req_ptr.p->m_flags & DIRTY_FLAGS)
|
if (req_ptr.p->m_flags & DIRTY_FLAGS)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
|
@ -997,6 +997,8 @@ Pgman::process_callback(Signal* signal, Ptr<Page_entry> ptr)
|
||||||
ndbassert(ptr.p->m_dirty_count);
|
ndbassert(ptr.p->m_dirty_count);
|
||||||
ptr.p->m_dirty_count --;
|
ptr.p->m_dirty_count --;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req_list.releaseFirst(req_ptr);
|
||||||
}
|
}
|
||||||
ndbrequire(state & Page_entry::BOUND);
|
ndbrequire(state & Page_entry::BOUND);
|
||||||
ndbrequire(state & Page_entry::MAPPED);
|
ndbrequire(state & Page_entry::MAPPED);
|
||||||
|
@ -1602,12 +1604,11 @@ Pgman::get_page(Signal* signal, Ptr<Page_entry> ptr, Page_request page_req)
|
||||||
// queue the request
|
// queue the request
|
||||||
Ptr<Pgman::Page_request> req_ptr;
|
Ptr<Pgman::Page_request> req_ptr;
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Page_request>
|
Local_page_request_list req_list(m_page_request_pool, ptr.p->m_requests);
|
||||||
req_list(m_page_request_pool, ptr.p->m_requests);
|
|
||||||
if (! (req_flags & Page_request::ALLOC_REQ))
|
if (! (req_flags & Page_request::ALLOC_REQ))
|
||||||
req_list.seize(req_ptr);
|
req_list.seizeLast(req_ptr);
|
||||||
else
|
else
|
||||||
req_list.seizeFront(req_ptr);
|
req_list.seizeFirst(req_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_ptr.i == RNIL)
|
if (req_ptr.i == RNIL)
|
||||||
|
@ -2171,7 +2172,7 @@ operator<<(NdbOut& out, Ptr<Pgman::Page_entry> ptr)
|
||||||
out << " busy_count=" << dec << pe.m_busy_count;
|
out << " busy_count=" << dec << pe.m_busy_count;
|
||||||
#ifdef VM_TRACE
|
#ifdef VM_TRACE
|
||||||
{
|
{
|
||||||
LocalDLFifoList<Pgman::Page_request>
|
Pgman::Local_page_request_list
|
||||||
req_list(ptr.p->m_this->m_page_request_pool, ptr.p->m_requests);
|
req_list(ptr.p->m_this->m_page_request_pool, ptr.p->m_requests);
|
||||||
if (! req_list.isEmpty())
|
if (! req_list.isEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -262,13 +262,14 @@ private:
|
||||||
Uint16 m_flags;
|
Uint16 m_flags;
|
||||||
SimulatedBlock::Callback m_callback;
|
SimulatedBlock::Callback m_callback;
|
||||||
|
|
||||||
union {
|
Uint32 nextList;
|
||||||
Uint32 nextPool;
|
Uint32 m_magic;
|
||||||
Uint32 nextList;
|
|
||||||
};
|
|
||||||
Uint32 prevList;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Page_request, WOPool> Page_request_pool;
|
||||||
|
typedef SLFifoListImpl<Page_request_pool, Page_request> Page_request_list;
|
||||||
|
typedef LocalSLFifoListImpl<Page_request_pool, Page_request> Local_page_request_list;
|
||||||
|
|
||||||
struct Page_entry_stack_ptr {
|
struct Page_entry_stack_ptr {
|
||||||
Uint32 nextList;
|
Uint32 nextList;
|
||||||
Uint32 prevList;
|
Uint32 prevList;
|
||||||
|
@ -338,7 +339,7 @@ private:
|
||||||
Uint32 nextPool;
|
Uint32 nextPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
DLFifoList<Page_request>::Head m_requests;
|
Page_request_list::Head m_requests;
|
||||||
|
|
||||||
Uint32 nextHash;
|
Uint32 nextHash;
|
||||||
Uint32 prevHash;
|
Uint32 prevHash;
|
||||||
|
@ -384,7 +385,7 @@ private:
|
||||||
File_map::DataBufferPool m_data_buffer_pool;
|
File_map::DataBufferPool m_data_buffer_pool;
|
||||||
|
|
||||||
// page entries and requests
|
// page entries and requests
|
||||||
ArrayPool<Page_request> m_page_request_pool;
|
Page_request_pool m_page_request_pool;
|
||||||
ArrayPool<Page_entry> m_page_entry_pool;
|
ArrayPool<Page_entry> m_page_entry_pool;
|
||||||
Page_hashlist m_page_hashlist;
|
Page_hashlist m_page_hashlist;
|
||||||
Page_stack m_page_stack;
|
Page_stack m_page_stack;
|
||||||
|
|
|
@ -17,17 +17,6 @@
|
||||||
#ifndef KERNEL_RECORDS_HPP
|
#ifndef KERNEL_RECORDS_HPP
|
||||||
#define KERNEL_RECORDS_HPP
|
#define KERNEL_RECORDS_HPP
|
||||||
|
|
||||||
/**
|
|
||||||
* Record types
|
|
||||||
*/
|
|
||||||
#define PGMAN_PAGE_REQUEST 1
|
|
||||||
|
|
||||||
#define LGMAN_LOG_BUFFER_WAITER 2
|
|
||||||
#define LGMAN_LOG_SYNC_WAITER 3
|
|
||||||
|
|
||||||
#define DBTUP_PAGE_REQUEST 4
|
|
||||||
#define DBTUP_EXTENT_INFO 5
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource groups
|
* Resource groups
|
||||||
*/
|
*/
|
||||||
|
@ -35,8 +24,7 @@
|
||||||
/**
|
/**
|
||||||
* Operations for dd
|
* Operations for dd
|
||||||
* PGMAN_PAGE_REQUEST
|
* PGMAN_PAGE_REQUEST
|
||||||
* LGMAN_LOG_BUFFER_WAITER
|
* LGMAN_LOG_WAITER
|
||||||
* LGMAN_LOG_SYNC_WAITER
|
|
||||||
* DBTUP_PAGE_REQUEST
|
* DBTUP_PAGE_REQUEST
|
||||||
*/
|
*/
|
||||||
#define RG_DISK_OPERATIONS 1
|
#define RG_DISK_OPERATIONS 1
|
||||||
|
@ -47,4 +35,25 @@
|
||||||
*/
|
*/
|
||||||
#define RG_DISK_RECORDS 2
|
#define RG_DISK_RECORDS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define RG_RESERVED 0
|
||||||
|
#define RG_COUNT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record types
|
||||||
|
*/
|
||||||
|
#define RT_PGMAN_PAGE_REQUEST MAKE_TID( 1, RG_DISK_OPERATIONS)
|
||||||
|
#define RT_LGMAN_LOG_WAITER MAKE_TID( 2, RG_DISK_OPERATIONS)
|
||||||
|
#define RT_DBTUP_PAGE_REQUEST MAKE_TID( 3, RG_DISK_OPERATIONS)
|
||||||
|
|
||||||
|
#define RT_DBTUP_EXTENT_INFO MAKE_TID( 4, RG_DISK_RECORDS)
|
||||||
|
#define RT_DBDICT_FILE MAKE_TID( 5, RG_DISK_RECORDS)
|
||||||
|
#define RT_DBDICT_FILEGROUP MAKE_TID( 6, RG_DISK_RECORDS)
|
||||||
|
#define RT_LGMAN_FILE MAKE_TID( 7, RG_DISK_RECORDS)
|
||||||
|
#define RT_LGMAN_FILEGROUP MAKE_TID( 8, RG_DISK_RECORDS)
|
||||||
|
#define RT_TSMAN_FILE MAKE_TID( 9, RG_DISK_RECORDS)
|
||||||
|
#define RT_TSMAN_FILEGROUP MAKE_TID(10, RG_DISK_RECORDS)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,9 +83,7 @@ Tsman::Tsman(Block_context& ctx,
|
||||||
|
|
||||||
addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ);
|
addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ);
|
||||||
|
|
||||||
m_tablespace_pool.setSize(10);
|
|
||||||
m_tablespace_hash.setSize(10);
|
m_tablespace_hash.setSize(10);
|
||||||
m_file_pool.setSize(10);
|
|
||||||
m_file_hash.setSize(10);
|
m_file_hash.setSize(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +107,12 @@ Tsman::execREAD_CONFIG_REQ(Signal* signal)
|
||||||
m_ctx.m_config.getOwnConfigIterator();
|
m_ctx.m_config.getOwnConfigIterator();
|
||||||
ndbrequire(p != 0);
|
ndbrequire(p != 0);
|
||||||
|
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = this;
|
||||||
|
|
||||||
|
m_file_pool.init(RT_TSMAN_FILE, pc);
|
||||||
|
m_tablespace_pool.init(RT_TSMAN_FILEGROUP, pc);
|
||||||
|
|
||||||
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
|
||||||
conf->senderRef = reference();
|
conf->senderRef = reference();
|
||||||
conf->senderData = senderData;
|
conf->senderData = senderData;
|
||||||
|
@ -431,10 +435,10 @@ Tsman::execDROP_FILEGROUP_REQ(Signal* signal){
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Tsman::find_file_by_id(Ptr<Datafile>& ptr,
|
Tsman::find_file_by_id(Ptr<Datafile>& ptr,
|
||||||
DLList<Datafile>::Head& head,
|
Datafile_list::Head& head,
|
||||||
Uint32 id)
|
Uint32 id)
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> list(m_file_pool, head);
|
Local_datafile_list list(m_file_pool, head);
|
||||||
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
for(list.first(ptr); !ptr.isNull(); list.next(ptr))
|
||||||
if(ptr.p->m_file_id == id)
|
if(ptr.p->m_file_id == id)
|
||||||
return true;
|
return true;
|
||||||
|
@ -522,7 +526,7 @@ Tsman::execCREATE_FILE_REQ(Signal* signal){
|
||||||
}
|
}
|
||||||
|
|
||||||
new (file_ptr.p) Datafile(req);
|
new (file_ptr.p) Datafile(req);
|
||||||
LocalDLList<Datafile> tmp(m_file_pool, ptr.p->m_meta_files);
|
Local_datafile_list tmp(m_file_pool, ptr.p->m_meta_files);
|
||||||
tmp.add(file_ptr);
|
tmp.add(file_ptr);
|
||||||
|
|
||||||
file_ptr.p->m_state = Datafile::FS_CREATING;
|
file_ptr.p->m_state = Datafile::FS_CREATING;
|
||||||
|
@ -649,7 +653,7 @@ Tsman::execFSCLOSECONF(Signal* signal)
|
||||||
|
|
||||||
{
|
{
|
||||||
m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
|
m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
|
||||||
LocalDLList<Datafile> list(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_datafile_list list(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
list.release(ptr);
|
list.release(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,7 +837,7 @@ Tsman::create_file_ref(Signal* signal,
|
||||||
sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_REF, signal,
|
sendSignal(ptr.p->m_create.m_senderRef, GSN_CREATE_FILE_REF, signal,
|
||||||
CreateFileImplRef::SignalLength, JBB);
|
CreateFileImplRef::SignalLength, JBB);
|
||||||
|
|
||||||
LocalDLList<Datafile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
meta.release(ptr);
|
meta.release(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,8 +1108,8 @@ Tsman::load_extent_page_callback(Signal* signal,
|
||||||
(getNodeState().getNodeRestartInProgress() &&
|
(getNodeState().getNodeRestartInProgress() &&
|
||||||
getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
|
getNodeState().starting.restartType == NodeState::ST_INITIAL_NODE_RESTART))
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> free(m_file_pool, ts_ptr.p->m_free_files);
|
Local_datafile_list free(m_file_pool, ts_ptr.p->m_free_files);
|
||||||
LocalDLList<Datafile> meta(m_file_pool, ts_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, ts_ptr.p->m_meta_files);
|
||||||
meta.remove(ptr);
|
meta.remove(ptr);
|
||||||
free.add(ptr);
|
free.add(ptr);
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1148,7 @@ Tsman::scan_tablespace(Signal* signal, Uint32 ptrI)
|
||||||
|
|
||||||
Ptr<Datafile> file_ptr;
|
Ptr<Datafile> file_ptr;
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
meta.first(file_ptr);
|
meta.first(file_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1249,18 +1253,18 @@ Tsman::scan_extent_headers(Signal* signal, Ptr<Datafile> ptr)
|
||||||
}
|
}
|
||||||
ptr.p->m_online.m_first_free_extent= firstFree;
|
ptr.p->m_online.m_first_free_extent= firstFree;
|
||||||
|
|
||||||
LocalDLList<Datafile> meta(m_file_pool, lg_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, lg_ptr.p->m_meta_files);
|
||||||
Ptr<Datafile> next = ptr;
|
Ptr<Datafile> next = ptr;
|
||||||
meta.next(next);
|
meta.next(next);
|
||||||
if(firstFree != RNIL)
|
if(firstFree != RNIL)
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> free(m_file_pool, lg_ptr.p->m_free_files);
|
Local_datafile_list free(m_file_pool, lg_ptr.p->m_free_files);
|
||||||
meta.remove(ptr);
|
meta.remove(ptr);
|
||||||
free.add(ptr);
|
free.add(ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> full(m_file_pool, lg_ptr.p->m_full_files);
|
Local_datafile_list full(m_file_pool, lg_ptr.p->m_full_files);
|
||||||
meta.remove(ptr);
|
meta.remove(ptr);
|
||||||
full.add(ptr);
|
full.add(ptr);
|
||||||
}
|
}
|
||||||
|
@ -1299,13 +1303,13 @@ Tsman::execDROP_FILE_REQ(Signal* signal)
|
||||||
if (find_file_by_id(file_ptr, fg_ptr.p->m_full_files, req.file_id))
|
if (find_file_by_id(file_ptr, fg_ptr.p->m_full_files, req.file_id))
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLList<Datafile> full(m_file_pool, fg_ptr.p->m_full_files);
|
Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
|
||||||
full.remove(file_ptr);
|
full.remove(file_ptr);
|
||||||
}
|
}
|
||||||
else if(find_file_by_id(file_ptr, fg_ptr.p->m_free_files, req.file_id))
|
else if(find_file_by_id(file_ptr, fg_ptr.p->m_free_files, req.file_id))
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLList<Datafile> free(m_file_pool, fg_ptr.p->m_free_files);
|
Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
|
||||||
free.remove(file_ptr);
|
free.remove(file_ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1314,7 +1318,7 @@ Tsman::execDROP_FILE_REQ(Signal* signal)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDLList<Datafile> meta(m_file_pool, fg_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
|
||||||
meta.add(file_ptr);
|
meta.add(file_ptr);
|
||||||
|
|
||||||
if (file_ptr.p->m_online.m_used_extent_cnt ||
|
if (file_ptr.p->m_online.m_used_extent_cnt ||
|
||||||
|
@ -1338,16 +1342,16 @@ Tsman::execDROP_FILE_REQ(Signal* signal)
|
||||||
case DropFileImplReq::Abort:{
|
case DropFileImplReq::Abort:{
|
||||||
ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
|
ndbrequire(find_file_by_id(file_ptr, fg_ptr.p->m_meta_files, req.file_id));
|
||||||
file_ptr.p->m_state = Datafile::FS_ONLINE;
|
file_ptr.p->m_state = Datafile::FS_ONLINE;
|
||||||
LocalDLList<Datafile> meta(m_file_pool, fg_ptr.p->m_meta_files);
|
Local_datafile_list meta(m_file_pool, fg_ptr.p->m_meta_files);
|
||||||
meta.remove(file_ptr);
|
meta.remove(file_ptr);
|
||||||
if (file_ptr.p->m_online.m_first_free_extent != RNIL)
|
if (file_ptr.p->m_online.m_first_free_extent != RNIL)
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> free(m_file_pool, fg_ptr.p->m_free_files);
|
Local_datafile_list free(m_file_pool, fg_ptr.p->m_free_files);
|
||||||
free.add(file_ptr);
|
free.add(file_ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> full(m_file_pool, fg_ptr.p->m_full_files);
|
Local_datafile_list full(m_file_pool, fg_ptr.p->m_full_files);
|
||||||
full.add(file_ptr);
|
full.add(file_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1407,7 +1411,7 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal)
|
||||||
|
|
||||||
ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
|
ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
|
||||||
Uint32 size = ts_ptr.p->m_extent_size;
|
Uint32 size = ts_ptr.p->m_extent_size;
|
||||||
LocalDLList<Datafile> tmp(m_file_pool, ts_ptr.p->m_free_files);
|
Local_datafile_list tmp(m_file_pool, ts_ptr.p->m_free_files);
|
||||||
|
|
||||||
if (tmp.first(file_ptr))
|
if (tmp.first(file_ptr))
|
||||||
{
|
{
|
||||||
|
@ -1456,7 +1460,7 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal)
|
||||||
if (next_free == RNIL)
|
if (next_free == RNIL)
|
||||||
{
|
{
|
||||||
jam();
|
jam();
|
||||||
LocalDLList<Datafile> full(m_file_pool, ts_ptr.p->m_full_files);
|
Local_datafile_list full(m_file_pool, ts_ptr.p->m_full_files);
|
||||||
tmp.remove(file_ptr);
|
tmp.remove(file_ptr);
|
||||||
full.add(file_ptr);
|
full.add(file_ptr);
|
||||||
}
|
}
|
||||||
|
@ -1988,7 +1992,7 @@ Tsman::end_lcp(Signal* signal, Uint32 ptrI, Uint32 list, Uint32 filePtrI)
|
||||||
switch(list){
|
switch(list){
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> tmp(m_file_pool, ptr.p->m_free_files);
|
Local_datafile_list tmp(m_file_pool, ptr.p->m_free_files);
|
||||||
if(file.i == RNIL)
|
if(file.i == RNIL)
|
||||||
{
|
{
|
||||||
if(!tmp.first(file))
|
if(!tmp.first(file))
|
||||||
|
@ -2005,7 +2009,7 @@ Tsman::end_lcp(Signal* signal, Uint32 ptrI, Uint32 list, Uint32 filePtrI)
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
LocalDLList<Datafile> tmp(m_file_pool, ptr.p->m_full_files);
|
Local_datafile_list tmp(m_file_pool, ptr.p->m_full_files);
|
||||||
if(file.i == RNIL)
|
if(file.i == RNIL)
|
||||||
{
|
{
|
||||||
if(!tmp.first(file))
|
if(!tmp.first(file))
|
||||||
|
@ -2046,8 +2050,8 @@ Tsman::end_lcp(Signal* signal, Uint32 ptrI, Uint32 list, Uint32 filePtrI)
|
||||||
file.p->m_online.m_lcp_free_extent_head = RNIL;
|
file.p->m_online.m_lcp_free_extent_head = RNIL;
|
||||||
file.p->m_online.m_lcp_free_extent_tail = RNIL;
|
file.p->m_online.m_lcp_free_extent_tail = RNIL;
|
||||||
|
|
||||||
LocalDLList<Datafile> free(m_file_pool, ptr.p->m_free_files);
|
Local_datafile_list free(m_file_pool, ptr.p->m_free_files);
|
||||||
LocalDLList<Datafile> full(m_file_pool, ptr.p->m_full_files);
|
Local_datafile_list full(m_file_pool, ptr.p->m_full_files);
|
||||||
full.remove(file);
|
full.remove(file);
|
||||||
free.add(file);
|
free.add(file);
|
||||||
}
|
}
|
||||||
|
@ -2151,7 +2155,7 @@ void Tsman::execGET_TABINFOREQ(Signal* signal)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLHashTable<Datafile>::Iterator iter;
|
Datafile_hash::Iterator iter;
|
||||||
ndbrequire(m_file_hash.first(iter));
|
ndbrequire(m_file_hash.first(iter));
|
||||||
|
|
||||||
while(iter.curr.p->m_file_id != tableId && m_file_hash.next(iter))
|
while(iter.curr.p->m_file_id != tableId && m_file_hash.next(iter))
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
* - Part of local key
|
* - Part of local key
|
||||||
* - Set by pgman
|
* - Set by pgman
|
||||||
*/
|
*/
|
||||||
|
Uint32 m_magic;
|
||||||
Uint32 m_file_no;
|
Uint32 m_file_no;
|
||||||
Uint32 m_file_id; // Used when talking to DICT
|
Uint32 m_file_id; // Used when talking to DICT
|
||||||
Uint32 m_fd; // NDBFS
|
Uint32 m_fd; // NDBFS
|
||||||
|
@ -136,12 +137,18 @@ public:
|
||||||
return m_file_no == rec.m_file_no;
|
return m_file_no == rec.m_file_no;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Datafile, RWPool> Datafile_pool;
|
||||||
|
typedef DLListImpl<Datafile_pool, Datafile> Datafile_list;
|
||||||
|
typedef LocalDLListImpl<Datafile_pool, Datafile> Local_datafile_list;
|
||||||
|
typedef DLHashTableImpl<Datafile_pool, Datafile> Datafile_hash;
|
||||||
|
|
||||||
struct Tablespace
|
struct Tablespace
|
||||||
{
|
{
|
||||||
Tablespace(){}
|
Tablespace(){}
|
||||||
Tablespace(Tsman*, Lgman*, const struct CreateFilegroupImplReq*);
|
Tablespace(Tsman*, Lgman*, const struct CreateFilegroupImplReq*);
|
||||||
|
|
||||||
|
Uint32 m_magic;
|
||||||
union {
|
union {
|
||||||
Uint32 key;
|
Uint32 key;
|
||||||
Uint32 m_tablespace_id;
|
Uint32 m_tablespace_id;
|
||||||
|
@ -157,11 +164,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
Uint32 m_extent_size; // In pages
|
Uint32 m_extent_size; // In pages
|
||||||
DLList<Datafile>::Head m_free_files; // Files w/ free space
|
Datafile_list::Head m_free_files; // Files w/ free space
|
||||||
Logfile_client m_logfile_client;
|
Logfile_client m_logfile_client;
|
||||||
|
|
||||||
DLList<Datafile>::Head m_full_files; // Files wo/ free space
|
Datafile_list::Head m_full_files; // Files wo/ free space
|
||||||
DLList<Datafile>::Head m_meta_files; // Files being created/dropped
|
Datafile_list::Head m_meta_files; // Files being created/dropped
|
||||||
|
|
||||||
Uint32 nextHash;
|
Uint32 nextHash;
|
||||||
Uint32 prevHash;
|
Uint32 prevHash;
|
||||||
|
@ -179,14 +186,19 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef RecordPool<Tablespace, RWPool> Tablespace_pool;
|
||||||
|
typedef DLListImpl<Tablespace_pool, Tablespace> Tablespace_list;
|
||||||
|
typedef LocalDLListImpl<Tablespace_pool, Tablespace> Local_tablespace_list;
|
||||||
|
typedef KeyTableImpl<Tablespace_pool, Tablespace> Tablespace_hash;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Tablespace_client;
|
friend class Tablespace_client;
|
||||||
ArrayPool<Datafile> m_file_pool;
|
Datafile_pool m_file_pool;
|
||||||
ArrayPool<Tablespace> m_tablespace_pool;
|
Tablespace_pool m_tablespace_pool;
|
||||||
|
|
||||||
DLHashTable<Datafile> m_file_hash;
|
Datafile_hash m_file_hash;
|
||||||
DLList<Tablespace> m_tablespace_list;
|
Tablespace_list m_tablespace_list;
|
||||||
KeyTable<Tablespace> m_tablespace_hash;
|
Tablespace_hash m_tablespace_hash;
|
||||||
Page_cache_client m_page_cache_client;
|
Page_cache_client m_page_cache_client;
|
||||||
Lgman * const m_lgman;
|
Lgman * const m_lgman;
|
||||||
|
|
||||||
|
@ -209,7 +221,7 @@ private:
|
||||||
void scan_datafile(Signal*, Uint32, Uint32);
|
void scan_datafile(Signal*, Uint32, Uint32);
|
||||||
void scan_extent_headers(Signal*, Ptr<Datafile>);
|
void scan_extent_headers(Signal*, Ptr<Datafile>);
|
||||||
|
|
||||||
bool find_file_by_id(Ptr<Datafile>&, DLList<Datafile>::Head&, Uint32 id);
|
bool find_file_by_id(Ptr<Datafile>&, Datafile_list::Head&, Uint32 id);
|
||||||
void create_file_abort(Signal* signal, Ptr<Datafile>);
|
void create_file_abort(Signal* signal, Ptr<Datafile>);
|
||||||
|
|
||||||
void release_extent_pages(Signal* signal, Ptr<Datafile> ptr);
|
void release_extent_pages(Signal* signal, Ptr<Datafile> ptr);
|
||||||
|
|
|
@ -406,7 +406,7 @@ int main(int argc, char** argv)
|
||||||
systemInfo(* theConfig, * theConfig->m_logLevel);
|
systemInfo(* theConfig, * theConfig->m_logLevel);
|
||||||
|
|
||||||
// Load blocks
|
// Load blocks
|
||||||
globalEmulatorData.theSimBlockList->load(* theConfig);
|
globalEmulatorData.theSimBlockList->load(globalEmulatorData);
|
||||||
|
|
||||||
// Set thread concurrency for Solaris' light weight processes
|
// Set thread concurrency for Solaris' light weight processes
|
||||||
int status;
|
int status;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
*/
|
*/
|
||||||
bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true, bool guard = true);
|
bool setSize(Uint32 noOfElements, bool align = false, bool exit_on_error = true, bool guard = true);
|
||||||
bool set(T*, Uint32 cnt, bool align = false);
|
bool set(T*, Uint32 cnt, bool align = false);
|
||||||
|
void clear() { theArray = 0; }
|
||||||
|
|
||||||
inline Uint32 getNoOfFree() const {
|
inline Uint32 getNoOfFree() const {
|
||||||
return noOfFree;
|
return noOfFree;
|
||||||
|
|
|
@ -17,20 +17,23 @@
|
||||||
#ifndef DLFIFOLIST_HPP
|
#ifndef DLFIFOLIST_HPP
|
||||||
#define DLFIFOLIST_HPP
|
#define DLFIFOLIST_HPP
|
||||||
|
|
||||||
#include "ArrayPool.hpp"
|
#include <ndb_global.h>
|
||||||
#include <NdbOut.hpp>
|
#include <kernel_types.h>
|
||||||
|
#include "Pool.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template class used for implementing an
|
* Template class used for implementing an
|
||||||
* list of object retreived from a pool
|
* list of object retreived from a pool
|
||||||
*/
|
*/
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class DLFifoList {
|
class DLFifoListImpl
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* List head
|
* List head
|
||||||
*/
|
*/
|
||||||
struct Head {
|
struct Head
|
||||||
|
{
|
||||||
Head();
|
Head();
|
||||||
Uint32 firstItem;
|
Uint32 firstItem;
|
||||||
Uint32 lastItem;
|
Uint32 lastItem;
|
||||||
|
@ -42,61 +45,26 @@ public:
|
||||||
inline bool isEmpty() const { return firstItem == RNIL;}
|
inline bool isEmpty() const { return firstItem == RNIL;}
|
||||||
};
|
};
|
||||||
|
|
||||||
DLFifoList(ArrayPool<T> & thePool);
|
DLFifoListImpl(P & thePool);
|
||||||
|
|
||||||
/**
|
bool seizeFirst(Ptr<T> &);
|
||||||
* Allocate an object from pool - update Ptr
|
bool seizeLast(Ptr<T> &);
|
||||||
*
|
bool seize(Ptr<T> & ptr) { return seizeLast(ptr);}
|
||||||
* Return i
|
|
||||||
*/
|
|
||||||
bool seize(Ptr<T> &);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate an object from pool - update Ptr - put in front of list
|
|
||||||
*
|
|
||||||
* Return i
|
|
||||||
*/
|
|
||||||
bool seizeFront(Ptr<T> &);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate object <b>i</b> from pool - update Ptr
|
|
||||||
*
|
|
||||||
* Return i
|
|
||||||
*/
|
|
||||||
bool seizeId(Ptr<T> &, Uint32 i);
|
|
||||||
|
|
||||||
/**
|
void release(Ptr<T> &);
|
||||||
* Add object to list
|
void release(); // release all
|
||||||
*
|
|
||||||
* @NOTE MUST be seized from correct pool
|
void addFirst(Ptr<T> &);
|
||||||
*/
|
void addLast(Ptr<T> &);
|
||||||
void add(Ptr<T> &);
|
void add(Ptr<T> & ptr) { addLast(ptr);}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert object <em>ptr</ptr> _before_ <em>loc</em>
|
* Insert object <em>ptr</ptr> _before_ <em>loc</em>
|
||||||
*/
|
*/
|
||||||
void insert(Ptr<T> & ptr, Ptr<T>& loc);
|
void insert(Ptr<T> & ptr, Ptr<T>& loc);
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove from list
|
|
||||||
*/
|
|
||||||
void remove(Ptr<T> &);
|
void remove(Ptr<T> &);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an object to pool
|
|
||||||
*/
|
|
||||||
void release(Uint32 i);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an object to pool
|
|
||||||
*/
|
|
||||||
void release(Ptr<T> &);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return all objects to the pool
|
|
||||||
*/
|
|
||||||
void release();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update i & p value according to <b>i</b>
|
* Update i & p value according to <b>i</b>
|
||||||
*/
|
*/
|
||||||
|
@ -119,7 +87,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool first(Ptr<T> &) const ;
|
bool first(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update ptr to first element in list
|
* Update ptr to first element in list
|
||||||
*
|
*
|
||||||
|
@ -134,7 +101,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool next(Ptr<T> &) const ;
|
bool next(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get next element
|
* Get next element
|
||||||
*
|
*
|
||||||
|
@ -148,61 +114,37 @@ public:
|
||||||
* NOTE ptr must be both p & i
|
* NOTE ptr must be both p & i
|
||||||
*/
|
*/
|
||||||
bool hasNext(const Ptr<T> &) const;
|
bool hasNext(const Ptr<T> &) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if prev exists i.e. this is not first
|
* Check if next exists i.e. this is not last
|
||||||
*
|
*
|
||||||
* NOTE ptr must be both p & i
|
* NOTE ptr must be both p & i
|
||||||
*/
|
*/
|
||||||
bool hasPrev(const Ptr<T> &) const;
|
bool hasPrev(const Ptr<T> &) const;
|
||||||
|
|
||||||
Uint32 noOfElements() const {
|
|
||||||
Uint32 c = 0;
|
|
||||||
Uint32 i = head.firstItem;
|
|
||||||
while(i != RNIL){
|
|
||||||
c++;
|
|
||||||
const T * t = thePool.getPtr(i);
|
|
||||||
i = t->U::nextList;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print
|
|
||||||
* (Run operator NdbOut<< on every element)
|
|
||||||
*/
|
|
||||||
void print(NdbOut & out) {
|
|
||||||
Uint32 i = head.firstItem;
|
|
||||||
while(i != RNIL){
|
|
||||||
T * t = thePool.getPtr(i);
|
|
||||||
out << (unsigned int) t << "[" << i << "]:";
|
|
||||||
t->print(out); out << " ";
|
|
||||||
i = t->U::nextList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isEmpty() const { return head.firstItem == RNIL;}
|
inline bool isEmpty() const { return head.firstItem == RNIL;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy list (head)
|
* Copy list (head)
|
||||||
* Will construct to identical lists
|
* Will construct to identical lists
|
||||||
*/
|
*/
|
||||||
DLFifoList<T>& operator=(const DLFifoList<T>& src){
|
DLFifoListImpl<P,T,U>& operator=(const DLFifoListImpl<P,T,U>& src){
|
||||||
assert(&thePool == &src.thePool);
|
assert(&thePool == &src.thePool);
|
||||||
this->head = src.head;
|
this->head = src.head;
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Head head;
|
Head head;
|
||||||
ArrayPool<T> & thePool;
|
P & thePool;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class LocalDLFifoList : public DLFifoList<T,U> {
|
class LocalDLFifoListImpl : public DLFifoListImpl<P,T,U>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
LocalDLFifoList(ArrayPool<T> & thePool, typename DLFifoList<T,U>::Head &_src)
|
LocalDLFifoListImpl(P & thePool, typename DLFifoListImpl<P,T,U>::Head &_src)
|
||||||
: DLFifoList<T,U>(thePool), src(_src)
|
: DLFifoListImpl<P,T,U>(thePool), src(_src)
|
||||||
{
|
{
|
||||||
this->head = src;
|
this->head = src;
|
||||||
#ifdef VM_TRACE
|
#ifdef VM_TRACE
|
||||||
|
@ -211,25 +153,27 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~LocalDLFifoList(){
|
~LocalDLFifoListImpl(){
|
||||||
#ifdef VM_TRACE
|
#ifdef VM_TRACE
|
||||||
assert(src.in_use == true);
|
assert(src.in_use == true);
|
||||||
#endif
|
#endif
|
||||||
src = this->head;
|
src = this->head;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
typename DLFifoList<T,U>::Head & src;
|
typename DLFifoListImpl<P,T,U>::Head & src;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLFifoList<T,U>::DLFifoList(ArrayPool<T> & _pool):
|
DLFifoListImpl<P,T,U>::DLFifoListImpl(P & _pool):
|
||||||
thePool(_pool){
|
thePool(_pool)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLFifoList<T,U>::Head::Head(){
|
DLFifoListImpl<P,T,U>::Head::Head()
|
||||||
|
{
|
||||||
firstItem = RNIL;
|
firstItem = RNIL;
|
||||||
lastItem = RNIL;
|
lastItem = RNIL;
|
||||||
#ifdef VM_TRACE
|
#ifdef VM_TRACE
|
||||||
|
@ -237,94 +181,83 @@ DLFifoList<T,U>::Head::Head(){
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
template <typename P, typename T, typename U>
|
||||||
* Allocate an object from pool - update Ptr
|
|
||||||
*
|
|
||||||
* Return i
|
|
||||||
*/
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::seize(Ptr<T> & p){
|
DLFifoListImpl<P,T,U>::seizeFirst(Ptr<T> & p)
|
||||||
thePool.seize(p);
|
{
|
||||||
if (p.i != RNIL) {
|
if (likely(thePool.seize(p)))
|
||||||
add(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
p.p = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
DLFifoList<T,U>::seizeFront(Ptr<T> & p){
|
|
||||||
Uint32 ff = head.firstItem;
|
|
||||||
thePool.seize(p);
|
|
||||||
if (p.i != RNIL)
|
|
||||||
{
|
{
|
||||||
p.p->U::prevList = RNIL;
|
addFirst(p);
|
||||||
p.p->U::nextList = ff;
|
|
||||||
head.firstItem = p.i;
|
|
||||||
if (ff == RNIL)
|
|
||||||
{
|
|
||||||
head.lastItem = p.i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
T * t2 = thePool.getPtr(ff);
|
|
||||||
t2->U::prevList = p.i;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
p.p = NULL;
|
p.p = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
template <typename P, typename T, typename U>
|
||||||
* Allocate an object from pool - update Ptr
|
|
||||||
*
|
|
||||||
* Return i
|
|
||||||
*/
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::seizeId(Ptr<T> & p, Uint32 ir){
|
DLFifoListImpl<P,T,U>::seizeLast(Ptr<T> & p)
|
||||||
thePool.seizeId(p, ir);
|
{
|
||||||
if(p.i != RNIL){
|
if (likely(thePool.seize(p)))
|
||||||
add(p);
|
{
|
||||||
|
addLast(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
p.p = NULL;
|
p.p = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::add(Ptr<T> & p){
|
DLFifoListImpl<P,T,U>::addFirst(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
Uint32 ff = head.firstItem;
|
||||||
|
|
||||||
|
p.p->U::prevList = RNIL;
|
||||||
|
p.p->U::nextList = ff;
|
||||||
|
head.firstItem = p.i;
|
||||||
|
if (ff == RNIL)
|
||||||
|
{
|
||||||
|
head.lastItem = p.i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
T * t2 = thePool.getPtr(ff);
|
||||||
|
t2->U::prevList = p.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
DLFifoListImpl<P,T,U>::addLast(Ptr<T> & p)
|
||||||
|
{
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
Uint32 last = head.lastItem;
|
Uint32 last = head.lastItem;
|
||||||
|
head.lastItem = p.i;
|
||||||
if(p.i == RNIL)
|
|
||||||
ErrorReporter::handleAssert("DLFifoList<T,U>::add", __FILE__, __LINE__);
|
|
||||||
|
|
||||||
t->U::nextList = RNIL;
|
t->U::nextList = RNIL;
|
||||||
t->U::prevList = last;
|
t->U::prevList = last;
|
||||||
if (head.firstItem == RNIL)
|
|
||||||
head.firstItem = p.i;
|
|
||||||
head.lastItem = p.i;
|
|
||||||
|
|
||||||
if(last != RNIL){
|
if(last != RNIL)
|
||||||
|
{
|
||||||
T * t2 = thePool.getPtr(last);
|
T * t2 = thePool.getPtr(last);
|
||||||
t2->U::nextList = p.i;
|
t2->U::nextList = p.i;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.firstItem = p.i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::insert(Ptr<T> & ptr, Ptr<T> & loc){
|
DLFifoListImpl<P,T,U>::insert(Ptr<T> & ptr, Ptr<T> & loc)
|
||||||
|
{
|
||||||
Uint32 prev= loc.p->U::prevList;
|
Uint32 prev= loc.p->U::prevList;
|
||||||
if(loc.i == head.firstItem)
|
if(loc.i == head.firstItem)
|
||||||
{
|
{
|
||||||
|
@ -342,88 +275,85 @@ DLFifoList<T,U>::insert(Ptr<T> & ptr, Ptr<T> & loc){
|
||||||
ptr.p->U::nextList = loc.i;
|
ptr.p->U::nextList = loc.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
template <typename P, typename T, typename U>
|
||||||
* Return an object to pool
|
|
||||||
*/
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::release(Uint32 i){
|
DLFifoListImpl<P,T,U>::remove(Ptr<T> & p)
|
||||||
Ptr<T> p;
|
{
|
||||||
p.i = i;
|
|
||||||
p.p = thePool.getPtr(i);
|
|
||||||
release(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
DLFifoList<T,U>::remove(Ptr<T> & p){
|
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
Uint32 ni = t->U::nextList;
|
Uint32 ni = t->U::nextList;
|
||||||
Uint32 pi = t->U::prevList;
|
Uint32 pi = t->U::prevList;
|
||||||
|
|
||||||
if(ni != RNIL){
|
if(ni != RNIL)
|
||||||
|
{
|
||||||
T * t = thePool.getPtr(ni);
|
T * t = thePool.getPtr(ni);
|
||||||
t->U::prevList = pi;
|
t->U::prevList = pi;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// We are releasing last
|
// We are releasing last
|
||||||
head.lastItem = pi;
|
head.lastItem = pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pi != RNIL){
|
if(pi != RNIL)
|
||||||
|
{
|
||||||
T * t = thePool.getPtr(pi);
|
T * t = thePool.getPtr(pi);
|
||||||
t->U::nextList = ni;
|
t->U::nextList = ni;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// We are releasing first
|
// We are releasing first
|
||||||
head.firstItem = ni;
|
head.firstItem = ni;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an object to pool
|
|
||||||
*/
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
DLFifoList<T,U>::release(Ptr<T> & p){
|
|
||||||
remove(p);
|
|
||||||
thePool.release(p.i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::release(){
|
DLFifoListImpl<P,T,U>::release()
|
||||||
|
{
|
||||||
Ptr<T> p;
|
Ptr<T> p;
|
||||||
while(head.firstItem != RNIL){
|
while(head.firstItem != RNIL)
|
||||||
|
{
|
||||||
p.i = head.firstItem;
|
p.i = head.firstItem;
|
||||||
p.p = thePool.getPtr(head.firstItem);
|
p.p = thePool.getPtr(head.firstItem);
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
head.firstItem = t->U::nextList;
|
head.firstItem = t->U::nextList;
|
||||||
release(p);
|
release(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::getPtr(Ptr<T> & p, Uint32 i) const {
|
DLFifoListImpl<P,T,U>::release(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
remove(p);
|
||||||
|
thePool.release(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
DLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
|
||||||
|
{
|
||||||
p.i = i;
|
p.i = i;
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLFifoList<T,U>::getPtr(Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p) const
|
||||||
|
{
|
||||||
thePool.getPtr(p);
|
thePool.getPtr(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
T *
|
T *
|
||||||
DLFifoList<T,U>::getPtr(Uint32 i) const {
|
DLFifoListImpl<P,T,U>::getPtr(Uint32 i) const
|
||||||
|
{
|
||||||
return thePool.getPtr(i);
|
return thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,12 +362,14 @@ DLFifoList<T,U>::getPtr(Uint32 i) const {
|
||||||
*
|
*
|
||||||
* Return i
|
* Return i
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::first(Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::first(Ptr<T> & p) const
|
||||||
|
{
|
||||||
p.i = head.firstItem;
|
p.i = head.firstItem;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(p.i);
|
p.p = thePool.getPtr(p.i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -445,12 +377,14 @@ DLFifoList<T,U>::first(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::last(Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::last(Ptr<T> & p) const
|
||||||
|
{
|
||||||
p.i = head.lastItem;
|
p.i = head.lastItem;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(p.i);
|
p.p = thePool.getPtr(p.i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -458,12 +392,14 @@ DLFifoList<T,U>::last(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::next(Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::next(Ptr<T> & p) const
|
||||||
|
{
|
||||||
p.i = p.p->U::nextList;
|
p.i = p.p->U::nextList;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(p.i);
|
p.p = thePool.getPtr(p.i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -471,12 +407,14 @@ DLFifoList<T,U>::next(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::prev(Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::prev(Ptr<T> & p) const
|
||||||
|
{
|
||||||
p.i = p.p->U::prevList;
|
p.i = p.p->U::prevList;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(p.i);
|
p.p = thePool.getPtr(p.i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -484,18 +422,36 @@ DLFifoList<T,U>::prev(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::hasNext(const Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
|
||||||
|
{
|
||||||
return p.p->U::nextList != RNIL;
|
return p.p->U::nextList != RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLFifoList<T,U>::hasPrev(const Ptr<T> & p) const {
|
DLFifoListImpl<P,T,U>::hasPrev(const Ptr<T> & p) const
|
||||||
|
{
|
||||||
return p.p->U::prevList != RNIL;
|
return p.p->U::prevList != RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class DLFifoList : public DLFifoListImpl<ArrayPool<T>, T, U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DLFifoList(ArrayPool<T> & p) : DLFifoListImpl<ArrayPool<T>, T, U>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class LocalDLFifoList : public LocalDLFifoListImpl<ArrayPool<T>,T,U> {
|
||||||
|
public:
|
||||||
|
LocalDLFifoList(ArrayPool<T> & p, typename DLFifoList<T,U>::Head & _src)
|
||||||
|
: LocalDLFifoListImpl<ArrayPool<T>,T,U>(p, _src) {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,11 +30,12 @@
|
||||||
* -# Uint32 hashValue() const;
|
* -# Uint32 hashValue() const;
|
||||||
* Which should return a 32 bit hashvalue
|
* Which should return a 32 bit hashvalue
|
||||||
*/
|
*/
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class DLHashTable {
|
class DLHashTableImpl
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
DLHashTable(ArrayPool<T> & thePool);
|
DLHashTableImpl(P & thePool);
|
||||||
~DLHashTable();
|
~DLHashTableImpl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the no of bucket in the hashtable
|
* Set the no of bucket in the hashtable
|
||||||
|
@ -101,12 +102,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void removeAll();
|
void removeAll();
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove element (and set Ptr to removed element)
|
|
||||||
* And return element to pool
|
|
||||||
*/
|
|
||||||
void release(Ptr<T> &, const T & key);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove element and return to pool
|
* Remove element and return to pool
|
||||||
*/
|
*/
|
||||||
|
@ -153,40 +148,44 @@ public:
|
||||||
private:
|
private:
|
||||||
Uint32 mask;
|
Uint32 mask;
|
||||||
Uint32 * hashValues;
|
Uint32 * hashValues;
|
||||||
ArrayPool<T> & thePool;
|
P & thePool;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLHashTable<T,U>::DLHashTable(ArrayPool<T> & _pool)
|
DLHashTableImpl<P, T, U>::DLHashTableImpl(P & _pool)
|
||||||
: thePool(_pool)
|
: thePool(_pool)
|
||||||
{
|
{
|
||||||
mask = 0;
|
mask = 0;
|
||||||
hashValues = 0;
|
hashValues = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLHashTable<T,U>::~DLHashTable(){
|
DLHashTableImpl<P, T, U>::~DLHashTableImpl()
|
||||||
|
{
|
||||||
if(hashValues != 0)
|
if(hashValues != 0)
|
||||||
delete [] hashValues;
|
delete [] hashValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::setSize(Uint32 size){
|
DLHashTableImpl<P, T, U>::setSize(Uint32 size)
|
||||||
|
{
|
||||||
Uint32 i = 1;
|
Uint32 i = 1;
|
||||||
while(i < size) i *= 2;
|
while(i < size) i *= 2;
|
||||||
|
|
||||||
if(mask == (i - 1)){
|
if(mask == (i - 1))
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* The size is already set to <b>size</b>
|
* The size is already set to <b>size</b>
|
||||||
*/
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mask != 0){
|
if(mask != 0)
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* The mask is already set
|
* The mask is already set
|
||||||
*/
|
*/
|
||||||
|
@ -201,19 +200,22 @@ DLHashTable<T,U>::setSize(Uint32 size){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::add(Ptr<T> & obj){
|
DLHashTableImpl<P, T, U>::add(Ptr<T> & obj)
|
||||||
|
{
|
||||||
const Uint32 hv = obj.p->hashValue() & mask;
|
const Uint32 hv = obj.p->hashValue() & mask;
|
||||||
const Uint32 i = hashValues[hv];
|
const Uint32 i = hashValues[hv];
|
||||||
|
|
||||||
if(i == RNIL){
|
if(i == RNIL)
|
||||||
|
{
|
||||||
hashValues[hv] = obj.i;
|
hashValues[hv] = obj.i;
|
||||||
obj.p->U::nextHash = RNIL;
|
obj.p->U::nextHash = RNIL;
|
||||||
obj.p->U::prevHash = RNIL;
|
obj.p->U::prevHash = RNIL;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
T * tmp = thePool.getPtr(i);
|
T * tmp = thePool.getPtr(i);
|
||||||
tmp->U::prevHash = obj.i;
|
tmp->U::prevHash = obj.i;
|
||||||
obj.p->U::nextHash = i;
|
obj.p->U::nextHash = i;
|
||||||
|
@ -226,36 +228,45 @@ DLHashTable<T,U>::add(Ptr<T> & obj){
|
||||||
/**
|
/**
|
||||||
* First element
|
* First element
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::first(Iterator & iter) const {
|
DLHashTableImpl<P, T, U>::first(Iterator & iter) const
|
||||||
|
{
|
||||||
Uint32 i = 0;
|
Uint32 i = 0;
|
||||||
while(i <= mask && hashValues[i] == RNIL) i++;
|
while(i <= mask && hashValues[i] == RNIL) i++;
|
||||||
if(i <= mask){
|
if(i <= mask)
|
||||||
|
{
|
||||||
iter.bucket = i;
|
iter.bucket = i;
|
||||||
iter.curr.i = hashValues[i];
|
iter.curr.i = hashValues[i];
|
||||||
iter.curr.p = thePool.getPtr(iter.curr.i);
|
iter.curr.p = thePool.getPtr(iter.curr.i);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
iter.curr.i = RNIL;
|
iter.curr.i = RNIL;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::next(Iterator & iter) const {
|
DLHashTableImpl<P, T, U>::next(Iterator & iter) const
|
||||||
if(iter.curr.p->U::nextHash == RNIL){
|
{
|
||||||
|
if(iter.curr.p->U::nextHash == RNIL)
|
||||||
|
{
|
||||||
Uint32 i = iter.bucket + 1;
|
Uint32 i = iter.bucket + 1;
|
||||||
while(i <= mask && hashValues[i] == RNIL) i++;
|
while(i <= mask && hashValues[i] == RNIL) i++;
|
||||||
if(i <= mask){
|
if(i <= mask)
|
||||||
|
{
|
||||||
iter.bucket = i;
|
iter.bucket = i;
|
||||||
iter.curr.i = hashValues[i];
|
iter.curr.i = hashValues[i];
|
||||||
iter.curr.p = thePool.getPtr(iter.curr.i);
|
iter.curr.p = thePool.getPtr(iter.curr.i);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
iter.curr.i = RNIL;
|
iter.curr.i = RNIL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -266,10 +277,11 @@ DLHashTable<T,U>::next(Iterator & iter) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::remove(Ptr<T> & ptr, const T & key){
|
DLHashTableImpl<P, T, U>::remove(Ptr<T> & ptr, const T & key)
|
||||||
|
{
|
||||||
const Uint32 hv = key.hashValue() & mask;
|
const Uint32 hv = key.hashValue() & mask;
|
||||||
|
|
||||||
Uint32 i;
|
Uint32 i;
|
||||||
|
@ -278,21 +290,27 @@ DLHashTable<T,U>::remove(Ptr<T> & ptr, const T & key){
|
||||||
prev.i = RNIL;
|
prev.i = RNIL;
|
||||||
|
|
||||||
i = hashValues[hv];
|
i = hashValues[hv];
|
||||||
while(i != RNIL){
|
while(i != RNIL)
|
||||||
|
{
|
||||||
p = thePool.getPtr(i);
|
p = thePool.getPtr(i);
|
||||||
if(key.equal(* p)){
|
if(key.equal(* p))
|
||||||
|
{
|
||||||
const Uint32 next = p->U::nextHash;
|
const Uint32 next = p->U::nextHash;
|
||||||
if(prev.i == RNIL){
|
if(prev.i == RNIL)
|
||||||
|
{
|
||||||
hashValues[hv] = next;
|
hashValues[hv] = next;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
prev.p->U::nextHash = next;
|
prev.p->U::nextHash = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next != RNIL){
|
if(next != RNIL)
|
||||||
|
{
|
||||||
T * nextP = thePool.getPtr(next);
|
T * nextP = thePool.getPtr(next);
|
||||||
nextP->U::prevHash = prev.i;
|
nextP->U::prevHash = prev.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr.i = i;
|
ptr.i = i;
|
||||||
ptr.p = p;
|
ptr.p = p;
|
||||||
return;
|
return;
|
||||||
|
@ -304,125 +322,101 @@ DLHashTable<T,U>::remove(Ptr<T> & ptr, const T & key){
|
||||||
ptr.i = RNIL;
|
ptr.i = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::release(Ptr<T> & ptr, const T & key){
|
DLHashTableImpl<P, T, U>::remove(Uint32 i)
|
||||||
const Uint32 hv = key.hashValue() & mask;
|
{
|
||||||
|
|
||||||
Uint32 i;
|
|
||||||
T * p;
|
|
||||||
Ptr<T> prev;
|
|
||||||
prev.i = RNIL;
|
|
||||||
|
|
||||||
i = hashValues[hv];
|
|
||||||
while(i != RNIL){
|
|
||||||
p = thePool.getPtr(i);
|
|
||||||
if(key.equal(* p)){
|
|
||||||
const Uint32 next = p->U::nextHash;
|
|
||||||
if(prev.i == RNIL){
|
|
||||||
hashValues[hv] = next;
|
|
||||||
} else {
|
|
||||||
prev.p->U::nextHash = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(next != RNIL){
|
|
||||||
T * nextP = thePool.getPtr(next);
|
|
||||||
nextP->U::prevHash = prev.i;
|
|
||||||
}
|
|
||||||
|
|
||||||
thePool.release(i);
|
|
||||||
ptr.i = i;
|
|
||||||
ptr.p = p;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prev.p = p;
|
|
||||||
prev.i = i;
|
|
||||||
i = p->U::nextHash;
|
|
||||||
}
|
|
||||||
ptr.i = RNIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class U>
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
DLHashTable<T,U>::remove(Uint32 i){
|
|
||||||
Ptr<T> tmp;
|
Ptr<T> tmp;
|
||||||
tmp.i = i;
|
tmp.i = i;
|
||||||
tmp.p = thePool.getPtr(i);
|
tmp.p = thePool.getPtr(i);
|
||||||
remove(tmp);
|
remove(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::release(Uint32 i){
|
DLHashTableImpl<P, T, U>::release(Uint32 i)
|
||||||
|
{
|
||||||
Ptr<T> tmp;
|
Ptr<T> tmp;
|
||||||
tmp.i = i;
|
tmp.i = i;
|
||||||
tmp.p = thePool.getPtr(i);
|
tmp.p = thePool.getPtr(i);
|
||||||
release(tmp);
|
release(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::remove(Ptr<T> & ptr){
|
DLHashTableImpl<P, T, U>::remove(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
const Uint32 next = ptr.p->U::nextHash;
|
const Uint32 next = ptr.p->U::nextHash;
|
||||||
const Uint32 prev = ptr.p->U::prevHash;
|
const Uint32 prev = ptr.p->U::prevHash;
|
||||||
|
|
||||||
if(prev != RNIL){
|
if(prev != RNIL)
|
||||||
|
{
|
||||||
T * prevP = thePool.getPtr(prev);
|
T * prevP = thePool.getPtr(prev);
|
||||||
prevP->U::nextHash = next;
|
prevP->U::nextHash = next;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
const Uint32 hv = ptr.p->hashValue() & mask;
|
const Uint32 hv = ptr.p->hashValue() & mask;
|
||||||
hashValues[hv] = next;
|
hashValues[hv] = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next != RNIL){
|
if(next != RNIL)
|
||||||
|
{
|
||||||
T * nextP = thePool.getPtr(next);
|
T * nextP = thePool.getPtr(next);
|
||||||
nextP->U::prevHash = prev;
|
nextP->U::prevHash = prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::release(Ptr<T> & ptr){
|
DLHashTableImpl<P, T, U>::release(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
const Uint32 next = ptr.p->U::nextHash;
|
const Uint32 next = ptr.p->U::nextHash;
|
||||||
const Uint32 prev = ptr.p->U::prevHash;
|
const Uint32 prev = ptr.p->U::prevHash;
|
||||||
|
|
||||||
if(prev != RNIL){
|
if(prev != RNIL)
|
||||||
|
{
|
||||||
T * prevP = thePool.getPtr(prev);
|
T * prevP = thePool.getPtr(prev);
|
||||||
prevP->U::nextHash = next;
|
prevP->U::nextHash = next;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
const Uint32 hv = ptr.p->hashValue() & mask;
|
const Uint32 hv = ptr.p->hashValue() & mask;
|
||||||
hashValues[hv] = next;
|
hashValues[hv] = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(next != RNIL){
|
if(next != RNIL)
|
||||||
|
{
|
||||||
T * nextP = thePool.getPtr(next);
|
T * nextP = thePool.getPtr(next);
|
||||||
nextP->U::prevHash = prev;
|
nextP->U::prevHash = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
thePool.release(ptr.i);
|
thePool.release(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::removeAll(){
|
DLHashTableImpl<P, T, U>::removeAll()
|
||||||
|
{
|
||||||
for(Uint32 i = 0; i<=mask; i++)
|
for(Uint32 i = 0; i<=mask; i++)
|
||||||
hashValues[i] = RNIL;
|
hashValues[i] = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::next(Uint32 bucket, Iterator & iter) const {
|
DLHashTableImpl<P, T, U>::next(Uint32 bucket, Iterator & iter) const
|
||||||
|
{
|
||||||
while (bucket <= mask && hashValues[bucket] == RNIL)
|
while (bucket <= mask && hashValues[bucket] == RNIL)
|
||||||
bucket++;
|
bucket++;
|
||||||
|
|
||||||
if (bucket > mask) {
|
if (bucket > mask)
|
||||||
|
{
|
||||||
iter.bucket = bucket;
|
iter.bucket = bucket;
|
||||||
iter.curr.i = RNIL;
|
iter.curr.i = RNIL;
|
||||||
return false;
|
return false;
|
||||||
|
@ -434,10 +428,11 @@ DLHashTable<T,U>::next(Uint32 bucket, Iterator & iter) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::seize(Ptr<T> & ptr){
|
DLHashTableImpl<P, T, U>::seize(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
if(thePool.seize(ptr)){
|
if(thePool.seize(ptr)){
|
||||||
ptr.p->U::nextHash = ptr.p->U::prevHash = RNIL;
|
ptr.p->U::nextHash = ptr.p->U::prevHash = RNIL;
|
||||||
return true;
|
return true;
|
||||||
|
@ -445,41 +440,47 @@ DLHashTable<T,U>::seize(Ptr<T> & ptr){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::getPtr(Ptr<T> & ptr, Uint32 i) const {
|
DLHashTableImpl<P, T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const
|
||||||
|
{
|
||||||
ptr.i = i;
|
ptr.i = i;
|
||||||
ptr.p = thePool.getPtr(i);
|
ptr.p = thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLHashTable<T,U>::getPtr(Ptr<T> & ptr) const {
|
DLHashTableImpl<P, T, U>::getPtr(Ptr<T> & ptr) const
|
||||||
|
{
|
||||||
thePool.getPtr(ptr);
|
thePool.getPtr(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
T *
|
T *
|
||||||
DLHashTable<T,U>::getPtr(Uint32 i) const {
|
DLHashTableImpl<P, T, U>::getPtr(Uint32 i) const
|
||||||
|
{
|
||||||
return thePool.getPtr(i);
|
return thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLHashTable<T,U>::find(Ptr<T> & ptr, const T & key) const {
|
DLHashTableImpl<P, T, U>::find(Ptr<T> & ptr, const T & key) const
|
||||||
|
{
|
||||||
const Uint32 hv = key.hashValue() & mask;
|
const Uint32 hv = key.hashValue() & mask;
|
||||||
|
|
||||||
Uint32 i;
|
Uint32 i;
|
||||||
T * p;
|
T * p;
|
||||||
|
|
||||||
i = hashValues[hv];
|
i = hashValues[hv];
|
||||||
while(i != RNIL){
|
while(i != RNIL)
|
||||||
|
{
|
||||||
p = thePool.getPtr(i);
|
p = thePool.getPtr(i);
|
||||||
if(key.equal(* p)){
|
if(key.equal(* p))
|
||||||
|
{
|
||||||
ptr.i = i;
|
ptr.i = i;
|
||||||
ptr.p = p;
|
ptr.p = p;
|
||||||
return true;
|
return true;
|
||||||
|
@ -490,4 +491,14 @@ DLHashTable<T,U>::find(Ptr<T> & ptr, const T & key) const {
|
||||||
ptr.p = NULL;
|
ptr.p = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class DLHashTable : public DLHashTableImpl<ArrayPool<T>, T, U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DLHashTable(ArrayPool<T> & p) : DLHashTableImpl<ArrayPool<T>, T, U>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
#define DLLIST_HPP
|
#define DLLIST_HPP
|
||||||
|
|
||||||
#include "ArrayPool.hpp"
|
#include "ArrayPool.hpp"
|
||||||
#include <NdbOut.hpp>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template class used for implementing an
|
* Template class used for implementing an
|
||||||
* list of object retreived from a pool
|
* list of object retreived from a pool
|
||||||
*/
|
*/
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class DLList {
|
class DLListImpl
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* List head
|
* List head
|
||||||
|
@ -36,7 +36,8 @@ public:
|
||||||
inline void init () { firstItem = RNIL; }
|
inline void init () { firstItem = RNIL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Head : public HeadPOD {
|
struct Head : public HeadPOD
|
||||||
|
{
|
||||||
Head();
|
Head();
|
||||||
Head& operator=(const HeadPOD& src) {
|
Head& operator=(const HeadPOD& src) {
|
||||||
this->firstItem = src.firstItem;
|
this->firstItem = src.firstItem;
|
||||||
|
@ -44,7 +45,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DLList(ArrayPool<T> & thePool);
|
DLListImpl(P& thePool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an object from pool - update Ptr
|
* Allocate an object from pool - update Ptr
|
||||||
|
@ -151,62 +152,41 @@ public:
|
||||||
*/
|
*/
|
||||||
bool hasNext(const Ptr<T> &) const;
|
bool hasNext(const Ptr<T> &) const;
|
||||||
|
|
||||||
Uint32 noOfElements() const {
|
|
||||||
Uint32 c = 0;
|
|
||||||
Uint32 i = head.firstItem;
|
|
||||||
while(i != RNIL){
|
|
||||||
c++;
|
|
||||||
const T * t = thePool.getPtr(i);
|
|
||||||
i = t->U::nextList;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print
|
|
||||||
* (Run operator NdbOut<< on every element)
|
|
||||||
*/
|
|
||||||
void print(NdbOut & out) {
|
|
||||||
Uint32 i = head.firstItem;
|
|
||||||
while(i != RNIL){
|
|
||||||
T * t = thePool.getPtr(i);
|
|
||||||
t->print(out); out << " ";
|
|
||||||
i = t->U::nextList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isEmpty() const { return head.firstItem == RNIL;}
|
inline bool isEmpty() const { return head.firstItem == RNIL;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Head head;
|
Head head;
|
||||||
ArrayPool<T> & thePool;
|
P & thePool;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class LocalDLList : public DLList<T,U> {
|
class LocalDLListImpl : public DLListImpl<P,T,U>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
LocalDLList(ArrayPool<T> & thePool, typename DLList<T,U>::HeadPOD & _src)
|
LocalDLListImpl(P & thePool, typename DLListImpl<P,T,U>::HeadPOD & _src)
|
||||||
: DLList<T,U>(thePool), src(_src)
|
: DLListImpl<P,T,U>(thePool), src(_src)
|
||||||
{
|
{
|
||||||
this->head = src;
|
this->head = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
~LocalDLList(){
|
~LocalDLListImpl(){
|
||||||
src = this->head;
|
src = this->head;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
typename DLList<T,U>::HeadPOD & src;
|
typename DLListImpl<P,T,U>::HeadPOD & src;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLList<T,U>::DLList(ArrayPool<T> & _pool):
|
DLListImpl<P,T,U>::DLListImpl(P & _pool)
|
||||||
thePool(_pool){
|
: thePool(_pool)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
DLList<T,U>::Head::Head(){
|
DLListImpl<P,T,U>::Head::Head()
|
||||||
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,11 +195,13 @@ DLList<T,U>::Head::Head(){
|
||||||
*
|
*
|
||||||
* Return i
|
* Return i
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::seize(Ptr<T> & p){
|
DLListImpl<P,T,U>::seize(Ptr<T> & p)
|
||||||
if(thePool.seize(p)){
|
{
|
||||||
|
if (likely(thePool.seize(p)))
|
||||||
|
{
|
||||||
add(p);
|
add(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -231,28 +213,32 @@ DLList<T,U>::seize(Ptr<T> & p){
|
||||||
*
|
*
|
||||||
* Return i
|
* Return i
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::seizeId(Ptr<T> & p, Uint32 ir){
|
DLListImpl<P,T,U>::seizeId(Ptr<T> & p, Uint32 ir)
|
||||||
if(thePool.seizeId(p, ir)){
|
{
|
||||||
|
if (likely(thePool.seizeId(p, ir)))
|
||||||
|
{
|
||||||
add(p);
|
add(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::findId(Uint32 i) const {
|
DLListImpl<P,T,U>::findId(Uint32 i) const
|
||||||
|
{
|
||||||
return thePool.findId(i);
|
return thePool.findId(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::add(Ptr<T> & p){
|
DLListImpl<P,T,U>::add(Ptr<T> & p)
|
||||||
|
{
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
Uint32 ff = head.firstItem;
|
Uint32 ff = head.firstItem;
|
||||||
|
|
||||||
|
@ -260,39 +246,43 @@ DLList<T,U>::add(Ptr<T> & p){
|
||||||
t->U::prevList = RNIL;
|
t->U::prevList = RNIL;
|
||||||
head.firstItem = p.i;
|
head.firstItem = p.i;
|
||||||
|
|
||||||
if(ff != RNIL){
|
if(ff != RNIL)
|
||||||
|
{
|
||||||
T * t2 = thePool.getPtr(ff);
|
T * t2 = thePool.getPtr(ff);
|
||||||
t2->U::prevList = p.i;
|
t2->U::prevList = p.i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::add(Uint32 first, Ptr<T> & lastPtr)
|
DLListImpl<P,T,U>::add(Uint32 first, Ptr<T> & lastPtr)
|
||||||
{
|
{
|
||||||
Uint32 ff = head.firstItem;
|
Uint32 ff = head.firstItem;
|
||||||
|
|
||||||
head.firstItem = first;
|
head.firstItem = first;
|
||||||
lastPtr.p->U::nextList = ff;
|
lastPtr.p->U::nextList = ff;
|
||||||
|
|
||||||
if(ff != RNIL){
|
if(ff != RNIL)
|
||||||
|
{
|
||||||
T * t2 = thePool.getPtr(ff);
|
T * t2 = thePool.getPtr(ff);
|
||||||
t2->U::prevList = lastPtr.i;
|
t2->U::prevList = lastPtr.i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::remove(Ptr<T> & p){
|
DLListImpl<P,T,U>::remove(Ptr<T> & p)
|
||||||
|
{
|
||||||
remove(p.p);
|
remove(p.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::remove(T * p){
|
DLListImpl<P,T,U>::remove(T * p)
|
||||||
|
{
|
||||||
T * t = p;
|
T * t = p;
|
||||||
Uint32 ni = t->U::nextList;
|
Uint32 ni = t->U::nextList;
|
||||||
Uint32 pi = t->U::prevList;
|
Uint32 pi = t->U::prevList;
|
||||||
|
@ -313,10 +303,11 @@ DLList<T,U>::remove(T * p){
|
||||||
/**
|
/**
|
||||||
* Return an object to pool
|
* Return an object to pool
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::release(Uint32 i){
|
DLListImpl<P,T,U>::release(Uint32 i)
|
||||||
|
{
|
||||||
Ptr<T> p;
|
Ptr<T> p;
|
||||||
p.i = i;
|
p.i = i;
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
|
@ -326,52 +317,59 @@ DLList<T,U>::release(Uint32 i){
|
||||||
/**
|
/**
|
||||||
* Return an object to pool
|
* Return an object to pool
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::release(Ptr<T> & p){
|
DLListImpl<P,T,U>::release(Ptr<T> & p)
|
||||||
|
{
|
||||||
remove(p);
|
remove(p);
|
||||||
thePool.release(p.i);
|
thePool.release(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::release(){
|
DLListImpl<P,T,U>::release()
|
||||||
while(head.firstItem != RNIL){
|
{
|
||||||
const T * t = thePool.getPtr(head.firstItem);
|
Ptr<T> ptr;
|
||||||
const Uint32 i = head.firstItem;
|
while((ptr.i = head.firstItem) != RNIL)
|
||||||
head.firstItem = t->U::nextList;
|
{
|
||||||
thePool.release(i);
|
thePool.getPtr(ptr);
|
||||||
|
head.firstItem = ptr.p->U::nextList;
|
||||||
|
thePool.release(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::remove(){
|
DLListImpl<P,T,U>::remove()
|
||||||
|
{
|
||||||
head.firstItem = RNIL;
|
head.firstItem = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::getPtr(Ptr<T> & p, Uint32 i) const {
|
DLListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
|
||||||
|
{
|
||||||
p.i = i;
|
p.i = i;
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
DLList<T,U>::getPtr(Ptr<T> & p) const {
|
DLListImpl<P,T,U>::getPtr(Ptr<T> & p) const
|
||||||
|
{
|
||||||
thePool.getPtr(p);
|
thePool.getPtr(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
T *
|
T *
|
||||||
DLList<T,U>::getPtr(Uint32 i) const {
|
DLListImpl<P,T,U>::getPtr(Uint32 i) const
|
||||||
|
{
|
||||||
return thePool.getPtr(i);
|
return thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,13 +378,15 @@ DLList<T,U>::getPtr(Uint32 i) const {
|
||||||
*
|
*
|
||||||
* Return i
|
* Return i
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::first(Ptr<T> & p) const {
|
DLListImpl<P,T,U>::first(Ptr<T> & p) const
|
||||||
|
{
|
||||||
Uint32 i = head.firstItem;
|
Uint32 i = head.firstItem;
|
||||||
p.i = i;
|
p.i = i;
|
||||||
if(i != RNIL){
|
if(i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -394,10 +394,11 @@ DLList<T,U>::first(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::next(Ptr<T> & p) const {
|
DLListImpl<P,T,U>::next(Ptr<T> & p) const
|
||||||
|
{
|
||||||
Uint32 i = p.p->U::nextList;
|
Uint32 i = p.p->U::nextList;
|
||||||
p.i = i;
|
p.i = i;
|
||||||
if(i != RNIL){
|
if(i != RNIL){
|
||||||
|
@ -408,11 +409,28 @@ DLList<T,U>::next(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
DLList<T,U>::hasNext(const Ptr<T> & p) const {
|
DLListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
|
||||||
|
{
|
||||||
return p.p->U::nextList != RNIL;
|
return p.p->U::nextList != RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class DLList : public DLListImpl<ArrayPool<T>, T, U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DLList(ArrayPool<T> & p) : DLListImpl<ArrayPool<T>, T, U>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class LocalDLList : public LocalDLListImpl<ArrayPool<T>, T, U> {
|
||||||
|
public:
|
||||||
|
LocalDLList(ArrayPool<T> & p, typename DLList<T,U>::HeadPOD & _src)
|
||||||
|
: LocalDLListImpl<ArrayPool<T>, T, U>(p, _src) {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "SimBlockList.hpp"
|
#include "SimBlockList.hpp"
|
||||||
|
|
||||||
#include <NodeState.hpp>
|
#include <NodeState.hpp>
|
||||||
|
#include "ndbd_malloc_impl.hpp"
|
||||||
|
|
||||||
#include <NdbMem.h>
|
#include <NdbMem.h>
|
||||||
#include <NdbMutex.h>
|
#include <NdbMutex.h>
|
||||||
|
@ -77,6 +78,7 @@ EmulatorData::EmulatorData(){
|
||||||
theSimBlockList = 0;
|
theSimBlockList = 0;
|
||||||
theShutdownMutex = 0;
|
theShutdownMutex = 0;
|
||||||
m_socket_server = 0;
|
m_socket_server = 0;
|
||||||
|
m_mem_manager = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -93,6 +95,7 @@ EmulatorData::create(){
|
||||||
theThreadConfig = new ThreadConfig();
|
theThreadConfig = new ThreadConfig();
|
||||||
theSimBlockList = new SimBlockList();
|
theSimBlockList = new SimBlockList();
|
||||||
m_socket_server = new SocketServer();
|
m_socket_server = new SocketServer();
|
||||||
|
m_mem_manager = new Ndbd_mem_manager();
|
||||||
|
|
||||||
theShutdownMutex = NdbMutex_Create();
|
theShutdownMutex = NdbMutex_Create();
|
||||||
|
|
||||||
|
@ -111,6 +114,9 @@ EmulatorData::destroy(){
|
||||||
delete theSimBlockList; theSimBlockList = 0;
|
delete theSimBlockList; theSimBlockList = 0;
|
||||||
if(m_socket_server)
|
if(m_socket_server)
|
||||||
delete m_socket_server; m_socket_server = 0;
|
delete m_socket_server; m_socket_server = 0;
|
||||||
|
if (m_mem_manager)
|
||||||
|
delete m_mem_manager; m_mem_manager = 0;
|
||||||
|
|
||||||
NdbMem_Destroy();
|
NdbMem_Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct EmulatorData {
|
||||||
class ThreadConfig * theThreadConfig;
|
class ThreadConfig * theThreadConfig;
|
||||||
class SimBlockList * theSimBlockList;
|
class SimBlockList * theSimBlockList;
|
||||||
class SocketServer * m_socket_server;
|
class SocketServer * m_socket_server;
|
||||||
|
class Ndbd_mem_manager * m_mem_manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|
|
@ -81,6 +81,7 @@ private:
|
||||||
SimulatedBlock* blockTable[NO_OF_BLOCKS]; // Owned by Dispatcher::
|
SimulatedBlock* blockTable[NO_OF_BLOCKS]; // Owned by Dispatcher::
|
||||||
public:
|
public:
|
||||||
ArrayPool<GlobalPage> m_global_page_pool;
|
ArrayPool<GlobalPage> m_global_page_pool;
|
||||||
|
ArrayPool<GlobalPage> m_shared_page_pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GlobalData globalData;
|
extern GlobalData globalData;
|
||||||
|
|
|
@ -22,22 +22,31 @@
|
||||||
/**
|
/**
|
||||||
* KeyTable2 is DLHashTable2 with hardcoded Uint32 key named "key".
|
* KeyTable2 is DLHashTable2 with hardcoded Uint32 key named "key".
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <typename P, typename T>
|
||||||
class KeyTable : public DLHashTable<T> {
|
class KeyTableImpl : public DLHashTableImpl<P, T> {
|
||||||
public:
|
public:
|
||||||
KeyTable(ArrayPool<T>& pool) :
|
KeyTableImpl(P & pool) :
|
||||||
DLHashTable<T>(pool) {
|
DLHashTableImpl<P, T>(pool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(Ptr<T>& ptr, const T& rec) const {
|
bool find(Ptr<T>& ptr, const T& rec) const {
|
||||||
return DLHashTable<T>::find(ptr, rec);
|
return DLHashTableImpl<P, T>::find(ptr, rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(Ptr<T>& ptr, Uint32 key) const {
|
bool find(Ptr<T>& ptr, Uint32 key) const {
|
||||||
T rec;
|
T rec;
|
||||||
rec.key = key;
|
rec.key = key;
|
||||||
return DLHashTable<T>::find(ptr, rec);
|
return DLHashTableImpl<P, T>::find(ptr, rec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class KeyTable : public KeyTableImpl<ArrayPool<T>, T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeyTable(ArrayPool<T> & p) : KeyTableImpl<ArrayPool<T>, T>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,8 @@ libkernel_a_SOURCES = \
|
||||||
SectionReader.cpp \
|
SectionReader.cpp \
|
||||||
Mutex.cpp SafeCounter.cpp \
|
Mutex.cpp SafeCounter.cpp \
|
||||||
Rope.cpp \
|
Rope.cpp \
|
||||||
ndbd_malloc.cpp ndbd_malloc_impl.cpp
|
ndbd_malloc.cpp ndbd_malloc_impl.cpp \
|
||||||
|
Pool.cpp WOPool.cpp RWPool.cpp
|
||||||
|
|
||||||
INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
|
INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
|
||||||
|
|
||||||
|
@ -52,9 +53,9 @@ ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
|
||||||
$(top_builddir)/dbug/libdbug.a \
|
$(top_builddir)/dbug/libdbug.a \
|
||||||
$(top_builddir)/strings/libmystrings.a
|
$(top_builddir)/strings/libmystrings.a
|
||||||
|
|
||||||
bench_pool_SOURCES = bench_pool.cpp ndbd_malloc.cpp \
|
bench_pool_SOURCES = bench_pool.cpp ../SimBlockList.o
|
||||||
SuperPool.cpp NdbdSuperPool.cpp ndbd_malloc_impl.cpp
|
|
||||||
bench_pool_LDFLAGS = @ndb_bin_am_ldflags@ \
|
bench_pool_LDFLAGS = @ndb_bin_am_ldflags@ \
|
||||||
|
libkernel.a ../error/liberror.a \
|
||||||
$(top_builddir)/storage/ndb/src/libndbclient.la \
|
$(top_builddir)/storage/ndb/src/libndbclient.la \
|
||||||
$(top_builddir)/mysys/libmysys.a \
|
$(top_builddir)/mysys/libmysys.a \
|
||||||
$(top_builddir)/dbug/libdbug.a \
|
$(top_builddir)/dbug/libdbug.a \
|
||||||
|
|
43
storage/ndb/src/kernel/vm/Pool.cpp
Normal file
43
storage/ndb/src/kernel/vm/Pool.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
|
#include "Pool.hpp"
|
||||||
|
#include "SimulatedBlock.hpp"
|
||||||
|
|
||||||
|
void*
|
||||||
|
Pool_context::alloc_page(Uint32 type_id, Uint32 *i)
|
||||||
|
{
|
||||||
|
return m_block->m_ctx.m_mm.alloc_page(type_id, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pool_context::release_page(Uint32 type_id, Uint32 i)
|
||||||
|
{
|
||||||
|
m_block->m_ctx.m_mm.release_page(type_id, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
Pool_context::get_memroot()
|
||||||
|
{
|
||||||
|
return m_block->m_ctx.m_mm.get_memroot();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Pool_context::handleAbort(int err, const char * msg)
|
||||||
|
{
|
||||||
|
m_block->progError(__LINE__, err, msg);
|
||||||
|
}
|
|
@ -17,8 +17,33 @@
|
||||||
#ifndef NDB_POOL_HPP
|
#ifndef NDB_POOL_HPP
|
||||||
#define NDB_POOL_HPP
|
#define NDB_POOL_HPP
|
||||||
|
|
||||||
|
#include <ndb_global.h>
|
||||||
#include <kernel_types.h>
|
#include <kernel_types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type bits
|
||||||
|
*
|
||||||
|
* Type id is 11 bits record type, and 5 bits resource id
|
||||||
|
* -> 2048 different kind of records and 32 different resource groups
|
||||||
|
*
|
||||||
|
* Resource id is used to handle configuration parameters
|
||||||
|
*
|
||||||
|
* see blocks/records_types.hpp
|
||||||
|
*/
|
||||||
|
#define RG_BITS 5
|
||||||
|
#define RG_MASK ((1 << RG_BITS) - 1)
|
||||||
|
#define MAKE_TID(TID,RG) ((TID << RG_BITS) | RG)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page bits
|
||||||
|
*/
|
||||||
|
#define POOL_RECORD_BITS 13
|
||||||
|
#define POOL_RECORD_MASK ((1 << POOL_RECORD_BITS) - 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record_info
|
||||||
|
*
|
||||||
|
*/
|
||||||
struct Record_info
|
struct Record_info
|
||||||
{
|
{
|
||||||
Uint16 m_size;
|
Uint16 m_size;
|
||||||
|
@ -27,6 +52,9 @@ struct Record_info
|
||||||
Uint16 m_offset_magic;
|
Uint16 m_offset_magic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource_limit
|
||||||
|
*/
|
||||||
struct Resource_limit
|
struct Resource_limit
|
||||||
{
|
{
|
||||||
Uint32 m_min;
|
Uint32 m_min;
|
||||||
|
@ -38,7 +66,11 @@ struct Resource_limit
|
||||||
struct Pool_context
|
struct Pool_context
|
||||||
{
|
{
|
||||||
class SimulatedBlock* m_block;
|
class SimulatedBlock* m_block;
|
||||||
struct Resource_limit* m_resource_limit;
|
|
||||||
|
/**
|
||||||
|
* Get mem root
|
||||||
|
*/
|
||||||
|
void* get_memroot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alloc consekutive pages
|
* Alloc consekutive pages
|
||||||
|
@ -48,7 +80,7 @@ struct Pool_context
|
||||||
*
|
*
|
||||||
* Will handle resource limit
|
* Will handle resource limit
|
||||||
*/
|
*/
|
||||||
void* alloc_page(Uint32 *i);
|
void* alloc_page(Uint32 type_id, Uint32 *i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release pages
|
* Release pages
|
||||||
|
@ -56,8 +88,8 @@ struct Pool_context
|
||||||
* @param i : in : i value of first page
|
* @param i : in : i value of first page
|
||||||
* @param p : in : pointer to first page
|
* @param p : in : pointer to first page
|
||||||
*/
|
*/
|
||||||
void release_page(Uint32 i, void* p);
|
void release_page(Uint32 type_id, Uint32 i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alloc consekutive pages
|
* Alloc consekutive pages
|
||||||
*
|
*
|
||||||
|
@ -70,7 +102,7 @@ struct Pool_context
|
||||||
*
|
*
|
||||||
* Will handle resource limit
|
* Will handle resource limit
|
||||||
*/
|
*/
|
||||||
void* alloc_pages(Uint32 *i, Uint32 *cnt, Uint32 min = 1);
|
void* alloc_pages(Uint32 type_id, Uint32 *i, Uint32 *cnt, Uint32 min =1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release pages
|
* Release pages
|
||||||
|
@ -79,21 +111,12 @@ struct Pool_context
|
||||||
* @param p : in : pointer to first page
|
* @param p : in : pointer to first page
|
||||||
* @param cnt : in : no of pages to release
|
* @param cnt : in : no of pages to release
|
||||||
*/
|
*/
|
||||||
void release_pages(Uint32 i, void* p, Uint32 cnt);
|
void release_pages(Uint32 type_id, Uint32 i, Uint32 cnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pool abort
|
* Abort
|
||||||
* Only know issue is getPtr with invalid i-value.
|
|
||||||
* If other emerges, we will add argument to this method
|
|
||||||
*/
|
*/
|
||||||
struct AbortArg
|
void handleAbort(int code, const char* msg);
|
||||||
{
|
|
||||||
Uint32 m_expected_magic;
|
|
||||||
Uint32 m_found_magic;
|
|
||||||
Uint32 i;
|
|
||||||
void * p;
|
|
||||||
};
|
|
||||||
void handle_abort(const AbortArg &);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -118,19 +141,181 @@ struct ConstPtr
|
||||||
/**
|
/**
|
||||||
* Any pool should implement the following
|
* Any pool should implement the following
|
||||||
*/
|
*/
|
||||||
struct Pool
|
struct PoolImpl
|
||||||
{
|
{
|
||||||
public:
|
Pool_context m_ctx;
|
||||||
Pool();
|
Record_info m_record_info;
|
||||||
|
|
||||||
void init(const Record_info& ri, const Pool_context& pc);
|
void init(const Record_info& ri, const Pool_context& pc);
|
||||||
|
void init(const Record_info& ri, const Pool_context& pc);
|
||||||
bool seize(Uint32*, void**);
|
|
||||||
void* seize(Uint32*);
|
bool seize(Ptr<void>&);
|
||||||
|
void release(Ptr<void>);
|
||||||
void release(Uint32 i, void* p);
|
|
||||||
void * getPtr(Uint32 i);
|
void * getPtr(Uint32 i);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
class RecordPool {
|
||||||
|
public:
|
||||||
|
RecordPool();
|
||||||
|
~RecordPool();
|
||||||
|
|
||||||
|
void init(Uint32 type_id, const Pool_context& pc);
|
||||||
|
void wo_pool_init(Uint32 type_id, const Pool_context& pc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update p value for ptr according to i value
|
||||||
|
*/
|
||||||
|
void getPtr(Ptr<T> &);
|
||||||
|
void getPtr(ConstPtr<T> &) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get pointer for i value
|
||||||
|
*/
|
||||||
|
T * getPtr(Uint32 i);
|
||||||
|
const T * getConstPtr(Uint32 i) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update p & i value for ptr according to <b>i</b> value
|
||||||
|
*/
|
||||||
|
void getPtr(Ptr<T> &, Uint32 i);
|
||||||
|
void getPtr(ConstPtr<T> &, Uint32 i) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an object from pool - update Ptr
|
||||||
|
*
|
||||||
|
* Return i
|
||||||
|
*/
|
||||||
|
bool seize(Ptr<T> &);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an object to pool
|
||||||
|
*/
|
||||||
|
void release(Uint32 i);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an object to pool
|
||||||
|
*/
|
||||||
|
void release(Ptr<T> &);
|
||||||
|
private:
|
||||||
|
P m_pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
RecordPool<T, P>::RecordPool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::init(Uint32 type_id, const Pool_context& pc)
|
||||||
|
{
|
||||||
|
Record_info ri;
|
||||||
|
ri.m_size = sizeof(T);
|
||||||
|
ri.m_offset_next_pool = offsetof(T, nextPool);
|
||||||
|
ri.m_offset_magic = offsetof(T, m_magic);
|
||||||
|
ri.m_type_id = type_id;
|
||||||
|
m_pool.init(ri, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::wo_pool_init(Uint32 type_id, const Pool_context& pc)
|
||||||
|
{
|
||||||
|
Record_info ri;
|
||||||
|
ri.m_size = sizeof(T);
|
||||||
|
ri.m_offset_next_pool = 0;
|
||||||
|
ri.m_offset_magic = offsetof(T, m_magic);
|
||||||
|
ri.m_type_id = type_id;
|
||||||
|
m_pool.init(ri, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
RecordPool<T, P>::~RecordPool()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::getPtr(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
|
ptr.p = static_cast<T*>(m_pool.getPtr(ptr.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::getPtr(ConstPtr<T> & ptr) const
|
||||||
|
{
|
||||||
|
ptr.p = static_cast<const T*>(m_pool.getPtr(ptr.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::getPtr(Ptr<T> & ptr, Uint32 i)
|
||||||
|
{
|
||||||
|
ptr.i = i;
|
||||||
|
ptr.p = static_cast<T*>(m_pool.getPtr(ptr.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::getPtr(ConstPtr<T> & ptr, Uint32 i) const
|
||||||
|
{
|
||||||
|
ptr.i = i;
|
||||||
|
ptr.p = static_cast<const T*>(m_pool.getPtr(ptr.i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
T *
|
||||||
|
RecordPool<T, P>::getPtr(Uint32 i)
|
||||||
|
{
|
||||||
|
return static_cast<T*>(m_pool.getPtr(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
const T *
|
||||||
|
RecordPool<T, P>::getConstPtr(Uint32 i) const
|
||||||
|
{
|
||||||
|
return static_cast<const T*>(m_pool.getPtr(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
RecordPool<T, P>::seize(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
|
return m_pool.seize(*(Ptr<void>*)&ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::release(Uint32 i)
|
||||||
|
{
|
||||||
|
Ptr<void> ptr;
|
||||||
|
ptr.i = i;
|
||||||
|
ptr.p = m_pool.getPtr(i);
|
||||||
|
m_pool.release(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename P>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
RecordPool<T, P>::release(Ptr<T> & ptr)
|
||||||
|
{
|
||||||
|
m_pool.release(*(Ptr<void>*)&ptr);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
226
storage/ndb/src/kernel/vm/RWPool.cpp
Normal file
226
storage/ndb/src/kernel/vm/RWPool.cpp
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "RWPool.hpp"
|
||||||
|
#include <ndbd_exit_codes.h>
|
||||||
|
#include <NdbOut.hpp>
|
||||||
|
|
||||||
|
#define REC_NIL GLOBAL_PAGE_SIZE_WORDS
|
||||||
|
|
||||||
|
RWPool::RWPool()
|
||||||
|
{
|
||||||
|
bzero(this, sizeof(* this));
|
||||||
|
m_current_pos = GLOBAL_PAGE_SIZE_WORDS;
|
||||||
|
m_current_first_free = REC_NIL;
|
||||||
|
m_first_free_page = RNIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RWPool::init(const Record_info& ri, const Pool_context& pc)
|
||||||
|
{
|
||||||
|
m_ctx = pc;
|
||||||
|
m_record_info = ri;
|
||||||
|
m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
|
||||||
|
m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
|
||||||
|
m_record_info.m_offset_next_pool = ((ri.m_offset_next_pool + 3) >> 2);
|
||||||
|
m_memroot = (RWPage*)m_ctx.get_memroot();
|
||||||
|
ndbout_c("RWPool::init(%x, %d)",ri.m_type_id, m_record_info.m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RWPool::seize(Ptr<void>& ptr)
|
||||||
|
{
|
||||||
|
Uint32 pos = m_current_pos;
|
||||||
|
Uint32 size = m_record_info.m_size;
|
||||||
|
Uint32 off = m_record_info.m_offset_magic;
|
||||||
|
RWPage *pageP = m_current_page;
|
||||||
|
if (likely(m_current_first_free != REC_NIL))
|
||||||
|
{
|
||||||
|
seize_free:
|
||||||
|
pos = m_current_first_free;
|
||||||
|
ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
|
||||||
|
ptr.p = pageP->m_data + pos;
|
||||||
|
pageP->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
|
||||||
|
m_current_ref_count++;
|
||||||
|
m_current_first_free = pageP->m_data[pos+m_record_info.m_offset_next_pool];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (pos + size < GLOBAL_PAGE_SIZE_WORDS)
|
||||||
|
{
|
||||||
|
seize_first:
|
||||||
|
ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
|
||||||
|
ptr.p = (pageP->m_data + pos);
|
||||||
|
pageP->m_data[pos+off] = ~(Uint32)m_record_info.m_type_id;
|
||||||
|
m_current_ref_count++;
|
||||||
|
m_current_pos = pos + size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_current_page)
|
||||||
|
{
|
||||||
|
m_current_page->m_first_free = REC_NIL;
|
||||||
|
m_current_page->m_next_page = RNIL;
|
||||||
|
m_current_page->m_prev_page = RNIL;
|
||||||
|
m_current_page->m_type_id = m_record_info.m_type_id;
|
||||||
|
m_current_page->m_ref_count = m_current_ref_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_first_free_page != RNIL)
|
||||||
|
{
|
||||||
|
pageP = m_current_page = m_memroot + m_first_free_page;
|
||||||
|
m_current_page_no = m_first_free_page;
|
||||||
|
m_current_pos = GLOBAL_PAGE_SIZE_WORDS;
|
||||||
|
m_current_first_free = m_current_page->m_first_free;
|
||||||
|
m_first_free_page = m_current_page->m_next_page;
|
||||||
|
m_current_ref_count = m_current_page->m_ref_count;
|
||||||
|
(m_memroot + m_first_free_page)->m_prev_page = RNIL;
|
||||||
|
goto seize_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current_ref_count = 0;
|
||||||
|
|
||||||
|
RWPage* page;
|
||||||
|
Uint32 page_no = RNIL;
|
||||||
|
if ((page = (RWPage*)m_ctx.alloc_page(m_record_info.m_type_id, &page_no)))
|
||||||
|
{
|
||||||
|
pos = 0;
|
||||||
|
m_current_page_no = page_no;
|
||||||
|
pageP = m_current_page = page;
|
||||||
|
m_current_first_free = REC_NIL;
|
||||||
|
page->m_type_id = m_record_info.m_type_id;
|
||||||
|
goto seize_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current_page = 0;
|
||||||
|
m_current_page_no = RNIL;
|
||||||
|
m_current_pos = GLOBAL_PAGE_SIZE_WORDS;
|
||||||
|
m_current_first_free = REC_NIL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RWPool::release(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
Uint32 cur_page = m_current_page_no;
|
||||||
|
Uint32 ptr_page = ptr.i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 *record_ptr = (Uint32*)ptr.p;
|
||||||
|
Uint32 magic_val = * (record_ptr + m_record_info.m_offset_magic);
|
||||||
|
|
||||||
|
if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
|
||||||
|
{
|
||||||
|
* (record_ptr + m_record_info.m_offset_magic) = 0;
|
||||||
|
if (cur_page == ptr_page)
|
||||||
|
{
|
||||||
|
* (record_ptr + m_record_info.m_offset_next_pool) = m_current_first_free;
|
||||||
|
assert(m_current_ref_count);
|
||||||
|
m_current_ref_count--;
|
||||||
|
m_current_first_free = ptr.i & POOL_RECORD_MASK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache miss on page...
|
||||||
|
RWPage* page = m_memroot + ptr_page;
|
||||||
|
Uint32 ref_cnt = page->m_ref_count;
|
||||||
|
Uint32 ff = page->m_first_free;
|
||||||
|
|
||||||
|
* (record_ptr + m_record_info.m_offset_next_pool) = ff;
|
||||||
|
page->m_first_free = ptr.i;
|
||||||
|
page->m_ref_count = ref_cnt - 1;
|
||||||
|
|
||||||
|
if (ff == REC_NIL)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* It was full...add to free page list
|
||||||
|
*/
|
||||||
|
Uint32 ffp = m_first_free_page;
|
||||||
|
if (ffp != RNIL)
|
||||||
|
{
|
||||||
|
RWPage* next = (m_memroot + ffp);
|
||||||
|
assert(next->m_prev_page == RNIL);
|
||||||
|
next->m_prev_page = ptr_page;
|
||||||
|
}
|
||||||
|
page->m_next_page = ffp;
|
||||||
|
page->m_prev_page = RNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(ref_cnt == 1)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* It's now empty...release it
|
||||||
|
*/
|
||||||
|
Uint32 prev = page->m_prev_page;
|
||||||
|
Uint32 next = page->m_next_page;
|
||||||
|
if (prev != RNIL)
|
||||||
|
{
|
||||||
|
(m_memroot + prev)->m_next_page = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_first_free_page == ptr_page);
|
||||||
|
m_first_free_page = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next != RNIL)
|
||||||
|
{
|
||||||
|
(m_memroot + next)->m_prev_page = prev;
|
||||||
|
}
|
||||||
|
m_ctx.release_page(m_record_info.m_type_id, ptr_page);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handle_invalid_release(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RWPool::handle_invalid_release(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
char buf[255];
|
||||||
|
|
||||||
|
Uint32 pos = ptr.i & POOL_RECORD_MASK;
|
||||||
|
Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 * record_ptr_p = (Uint32*)ptr.p;
|
||||||
|
Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
|
||||||
|
|
||||||
|
Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"Invalid memory release: ptr (%x %p %p) magic: (%.8x %.8x) memroot: %p page: %x",
|
||||||
|
ptr.i, ptr.p, record_ptr_i, magic, m_record_info.m_type_id,
|
||||||
|
m_memroot,
|
||||||
|
(m_memroot+pageI)->m_type_id);
|
||||||
|
|
||||||
|
m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RWPool::handle_invalid_get_ptr(Uint32 ptrI)
|
||||||
|
{
|
||||||
|
char buf[255];
|
||||||
|
|
||||||
|
Uint32 pos = ptrI & POOL_RECORD_MASK;
|
||||||
|
Uint32 pageI = ptrI >> POOL_RECORD_BITS;
|
||||||
|
Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
|
||||||
|
|
||||||
|
Uint32 magic = * (record_ptr_i + m_record_info.m_offset_magic);
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"Invalid memory access: ptr (%x %p) magic: (%.8x %.8x) memroot: %p page: %x",
|
||||||
|
ptrI, record_ptr_i, magic, m_record_info.m_type_id,
|
||||||
|
m_memroot,
|
||||||
|
(m_memroot+pageI)->m_type_id);
|
||||||
|
|
||||||
|
m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
|
||||||
|
}
|
75
storage/ndb/src/kernel/vm/RWPool.hpp
Normal file
75
storage/ndb/src/kernel/vm/RWPool.hpp
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef RWPOOL_HPP
|
||||||
|
#define RWPOOL_HPP
|
||||||
|
|
||||||
|
#include "Pool.hpp"
|
||||||
|
|
||||||
|
struct RWPage
|
||||||
|
{
|
||||||
|
Uint32 m_type_id;
|
||||||
|
Uint16 m_first_free;
|
||||||
|
Uint16 m_ref_count;
|
||||||
|
Uint32 m_next_page;
|
||||||
|
Uint32 m_prev_page;
|
||||||
|
Uint32 m_data[GLOBAL_PAGE_SIZE_WORDS - 4];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Write Pool
|
||||||
|
*/
|
||||||
|
struct RWPool
|
||||||
|
{
|
||||||
|
Record_info m_record_info;
|
||||||
|
RWPage* m_memroot;
|
||||||
|
RWPage* m_current_page;
|
||||||
|
Pool_context m_ctx;
|
||||||
|
Uint32 m_first_free_page;
|
||||||
|
Uint32 m_current_page_no;
|
||||||
|
Uint16 m_current_pos;
|
||||||
|
Uint16 m_current_first_free;
|
||||||
|
Uint16 m_current_ref_count;
|
||||||
|
public:
|
||||||
|
RWPool();
|
||||||
|
|
||||||
|
void init(const Record_info& ri, const Pool_context& pc);
|
||||||
|
bool seize(Ptr<void>&);
|
||||||
|
void release(Ptr<void>);
|
||||||
|
void * getPtr(Uint32 i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handle_invalid_release(Ptr<void>);
|
||||||
|
void handle_invalid_get_ptr(Uint32 i);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
void*
|
||||||
|
RWPool::getPtr(Uint32 i)
|
||||||
|
{
|
||||||
|
Uint32 page_no = i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 page_idx = i & POOL_RECORD_MASK;
|
||||||
|
RWPage * page = m_memroot + page_no;
|
||||||
|
Uint32 * record = page->m_data + page_idx;
|
||||||
|
Uint32 magic_val = * (record + m_record_info.m_offset_magic);
|
||||||
|
if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
|
||||||
|
{
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
handle_invalid_get_ptr(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
343
storage/ndb/src/kernel/vm/SLFifoList.hpp
Normal file
343
storage/ndb/src/kernel/vm/SLFifoList.hpp
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef SLFIFOLIST_HPP
|
||||||
|
#define SLFIFOLIST_HPP
|
||||||
|
|
||||||
|
#include <ndb_global.h>
|
||||||
|
#include <kernel_types.h>
|
||||||
|
#include "Pool.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template class used for implementing an
|
||||||
|
* list of object retreived from a pool
|
||||||
|
*/
|
||||||
|
template <typename P, typename T, typename U = T>
|
||||||
|
class SLFifoListImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* List head
|
||||||
|
*/
|
||||||
|
struct Head
|
||||||
|
{
|
||||||
|
Head();
|
||||||
|
Uint32 firstItem;
|
||||||
|
Uint32 lastItem;
|
||||||
|
|
||||||
|
#ifdef VM_TRACE
|
||||||
|
bool in_use;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline bool isEmpty() const { return firstItem == RNIL;}
|
||||||
|
};
|
||||||
|
|
||||||
|
SLFifoListImpl(P & thePool);
|
||||||
|
|
||||||
|
bool seizeFirst(Ptr<T> &);
|
||||||
|
bool seizeLast(Ptr<T> &);
|
||||||
|
bool seize(Ptr<T> & ptr) { return seizeLast(ptr);}
|
||||||
|
|
||||||
|
void releaseFirst(Ptr<T> &);
|
||||||
|
|
||||||
|
void addFirst(Ptr<T> &);
|
||||||
|
void addLast(Ptr<T> &);
|
||||||
|
|
||||||
|
void removeFirst(Ptr<T> &);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update i & p value according to <b>i</b>
|
||||||
|
*/
|
||||||
|
void getPtr(Ptr<T> &, Uint32 i) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update p value for ptr according to i value
|
||||||
|
*/
|
||||||
|
void getPtr(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get pointer for i value
|
||||||
|
*/
|
||||||
|
T * getPtr(Uint32 i) const ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update ptr to first element in list
|
||||||
|
*
|
||||||
|
* Return i
|
||||||
|
*/
|
||||||
|
bool first(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update ptr to first element in list
|
||||||
|
*
|
||||||
|
* Return i
|
||||||
|
*/
|
||||||
|
bool last(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next element
|
||||||
|
*
|
||||||
|
* NOTE ptr must be both p & i
|
||||||
|
*/
|
||||||
|
bool next(Ptr<T> &) const ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if next exists i.e. this is not last
|
||||||
|
*
|
||||||
|
* NOTE ptr must be both p & i
|
||||||
|
*/
|
||||||
|
bool hasNext(const Ptr<T> &) const;
|
||||||
|
|
||||||
|
inline bool isEmpty() const { return head.firstItem == RNIL;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Head head;
|
||||||
|
P & thePool;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U = T>
|
||||||
|
class LocalSLFifoListImpl : public SLFifoListImpl<P,T,U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LocalSLFifoListImpl(P & thePool, typename SLFifoListImpl<P,T,U>::Head &_src)
|
||||||
|
: SLFifoListImpl<P,T,U>(thePool), src(_src)
|
||||||
|
{
|
||||||
|
this->head = src;
|
||||||
|
#ifdef VM_TRACE
|
||||||
|
assert(src.in_use == false);
|
||||||
|
src.in_use = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~LocalSLFifoListImpl(){
|
||||||
|
#ifdef VM_TRACE
|
||||||
|
assert(src.in_use == true);
|
||||||
|
#endif
|
||||||
|
src = this->head;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
typename SLFifoListImpl<P,T,U>::Head & src;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
SLFifoListImpl<P,T,U>::SLFifoListImpl(P & _pool):
|
||||||
|
thePool(_pool)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
SLFifoListImpl<P,T,U>::Head::Head()
|
||||||
|
{
|
||||||
|
firstItem = RNIL;
|
||||||
|
lastItem = RNIL;
|
||||||
|
#ifdef VM_TRACE
|
||||||
|
in_use = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::seizeFirst(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
if (likely(thePool.seize(p)))
|
||||||
|
{
|
||||||
|
addFirst(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p.p = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::seizeLast(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
if (likely(thePool.seize(p)))
|
||||||
|
{
|
||||||
|
addLast(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p.p = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::addFirst(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
Uint32 first = head.firstItem;
|
||||||
|
head.firstItem = p.i;
|
||||||
|
if (first == RNIL)
|
||||||
|
{
|
||||||
|
head.lastItem = p.i;
|
||||||
|
}
|
||||||
|
p.p->U::nextList = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::addLast(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
T * t = p.p;
|
||||||
|
Uint32 last = head.lastItem;
|
||||||
|
|
||||||
|
t->U::nextList = RNIL;
|
||||||
|
head.lastItem = p.i;
|
||||||
|
|
||||||
|
if(last != RNIL)
|
||||||
|
{
|
||||||
|
T * t2 = thePool.getPtr(last);
|
||||||
|
t2->U::nextList = p.i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.firstItem = p.i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::removeFirst(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
Uint32 first = head.firstItem;
|
||||||
|
Uint32 last = head.lastItem;
|
||||||
|
assert(p.i == first);
|
||||||
|
if (first != last)
|
||||||
|
{
|
||||||
|
head.firstItem = p.p->U::nextList;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
head.firstItem = head.lastItem = RNIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::releaseFirst(Ptr<T> & p)
|
||||||
|
{
|
||||||
|
removeFirst(p);
|
||||||
|
thePool.release(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p, Uint32 i) const
|
||||||
|
{
|
||||||
|
p.i = i;
|
||||||
|
p.p = thePool.getPtr(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
SLFifoListImpl<P,T,U>::getPtr(Ptr<T> & p) const
|
||||||
|
{
|
||||||
|
thePool.getPtr(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
T *
|
||||||
|
SLFifoListImpl<P,T,U>::getPtr(Uint32 i) const
|
||||||
|
{
|
||||||
|
return thePool.getPtr(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update ptr to first element in list
|
||||||
|
*
|
||||||
|
* Return i
|
||||||
|
*/
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::first(Ptr<T> & p) const
|
||||||
|
{
|
||||||
|
p.i = head.firstItem;
|
||||||
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
|
p.p = thePool.getPtr(p.i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p.p = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::last(Ptr<T> & p) const
|
||||||
|
{
|
||||||
|
p.i = head.lastItem;
|
||||||
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
|
p.p = thePool.getPtr(p.i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p.p = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::next(Ptr<T> & p) const
|
||||||
|
{
|
||||||
|
p.i = p.p->U::nextList;
|
||||||
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
|
p.p = thePool.getPtr(p.i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
p.p = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P, typename T, typename U>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
SLFifoListImpl<P,T,U>::hasNext(const Ptr<T> & p) const
|
||||||
|
{
|
||||||
|
return p.p->U::nextList != RNIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class SLFifoList : public SLFifoListImpl<ArrayPool<T>, T, U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLFifoList(ArrayPool<T> & p) : SLFifoListImpl<ArrayPool<T>, T, U>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class LocalSLFifoList : public LocalSLFifoListImpl<ArrayPool<T>,T,U> {
|
||||||
|
public:
|
||||||
|
LocalSLFifoList(ArrayPool<T> & p, typename SLFifoList<T,U>::Head & _src)
|
||||||
|
: LocalSLFifoListImpl<ArrayPool<T>,T,U>(p, _src) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -24,8 +24,9 @@
|
||||||
* Template class used for implementing an
|
* Template class used for implementing an
|
||||||
* list of object retreived from a pool
|
* list of object retreived from a pool
|
||||||
*/
|
*/
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class SLList {
|
class SLListImpl
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* List head
|
* List head
|
||||||
|
@ -43,7 +44,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SLList(ArrayPool<T> & thePool);
|
SLListImpl(P & thePool);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate an object from pool - update Ptr
|
* Allocate an object from pool - update Ptr
|
||||||
|
@ -162,45 +163,50 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Head head;
|
Head head;
|
||||||
ArrayPool<T> & thePool;
|
P & thePool;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U = T>
|
template <typename P, typename T, typename U = T>
|
||||||
class LocalSLList : public SLList<T,U> {
|
class LocalSLListImpl : public SLListImpl<P, T, U>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
LocalSLList(ArrayPool<T> & thePool, typename SLList<T,U>::HeadPOD & _src)
|
LocalSLListImpl(P & thePool, typename SLListImpl<P, T, U>::HeadPOD & _src)
|
||||||
: SLList<T,U>(thePool), src(_src)
|
: SLListImpl<P, T, U>(thePool), src(_src)
|
||||||
{
|
{
|
||||||
this->head = src;
|
this->head = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
~LocalSLList(){
|
~LocalSLListImpl(){
|
||||||
src = this->head;
|
src = this->head;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
typename SLList<T,U>::HeadPOD & src;
|
typename SLListImpl<P, T, U>::HeadPOD & src;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
SLList<T,U>::SLList(ArrayPool<T> & _pool):
|
SLListImpl<P, T, U>::SLListImpl(P & _pool):
|
||||||
thePool(_pool){
|
thePool(_pool)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
SLList<T,U>::Head::Head(){
|
SLListImpl<P, T, U>::Head::Head()
|
||||||
|
{
|
||||||
this->init();
|
this->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::seize(Ptr<T> & p){
|
SLListImpl<P, T, U>::seize(Ptr<T> & p)
|
||||||
|
{
|
||||||
thePool.seize(p);
|
thePool.seize(p);
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
Uint32 ff = head.firstItem;
|
Uint32 ff = head.firstItem;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
t->U::nextList = ff;
|
t->U::nextList = ff;
|
||||||
head.firstItem = p.i;
|
head.firstItem = p.i;
|
||||||
return true;
|
return true;
|
||||||
|
@ -208,14 +214,16 @@ SLList<T,U>::seize(Ptr<T> & p){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::seizeId(Ptr<T> & p, Uint32 ir){
|
SLListImpl<P, T, U>::seizeId(Ptr<T> & p, Uint32 ir)
|
||||||
|
{
|
||||||
thePool.seizeId(p, ir);
|
thePool.seizeId(p, ir);
|
||||||
T * t = p.p;
|
T * t = p.p;
|
||||||
Uint32 ff = head.firstItem;
|
Uint32 ff = head.firstItem;
|
||||||
if(p.i != RNIL){
|
if(p.i != RNIL)
|
||||||
|
{
|
||||||
t->U::nextList = ff;
|
t->U::nextList = ff;
|
||||||
head.firstItem = p.i;
|
head.firstItem = p.i;
|
||||||
return true;
|
return true;
|
||||||
|
@ -223,20 +231,24 @@ SLList<T,U>::seizeId(Ptr<T> & p, Uint32 ir){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::seizeN(Ptr<T> & p, Uint32 n){
|
SLListImpl<P, T, U>::seizeN(Ptr<T> & p, Uint32 n)
|
||||||
for(Uint32 i = 0; i < n; i++){
|
{
|
||||||
if(seize(p) == RNIL){
|
for(Uint32 i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
if(seize(p) == RNIL)
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Failure
|
* Failure
|
||||||
*/
|
*/
|
||||||
for(; i > 0; i--){
|
for(; i > 0; i--)
|
||||||
const Uint32 tmp = head.firstItem;
|
{
|
||||||
const T * t = thePool.getPtr(tmp);
|
p.i = head.firstItem;
|
||||||
head.firstItem = t->U::nextList;
|
thePool.getPtr(p);
|
||||||
thePool.release(tmp);
|
head.firstItem = p.p->U::nextList;
|
||||||
|
thePool.release(p);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -252,17 +264,19 @@ SLList<T,U>::seizeN(Ptr<T> & p, Uint32 n){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
SLList<T,U>::remove(){
|
SLListImpl<P, T, U>::remove()
|
||||||
|
{
|
||||||
head.firstItem = RNIL;
|
head.firstItem = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::remove_front(Ptr<T> & p){
|
SLListImpl<P, T, U>::remove_front(Ptr<T> & p)
|
||||||
|
{
|
||||||
p.i = head.firstItem;
|
p.i = head.firstItem;
|
||||||
if (p.i != RNIL)
|
if (p.i != RNIL)
|
||||||
{
|
{
|
||||||
|
@ -273,45 +287,51 @@ SLList<T,U>::remove_front(Ptr<T> & p){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
SLList<T,U>::add(Uint32 first, Ptr<T> & last){
|
SLListImpl<P, T, U>::add(Uint32 first, Ptr<T> & last)
|
||||||
|
{
|
||||||
last.p->U::nextList = head.firstItem;
|
last.p->U::nextList = head.firstItem;
|
||||||
head.firstItem = first;
|
head.firstItem = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
SLList<T,U>::release(){
|
SLListImpl<P, T, U>::release()
|
||||||
while(head.firstItem != RNIL){
|
{
|
||||||
const T * t = thePool.getPtr(head.firstItem);
|
Ptr<T> ptr;
|
||||||
const Uint32 i = head.firstItem;
|
while((ptr.i = head.firstItem) != RNIL)
|
||||||
head.firstItem = t->U::nextList;
|
{
|
||||||
thePool.release(i);
|
thePool.getPtr(ptr);
|
||||||
|
head.firstItem = ptr.p->U::nextList;
|
||||||
|
thePool.release(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
SLList<T,U>::getPtr(Ptr<T> & p, Uint32 i) const {
|
SLListImpl<P, T, U>::getPtr(Ptr<T> & p, Uint32 i) const
|
||||||
|
{
|
||||||
p.i = i;
|
p.i = i;
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
SLList<T,U>::getPtr(Ptr<T> & p) const {
|
SLListImpl<P, T, U>::getPtr(Ptr<T> & p) const
|
||||||
|
{
|
||||||
thePool.getPtr(p);
|
thePool.getPtr(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
T *
|
T *
|
||||||
SLList<T,U>::getPtr(Uint32 i) const {
|
SLListImpl<P, T, U>::getPtr(Uint32 i) const
|
||||||
|
{
|
||||||
return thePool.getPtr(i);
|
return thePool.getPtr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,13 +340,15 @@ SLList<T,U>::getPtr(Uint32 i) const {
|
||||||
*
|
*
|
||||||
* Return i
|
* Return i
|
||||||
*/
|
*/
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::first(Ptr<T> & p) const {
|
SLListImpl<P, T, U>::first(Ptr<T> & p) const
|
||||||
|
{
|
||||||
Uint32 i = head.firstItem;
|
Uint32 i = head.firstItem;
|
||||||
p.i = i;
|
p.i = i;
|
||||||
if(i != RNIL){
|
if(i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -334,13 +356,15 @@ SLList<T,U>::first(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::next(Ptr<T> & p) const {
|
SLListImpl<P, T, U>::next(Ptr<T> & p) const
|
||||||
|
{
|
||||||
Uint32 i = p.p->U::nextList;
|
Uint32 i = p.p->U::nextList;
|
||||||
p.i = i;
|
p.i = i;
|
||||||
if(i != RNIL){
|
if(i != RNIL)
|
||||||
|
{
|
||||||
p.p = thePool.getPtr(i);
|
p.p = thePool.getPtr(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -348,11 +372,29 @@ SLList<T,U>::next(Ptr<T> & p) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class U>
|
template <typename P, typename T, typename U>
|
||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
SLList<T,U>::hasNext(const Ptr<T> & p) const {
|
SLListImpl<P, T, U>::hasNext(const Ptr<T> & p) const
|
||||||
|
{
|
||||||
return p.p->U::nextList != RNIL;
|
return p.p->U::nextList != RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specializations
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class SLList : public SLListImpl<ArrayPool<T>, T, U>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLList(ArrayPool<T> & p) : SLListImpl<ArrayPool<T>, T, U>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
class LocalSLList : public LocalSLListImpl<ArrayPool<T>,T,U> {
|
||||||
|
public:
|
||||||
|
LocalSLList(ArrayPool<T> & p, typename SLList<T,U>::Head & _src)
|
||||||
|
: LocalSLListImpl<ArrayPool<T>,T,U>(p, _src) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include <SimulatedBlock.hpp>
|
#include <SimulatedBlock.hpp>
|
||||||
|
|
||||||
class Configuration;
|
class EmulatorData;
|
||||||
|
|
||||||
class SimBlockList
|
class SimBlockList
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ public:
|
||||||
SimBlockList();
|
SimBlockList();
|
||||||
~SimBlockList();
|
~SimBlockList();
|
||||||
|
|
||||||
void load(Configuration & conf);
|
void load(EmulatorData&);
|
||||||
void unload();
|
void unload();
|
||||||
private:
|
private:
|
||||||
int noOfBlocks;
|
int noOfBlocks;
|
||||||
|
|
|
@ -52,6 +52,7 @@ SimulatedBlock::SimulatedBlock(BlockNumber blockNumber,
|
||||||
theReference(numberToRef(blockNumber, globalData.ownId)),
|
theReference(numberToRef(blockNumber, globalData.ownId)),
|
||||||
m_ctx(ctx),
|
m_ctx(ctx),
|
||||||
m_global_page_pool(globalData.m_global_page_pool),
|
m_global_page_pool(globalData.m_global_page_pool),
|
||||||
|
m_shared_page_pool(globalData.m_shared_page_pool),
|
||||||
c_fragmentInfoHash(c_fragmentInfoPool),
|
c_fragmentInfoHash(c_fragmentInfoPool),
|
||||||
c_linearFragmentSendList(c_fragmentSendPool),
|
c_linearFragmentSendList(c_fragmentSendPool),
|
||||||
c_segmentedFragmentSendList(c_fragmentSendPool),
|
c_segmentedFragmentSendList(c_fragmentSendPool),
|
||||||
|
@ -2031,3 +2032,6 @@ SimulatedBlock::create_distr_key(Uint32 tableId,
|
||||||
}
|
}
|
||||||
return dstPos;
|
return dstPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CArray<KeyDescriptor> g_key_descriptor_pool;
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
#include "DLList.hpp"
|
#include "DLList.hpp"
|
||||||
#include "ArrayPool.hpp"
|
#include "ArrayPool.hpp"
|
||||||
#include "DLHashTable.hpp"
|
#include "DLHashTable.hpp"
|
||||||
|
#include "WOPool.hpp"
|
||||||
|
#include "RWPool.hpp"
|
||||||
#include "Callback.hpp"
|
#include "Callback.hpp"
|
||||||
#include "SafeCounter.hpp"
|
#include "SafeCounter.hpp"
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@
|
||||||
#include <signaldata/ReadConfig.hpp>
|
#include <signaldata/ReadConfig.hpp>
|
||||||
#include <signaldata/UpgradeStartup.hpp>
|
#include <signaldata/UpgradeStartup.hpp>
|
||||||
#include "ndbd_malloc_impl.hpp"
|
#include "ndbd_malloc_impl.hpp"
|
||||||
|
#include <blocks/record_types.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Something for filesystem access
|
* Something for filesystem access
|
||||||
|
@ -93,6 +96,7 @@ class SimulatedBlock {
|
||||||
friend class Page_cache_client;
|
friend class Page_cache_client;
|
||||||
friend class Lgman;
|
friend class Lgman;
|
||||||
friend class Logfile_client;
|
friend class Logfile_client;
|
||||||
|
friend struct Pool_context;
|
||||||
public:
|
public:
|
||||||
friend class BlockComponent;
|
friend class BlockComponent;
|
||||||
virtual ~SimulatedBlock();
|
virtual ~SimulatedBlock();
|
||||||
|
@ -427,7 +431,8 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ArrayPool<GlobalPage>& m_global_page_pool;
|
ArrayPool<GlobalPage>& m_global_page_pool;
|
||||||
|
ArrayPool<GlobalPage>& m_shared_page_pool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Node state
|
* Node state
|
||||||
|
|
137
storage/ndb/src/kernel/vm/WOPool.cpp
Normal file
137
storage/ndb/src/kernel/vm/WOPool.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "WOPool.hpp"
|
||||||
|
#include <ndbd_exit_codes.h>
|
||||||
|
#include <NdbOut.hpp>
|
||||||
|
|
||||||
|
WOPool::WOPool()
|
||||||
|
{
|
||||||
|
bzero(this, sizeof(* this));
|
||||||
|
m_current_pos = GLOBAL_PAGE_SIZE_WORDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WOPool::init(const Record_info& ri, const Pool_context& pc)
|
||||||
|
{
|
||||||
|
m_ctx = pc;
|
||||||
|
m_record_info = ri;
|
||||||
|
m_record_info.m_size = ((ri.m_size + 3) >> 2); // Align to word boundary
|
||||||
|
m_record_info.m_offset_magic = ((ri.m_offset_magic + 3) >> 2);
|
||||||
|
m_memroot = (WOPage*)m_ctx.get_memroot();
|
||||||
|
ndbout_c("WOPool::init(%x, %d)",ri.m_type_id, m_record_info.m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WOPool::seize_new_page(Ptr<void>& ptr)
|
||||||
|
{
|
||||||
|
WOPage* page;
|
||||||
|
Uint32 page_no = RNIL;
|
||||||
|
if ((page = (WOPage*)m_ctx.alloc_page(m_record_info.m_type_id, &page_no)))
|
||||||
|
{
|
||||||
|
if (m_current_page)
|
||||||
|
{
|
||||||
|
m_current_page->m_ref_count = m_current_ref_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_current_pos = 0;
|
||||||
|
m_current_ref_count = 0;
|
||||||
|
m_current_page_no = page_no;
|
||||||
|
m_current_page = page;
|
||||||
|
page->m_type_id = m_record_info.m_type_id;
|
||||||
|
bool ret = seize(ptr);
|
||||||
|
assert(ret);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WOPool::release_not_current(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
WOPage* page = (WOPage*)(UintPtr(ptr.p) & ~(GLOBAL_PAGE_SIZE - 1));
|
||||||
|
Uint32 cnt = page->m_ref_count;
|
||||||
|
Uint32 type = page->m_type_id;
|
||||||
|
Uint32 ri_type = m_record_info.m_type_id;
|
||||||
|
if (likely(cnt && type == ri_type))
|
||||||
|
{
|
||||||
|
if (cnt == 1)
|
||||||
|
{
|
||||||
|
m_ctx.release_page(ri_type, ptr.i >> POOL_RECORD_BITS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
page->m_ref_count = cnt - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_inconsistent_release(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WOPool::handle_invalid_release(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
char buf[255];
|
||||||
|
|
||||||
|
Uint32 pos = ptr.i & POOL_RECORD_MASK;
|
||||||
|
Uint32 pageI = ptr.i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 * record_ptr_p = (Uint32*)ptr.p;
|
||||||
|
Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
|
||||||
|
|
||||||
|
Uint32 magic = * (record_ptr_p + m_record_info.m_offset_magic);
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"Invalid memory release: ptr (%x %p %p) magic: (%.8x %.8x) memroot: %p page: %x",
|
||||||
|
ptr.i, ptr.p, record_ptr_i, magic, m_record_info.m_type_id,
|
||||||
|
m_memroot,
|
||||||
|
(m_memroot+pageI)->m_type_id);
|
||||||
|
|
||||||
|
m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WOPool::handle_invalid_get_ptr(Uint32 ptrI)
|
||||||
|
{
|
||||||
|
char buf[255];
|
||||||
|
|
||||||
|
Uint32 pos = ptrI & POOL_RECORD_MASK;
|
||||||
|
Uint32 pageI = ptrI >> POOL_RECORD_BITS;
|
||||||
|
Uint32 * record_ptr_i = (m_memroot+pageI)->m_data + pos;
|
||||||
|
|
||||||
|
Uint32 magic = * (record_ptr_i + m_record_info.m_offset_magic);
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"Invalid memory access: ptr (%x %p) magic: (%.8x %.8x) memroot: %p page: %x",
|
||||||
|
ptrI, record_ptr_i, magic, m_record_info.m_type_id,
|
||||||
|
m_memroot,
|
||||||
|
(m_memroot+pageI)->m_type_id);
|
||||||
|
|
||||||
|
m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WOPool::handle_inconsistent_release(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
WOPage* page = (WOPage*)(UintPtr(ptr.p) & ~(GLOBAL_PAGE_SIZE - 1));
|
||||||
|
Uint32 cnt = page->m_ref_count;
|
||||||
|
Uint32 type = page->m_type_id;
|
||||||
|
Uint32 ri_type = m_record_info.m_type_id;
|
||||||
|
|
||||||
|
char buf[255];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"Memory corruption: ptr (%x %p) page (%d %x %x)",
|
||||||
|
ptr.i, ptr.p, cnt, type, ri_type);
|
||||||
|
|
||||||
|
m_ctx.handleAbort(NDBD_EXIT_PRGERR, buf);
|
||||||
|
}
|
120
storage/ndb/src/kernel/vm/WOPool.hpp
Normal file
120
storage/ndb/src/kernel/vm/WOPool.hpp
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
/* Copyright (C) 2003 MySQL AB
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef WOPOOL_HPP
|
||||||
|
#define WOPOOL_HPP
|
||||||
|
|
||||||
|
#include "Pool.hpp"
|
||||||
|
|
||||||
|
struct WOPage
|
||||||
|
{
|
||||||
|
Uint32 m_type_id;
|
||||||
|
Uint32 m_ref_count;
|
||||||
|
Uint32 m_data[GLOBAL_PAGE_SIZE_WORDS - 2];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write Once Pool
|
||||||
|
*/
|
||||||
|
struct WOPool
|
||||||
|
{
|
||||||
|
Record_info m_record_info;
|
||||||
|
WOPage* m_memroot;
|
||||||
|
WOPage* m_current_page;
|
||||||
|
Pool_context m_ctx;
|
||||||
|
Uint32 m_current_page_no;
|
||||||
|
Uint16 m_current_pos;
|
||||||
|
Uint16 m_current_ref_count;
|
||||||
|
public:
|
||||||
|
WOPool();
|
||||||
|
|
||||||
|
void init(const Record_info& ri, const Pool_context& pc);
|
||||||
|
bool seize(Ptr<void>&);
|
||||||
|
void release(Ptr<void>);
|
||||||
|
void * getPtr(Uint32 i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool seize_new_page(Ptr<void>&);
|
||||||
|
void release_not_current(Ptr<void>);
|
||||||
|
|
||||||
|
void handle_invalid_release(Ptr<void>);
|
||||||
|
void handle_invalid_get_ptr(Uint32 i);
|
||||||
|
void handle_inconsistent_release(Ptr<void>);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
WOPool::seize(Ptr<void>& ptr)
|
||||||
|
{
|
||||||
|
Uint32 pos = m_current_pos;
|
||||||
|
Uint32 size = m_record_info.m_size;
|
||||||
|
WOPage *pageP = m_current_page;
|
||||||
|
if (likely(pos + size < GLOBAL_PAGE_SIZE_WORDS))
|
||||||
|
{
|
||||||
|
ptr.i = (m_current_page_no << POOL_RECORD_BITS) + pos;
|
||||||
|
ptr.p = (pageP->m_data + pos);
|
||||||
|
pageP->m_data[pos+m_record_info.m_offset_magic] = ~(Uint32)m_record_info.m_type_id;
|
||||||
|
m_current_pos = pos + size;
|
||||||
|
m_current_ref_count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return seize_new_page(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
WOPool::release(Ptr<void> ptr)
|
||||||
|
{
|
||||||
|
Uint32 cur_page = m_current_page_no;
|
||||||
|
Uint32 ptr_page = ptr.i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 *magic_ptr = (((Uint32*)ptr.p)+m_record_info.m_offset_magic);
|
||||||
|
Uint32 magic_val = *magic_ptr;
|
||||||
|
|
||||||
|
if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
|
||||||
|
{
|
||||||
|
* magic_ptr = 0;
|
||||||
|
if (cur_page == ptr_page)
|
||||||
|
{
|
||||||
|
if (m_current_ref_count == 1)
|
||||||
|
{
|
||||||
|
m_current_pos = 0;
|
||||||
|
}
|
||||||
|
m_current_ref_count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return release_not_current(ptr);
|
||||||
|
}
|
||||||
|
handle_invalid_release(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void*
|
||||||
|
WOPool::getPtr(Uint32 i)
|
||||||
|
{
|
||||||
|
Uint32 page_no = i >> POOL_RECORD_BITS;
|
||||||
|
Uint32 page_idx = i & POOL_RECORD_MASK;
|
||||||
|
WOPage * page = m_memroot + page_no;
|
||||||
|
Uint32 * record = page->m_data + page_idx;
|
||||||
|
Uint32 magic_val = * (record + m_record_info.m_offset_magic);
|
||||||
|
if (likely(magic_val == ~(Uint32)m_record_info.m_type_id))
|
||||||
|
{
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
handle_invalid_get_ptr(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,66 +15,123 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
#include "NdbdSuperPool.hpp"
|
|
||||||
#include "ArrayPool.hpp"
|
#include "ArrayPool.hpp"
|
||||||
|
#include "WOPool.hpp"
|
||||||
|
#include "RWPool.hpp"
|
||||||
#include <NdbTick.h>
|
#include <NdbTick.h>
|
||||||
#include "ndbd_malloc_impl.hpp"
|
#include "ndbd_malloc_impl.hpp"
|
||||||
|
#include "SimulatedBlock.hpp"
|
||||||
|
|
||||||
|
#ifdef USE_CALLGRIND
|
||||||
|
#include <valgrind/callgrind.h>
|
||||||
|
#else
|
||||||
|
#define CALLGRIND_TOGGLE_COLLECT()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define T_TEST_AP (1 << 0)
|
||||||
|
#define T_TEST_WO (1 << 1)
|
||||||
|
#define T_TEST_RW (1 << 2)
|
||||||
|
|
||||||
|
#define T_SEIZE (1 << 0)
|
||||||
|
#define T_RELEASE (1 << 1)
|
||||||
|
#define T_G_RELEASE (1 << 2)
|
||||||
|
#define T_R_RELEASE (1 << 3)
|
||||||
|
#define T_R_G_RELEASE (1 << 4)
|
||||||
|
#define T_MIX (1 << 5)
|
||||||
|
#define T_GETPTR (1 << 6)
|
||||||
|
#define T_FIFO (1 << 7)
|
||||||
|
|
||||||
|
const char *test_names[] = {
|
||||||
|
"seize",
|
||||||
|
"release",
|
||||||
|
"get+rel",
|
||||||
|
"r-rel",
|
||||||
|
"r-get+rel",
|
||||||
|
"mix",
|
||||||
|
"getptr",
|
||||||
|
"fifo",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
Uint32 pools = ~0;
|
||||||
|
Uint32 tests = ~0;
|
||||||
|
Uint32 records = ~0;
|
||||||
|
Uint32 sizes = 7;
|
||||||
|
unsigned int seed;
|
||||||
|
Ndbd_mem_manager mm;
|
||||||
|
Configuration cfg;
|
||||||
|
Block_context ctx = { cfg, mm };
|
||||||
|
struct BB : public SimulatedBlock
|
||||||
|
{
|
||||||
|
BB(int no, Block_context& ctx) : SimulatedBlock(no, ctx) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
BB block(DBACC, ctx);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
|
||||||
void
|
void
|
||||||
init(ArrayPool<T> & pool, Uint32 cnt)
|
init(ArrayPool<T> & pool, Uint32 cnt)
|
||||||
{
|
{
|
||||||
pool.setSize(cnt + 1);
|
pool.setSize(cnt + 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
|
||||||
void
|
void
|
||||||
init(RecordPool<T> & pool, Uint32 cnt)
|
init(RecordPool<T, WOPool> & pool, Uint32 cnt)
|
||||||
{
|
{
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = █
|
||||||
|
pool.wo_pool_init(0x2001, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void
|
||||||
|
init(RecordPool<T, RWPool> & pool, Uint32 cnt)
|
||||||
|
{
|
||||||
|
Pool_context pc;
|
||||||
|
pc.m_block = █
|
||||||
|
pool.init(0x2001, pc);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename R>
|
template <typename T, typename R>
|
||||||
inline
|
|
||||||
void
|
void
|
||||||
test_pool(R& pool, Uint32 cnt, Uint32 loops)
|
test_pool(R& pool, Uint32 cnt, Uint32 loops)
|
||||||
{
|
{
|
||||||
init(pool, cnt);
|
|
||||||
Ptr<T> ptr;
|
Ptr<T> ptr;
|
||||||
Uint32 *arr = (Uint32*)alloca(cnt * sizeof(Uint32));
|
Uint32 *arr = (Uint32*)alloca(cnt * sizeof(Uint32));
|
||||||
|
bzero(arr, cnt * sizeof(Uint32));
|
||||||
|
if (tests & T_SEIZE)
|
||||||
{
|
{
|
||||||
printf(" ; seize "); fflush(stdout);
|
|
||||||
Uint64 sum = 0;
|
Uint64 sum = 0;
|
||||||
for(Uint32 i = 0; i<loops; i++)
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
{
|
{ // seize
|
||||||
Uint64 start = NdbTick_CurrentMillisecond();
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
{
|
{
|
||||||
bool b = pool.seize(ptr);
|
bool b = pool.seize(ptr);
|
||||||
arr[j] = ptr.i;
|
arr[j] = ptr.i;
|
||||||
|
ptr.p->do_stuff();
|
||||||
assert(b);
|
assert(b);
|
||||||
}
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
Uint64 stop = NdbTick_CurrentMillisecond();
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
{
|
{
|
||||||
ptr.i = arr[j];
|
ptr.i = arr[j];
|
||||||
pool.getPtr(ptr);
|
pool.getPtr(ptr);
|
||||||
pool.release(ptr);
|
ptr.p->do_stuff();
|
||||||
|
pool.release(ptr.i);
|
||||||
arr[j] = RNIL;
|
arr[j] = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum += (stop - start);
|
sum += (stop - start);
|
||||||
if (i == 0)
|
|
||||||
printf("; first ; %lld", (stop - start));
|
|
||||||
}
|
}
|
||||||
printf(" ; avg ; %lld ; tot ; %lld", sum/loops, sum);fflush(stdout);
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (tests & T_RELEASE)
|
||||||
printf(" ; release "); fflush(stdout);
|
{ // release
|
||||||
Uint64 sum = 0;
|
Uint64 sum = 0;
|
||||||
for(Uint32 i = 0; i<loops; i++)
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
{
|
{
|
||||||
|
@ -82,44 +139,135 @@ test_pool(R& pool, Uint32 cnt, Uint32 loops)
|
||||||
{
|
{
|
||||||
bool b = pool.seize(ptr);
|
bool b = pool.seize(ptr);
|
||||||
arr[j] = ptr.i;
|
arr[j] = ptr.i;
|
||||||
assert(b);
|
ptr.p->do_stuff();
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint64 start = NdbTick_CurrentMillisecond();
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
{
|
{
|
||||||
ptr.i = arr[j];
|
pool.release(arr[j]);
|
||||||
pool.release(ptr);
|
|
||||||
arr[j] = RNIL;
|
arr[j] = RNIL;
|
||||||
}
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
Uint64 stop = NdbTick_CurrentMillisecond();
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
sum += (stop - start);
|
sum += (stop - start);
|
||||||
}
|
}
|
||||||
printf("; avg ; %lld ; tot ; %lld", sum/loops, sum); fflush(stdout);
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tests & T_G_RELEASE)
|
||||||
|
{ // getptr + release
|
||||||
|
Uint64 sum = 0;
|
||||||
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
|
{
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
bool b = pool.seize(ptr);
|
||||||
|
arr[j] = ptr.i;
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
pool.getPtr(ptr, arr[j]);
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
pool.release(ptr);
|
||||||
|
arr[j] = RNIL;
|
||||||
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
|
sum += (stop - start);
|
||||||
|
}
|
||||||
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tests & T_R_RELEASE)
|
||||||
|
{ // release reverse
|
||||||
|
Uint64 sum = 0;
|
||||||
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
|
{
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
bool b = pool.seize(ptr);
|
||||||
|
arr[j] = ptr.i;
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
pool.release(arr[cnt - j - 1]);
|
||||||
|
arr[cnt - j - 1] = RNIL;
|
||||||
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
|
sum += (stop - start);
|
||||||
|
}
|
||||||
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tests & T_R_G_RELEASE)
|
||||||
|
{ // getptr + release
|
||||||
|
Uint64 sum = 0;
|
||||||
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
|
{
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
bool b = pool.seize(ptr);
|
||||||
|
arr[j] = ptr.i;
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
pool.getPtr(ptr, arr[cnt - j - 1]);
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
pool.release(ptr);
|
||||||
|
arr[cnt - j - 1] = RNIL;
|
||||||
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
|
sum += (stop - start);
|
||||||
|
}
|
||||||
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tests & T_MIX)
|
||||||
{
|
{
|
||||||
printf(" ; mix"); fflush(stdout);
|
|
||||||
|
|
||||||
Uint64 sum = 0;
|
Uint64 sum = 0;
|
||||||
Uint64 start = NdbTick_CurrentMillisecond();
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
Uint32 lseed = seed;
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
for(Uint32 i = 0; i<loops * cnt; i++)
|
for(Uint32 i = 0; i<loops * cnt; i++)
|
||||||
{
|
{
|
||||||
int pos = rand() % cnt;
|
int pos = rand_r(&lseed) % cnt;
|
||||||
ptr.i = arr[pos];
|
ptr.i = arr[pos];
|
||||||
if (ptr.i == RNIL)
|
if (ptr.i == RNIL)
|
||||||
{
|
{
|
||||||
pool.seize(ptr);
|
pool.seize(ptr);
|
||||||
arr[pos] = ptr.i;
|
arr[pos] = ptr.i;
|
||||||
assert(ptr.i != RNIL);
|
assert(ptr.i != RNIL);
|
||||||
|
ptr.p->do_stuff();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
pool.getPtr(ptr);
|
||||||
|
ptr.p->do_stuff();
|
||||||
pool.release(ptr);
|
pool.release(ptr);
|
||||||
arr[pos] = RNIL;
|
arr[pos] = RNIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
Uint64 stop = NdbTick_CurrentMillisecond();
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
@ -128,7 +276,7 @@ test_pool(R& pool, Uint32 cnt, Uint32 loops)
|
||||||
if (ptr.i != RNIL)
|
if (ptr.i != RNIL)
|
||||||
{
|
{
|
||||||
pool.getPtr(ptr);
|
pool.getPtr(ptr);
|
||||||
pool.release(ptr);
|
pool.release(ptr.i);
|
||||||
}
|
}
|
||||||
arr[j] = RNIL;
|
arr[j] = RNIL;
|
||||||
}
|
}
|
||||||
|
@ -137,113 +285,322 @@ test_pool(R& pool, Uint32 cnt, Uint32 loops)
|
||||||
printf(" ; %lld", sum); fflush(stdout);
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tests & T_GETPTR)
|
||||||
{
|
{
|
||||||
printf(" ; getPtr"); fflush(stdout);
|
Uint32 lseed = seed;
|
||||||
|
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
{
|
{
|
||||||
bool b = pool.seize(ptr);
|
bool b = pool.seize(ptr);
|
||||||
arr[j] = ptr.i;
|
arr[j] = ptr.i;
|
||||||
|
ptr.p->do_stuff();
|
||||||
assert(b);
|
assert(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint64 sum = 0;
|
Uint64 sum = 0;
|
||||||
Uint64 start = NdbTick_CurrentMillisecond();
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
for(Uint32 i = 0; i<loops * cnt; i++)
|
for(Uint32 i = 0; i<loops * cnt; i++)
|
||||||
{
|
{
|
||||||
int pos = rand() % cnt;
|
int pos = rand_r(&lseed) % cnt;
|
||||||
ptr.i = arr[pos];
|
ptr.i = arr[pos];
|
||||||
pool.getPtr(ptr);
|
pool.getPtr(ptr);
|
||||||
|
ptr.p->do_stuff();
|
||||||
}
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
Uint64 stop = NdbTick_CurrentMillisecond();
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
|
||||||
for(Uint32 j = 0; j<cnt; j++)
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
{
|
{
|
||||||
ptr.i = arr[j];
|
ptr.i = arr[j];
|
||||||
pool.getPtr(ptr);
|
pool.getPtr(ptr);
|
||||||
pool.release(ptr);
|
ptr.p->do_stuff();
|
||||||
|
pool.release(ptr.i);
|
||||||
arr[j] = RNIL;
|
arr[j] = RNIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum += (stop - start);
|
sum += (stop - start);
|
||||||
printf(" ; %lld", sum); fflush(stdout);
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tests & T_FIFO)
|
||||||
|
{ // fifo
|
||||||
|
Uint64 sum = 0;
|
||||||
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
for(Uint32 i = 0; i<loops; i++)
|
||||||
|
{
|
||||||
|
Uint32 head = RNIL;
|
||||||
|
Uint32 last = RNIL;
|
||||||
|
|
||||||
|
Uint64 sum = 0;
|
||||||
|
for(Uint32 j = 0; j<cnt; j++)
|
||||||
|
{
|
||||||
|
pool.seize(ptr);
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
ptr.p->m_nextList = RNIL;
|
||||||
|
if (head == RNIL)
|
||||||
|
{
|
||||||
|
head = ptr.i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
T* t = pool.getPtr(last);
|
||||||
|
t->m_nextList = ptr.i;
|
||||||
|
}
|
||||||
|
last = ptr.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (head != RNIL)
|
||||||
|
{
|
||||||
|
pool.getPtr(ptr, head);
|
||||||
|
ptr.p->do_stuff();
|
||||||
|
head = ptr.p->m_nextList;
|
||||||
|
pool.release(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CALLGRIND_TOGGLE_COLLECT();
|
||||||
|
Uint64 stop = NdbTick_CurrentMillisecond();
|
||||||
|
sum += (stop - start);
|
||||||
|
printf(" ; %lld", sum); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
ndbout_c("");
|
ndbout_c("");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Uint32 sz> struct Rec { char data[sz-4]; Uint32 nextPool; };
|
template <Uint32 sz>
|
||||||
|
struct Rec {
|
||||||
|
Uint32 m_data;
|
||||||
|
Uint32 m_magic;
|
||||||
|
Uint32 nextPool;
|
||||||
|
Uint32 m_nextList;
|
||||||
|
char m_cdata[sz-16];
|
||||||
|
|
||||||
|
void do_stuff() {
|
||||||
|
Uint32 sum = 0;
|
||||||
|
Uint32 *ptr = (Uint32*)this;
|
||||||
|
for(Uint32 i = 0; i<(sz >> 2); i++)
|
||||||
|
sum += * ptr ++;
|
||||||
|
m_data = sum;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef Rec<32> Rec32;
|
typedef Rec<32> Rec32;
|
||||||
typedef Rec<36> Rec36;
|
typedef Rec<36> Rec36;
|
||||||
typedef Rec<256> Rec256;
|
typedef Rec<56> Rec56;
|
||||||
typedef Rec<260> Rec260;
|
typedef Rec<224> Rec224;
|
||||||
|
|
||||||
Ndbd_mem_manager mem;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline
|
|
||||||
void test_rp(Uint32 cnt, Uint32 loop, Uint32 pgsz)
|
|
||||||
{
|
|
||||||
printf("RP ; %d ; ws ; %d ; page ; %d",
|
|
||||||
sizeof(T), (sizeof(T)*cnt) >> 10, pgsz >> 10);
|
|
||||||
NdbdSuperPool sp(mem, pgsz, 19);
|
|
||||||
GroupPool gp(sp);
|
|
||||||
sp.init_1();
|
|
||||||
sp.init_2();
|
|
||||||
|
|
||||||
sp.setInitPages(4);
|
|
||||||
sp.setIncrPages(4);
|
|
||||||
sp.setMaxPages(~0);
|
|
||||||
sp.allocMemory();
|
|
||||||
|
|
||||||
RecordPool<T> pool(gp);
|
|
||||||
test_pool<T, RecordPool<T> >(pool, cnt, loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline
|
|
||||||
void test_ap(Uint32 cnt, Uint32 loop)
|
void test_ap(Uint32 cnt, Uint32 loop)
|
||||||
{
|
{
|
||||||
printf("AP ; %d ; ws ; %d ; page ; n/a", sizeof(T), (cnt * sizeof(T))>>10);
|
printf("AP ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
|
||||||
ArrayPool<T> pool;
|
ArrayPool<T> pool;
|
||||||
|
init(pool, cnt);
|
||||||
test_pool<T, ArrayPool<T> >(pool, cnt, loop);
|
test_pool<T, ArrayPool<T> >(pool, cnt, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void test_rw(Uint32 cnt, Uint32 loop)
|
||||||
|
{
|
||||||
|
printf("RW ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
|
||||||
|
RecordPool<T, RWPool> pool;
|
||||||
|
init(pool, cnt);
|
||||||
|
test_pool<T, RecordPool<T, RWPool> >(pool, cnt, loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void test_wo(Uint32 cnt, Uint32 loop)
|
||||||
|
{
|
||||||
|
printf("WO ; %d ; %d", sizeof(T), (cnt * sizeof(T))>>10); fflush(stdout);
|
||||||
|
RecordPool<T, WOPool> pool;
|
||||||
|
init(pool, cnt);
|
||||||
|
test_pool<T, RecordPool<T, WOPool> >(pool, cnt, loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <EventLogger.hpp>
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
mem.init(10000);
|
Uint32 loops = 300000;
|
||||||
|
for (Uint32 i = 1 ; i<argc ; i++)
|
||||||
|
{
|
||||||
|
if (argc > i+1 && strcmp(argv[i], "-pools") == 0)
|
||||||
|
{
|
||||||
|
pools = 0;
|
||||||
|
for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
|
||||||
|
{
|
||||||
|
char c = argv[i+1][j];
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
pools |= 1 << (c - '0');
|
||||||
|
else
|
||||||
|
pools |= 1 << (10 + (c - 'a'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc > i+1 && strcmp(argv[i], "-tests") == 0)
|
||||||
|
{
|
||||||
|
tests = 0;
|
||||||
|
for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
|
||||||
|
{
|
||||||
|
char c = argv[i+1][j];
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
tests |= 1 << (c - '0');
|
||||||
|
else
|
||||||
|
tests |= 1 << (10 + (c - 'a'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc > i+1 && strcmp(argv[i], "-sizes") == 0)
|
||||||
|
{
|
||||||
|
sizes = 0;
|
||||||
|
for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
|
||||||
|
{
|
||||||
|
char c = argv[i+1][j];
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
sizes |= 1 << (c - '0');
|
||||||
|
else
|
||||||
|
sizes |= 1 << (10 + (c - 'a'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc > i+1 && strcmp(argv[i], "-records") == 0)
|
||||||
|
{
|
||||||
|
records = 0;
|
||||||
|
for (Uint32 j = 0; j<strlen(argv[i+1]); j++)
|
||||||
|
{
|
||||||
|
char c = argv[i+1][j];
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
records |= 1 << (c - '0');
|
||||||
|
else
|
||||||
|
records |= 1 << (10 + (c - 'a'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (argc > i+1 && strcmp(argv[i], "-loop") == 0)
|
||||||
|
{
|
||||||
|
loops = atoi(argv[i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource_limit rl;
|
||||||
|
rl.m_min = 0;
|
||||||
|
rl.m_max = 10000;
|
||||||
|
rl.m_resource_id = 0;
|
||||||
|
mm.set_resource_limit(rl);
|
||||||
|
if(!mm.init())
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
Uint32 cnt = 100;
|
seed = time(0);
|
||||||
Uint32 loop = 300000;
|
Uint32 sz = 0;
|
||||||
|
Uint32 cnt = 256;
|
||||||
|
|
||||||
|
printf("pool ; rs ; ws");
|
||||||
|
for (Uint32 i = 0; test_names[i] && i<31; i++)
|
||||||
|
if (tests & (1 << i))
|
||||||
|
printf(" ; %s", test_names[i]);
|
||||||
|
ndbout_c("");
|
||||||
|
|
||||||
while(cnt <= 1000000)
|
while(cnt <= 1000000)
|
||||||
{
|
{
|
||||||
test_rp<Rec32>(cnt, loop, 8192);
|
Uint32 loop = 768 * loops / cnt;
|
||||||
test_rp<Rec32>(cnt, loop, 32768);
|
if (sizes & (1 << sz))
|
||||||
test_ap<Rec32>(cnt, loop);
|
{
|
||||||
|
if (records & 1)
|
||||||
test_rp<Rec36>(cnt, loop, 8192);
|
{
|
||||||
test_rp<Rec36>(cnt, loop, 32768);
|
if (pools & T_TEST_AP)
|
||||||
test_ap<Rec36>(cnt, loop);
|
test_ap<Rec32>(cnt, loop);
|
||||||
|
if (pools & T_TEST_WO)
|
||||||
|
test_wo<Rec32>(cnt, loop);
|
||||||
|
if (pools & T_TEST_RW)
|
||||||
|
test_rw<Rec32>(cnt, loop);
|
||||||
|
}
|
||||||
|
if (records & 2)
|
||||||
|
{
|
||||||
|
if (pools & T_TEST_AP)
|
||||||
|
test_ap<Rec36>(cnt, loop);
|
||||||
|
if (pools & T_TEST_WO)
|
||||||
|
test_wo<Rec36>(cnt, loop);
|
||||||
|
if (pools & T_TEST_RW)
|
||||||
|
test_rw<Rec36>(cnt, loop);
|
||||||
|
}
|
||||||
|
if (records & 4)
|
||||||
|
{
|
||||||
|
if (pools & T_TEST_AP)
|
||||||
|
test_ap<Rec56>(cnt, loop);
|
||||||
|
if (pools & T_TEST_WO)
|
||||||
|
test_wo<Rec56>(cnt, loop);
|
||||||
|
if (pools & T_TEST_RW)
|
||||||
|
test_rw<Rec56>(cnt, loop);
|
||||||
|
}
|
||||||
|
if (records & 8)
|
||||||
|
{
|
||||||
|
if (pools & T_TEST_AP)
|
||||||
|
test_ap<Rec224>(cnt, loop);
|
||||||
|
if (pools & T_TEST_WO)
|
||||||
|
test_wo<Rec224>(cnt, loop);
|
||||||
|
if (pools & T_TEST_RW)
|
||||||
|
test_rw<Rec224>(cnt, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test_rp<Rec256>(cnt, loop, 8192);
|
cnt += (512 << sz);
|
||||||
test_rp<Rec256>(cnt, loop, 32768);
|
sz++;
|
||||||
test_ap<Rec256>(cnt, loop);
|
|
||||||
|
|
||||||
test_rp<Rec260>(cnt, loop, 8192);
|
|
||||||
test_rp<Rec260>(cnt, loop, 32768);
|
|
||||||
test_ap<Rec260>(cnt, loop);
|
|
||||||
|
|
||||||
cnt *= 100;
|
|
||||||
loop /= 100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Uint32 g_currentStartPhase;
|
||||||
ErrorReporter::handleAssert(const char * msg, const char * file,
|
|
||||||
int line, int)
|
void childExit(int code, Uint32 currentStartPhase)
|
||||||
{
|
{
|
||||||
ndbout << "ErrorReporter::handleAssert activated - "
|
|
||||||
<< " line= " << line << endl;
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void childAbort(int code, Uint32 currentStartPhase)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void childReportError(int error)
|
||||||
|
{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpgradeStartup::sendCmAppChg(Ndbcntr& cntr, Signal* signal, Uint32 startLevel){
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpgradeStartup::execCM_APPCHG(SimulatedBlock & block, Signal* signal){
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpgradeStartup::sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n){
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UpgradeStartup::execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal){
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <SimBlockList.hpp>
|
||||||
|
|
||||||
|
void
|
||||||
|
SimBlockList::unload()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INSTANCE(X) \
|
||||||
|
template void test_ap<X>(unsigned, unsigned);\
|
||||||
|
template void test_wo<X>(unsigned, unsigned);\
|
||||||
|
template void test_rw<X>(unsigned, unsigned);\
|
||||||
|
template void test_pool<X, ArrayPool<X> >(ArrayPool<X>&, unsigned, unsigned);\
|
||||||
|
template void test_pool<X, RecordPool<X, RWPool> >(RecordPool<X, RWPool>&, unsigned, unsigned); \
|
||||||
|
template void test_pool<X, RecordPool<X, WOPool> >(RecordPool<X, WOPool>&, unsigned, unsigned);\
|
||||||
|
template void init<X>(ArrayPool<X>&, unsigned);\
|
||||||
|
template void init<X>(RecordPool<X, RWPool>&, unsigned);\
|
||||||
|
template void init<X>(RecordPool<X, WOPool>&, unsigned)
|
||||||
|
|
||||||
|
INSTANCE(Rec32);
|
||||||
|
INSTANCE(Rec36);
|
||||||
|
INSTANCE(Rec56);
|
||||||
|
INSTANCE(Rec224);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,112 @@
|
||||||
|
|
||||||
#include "ndbd_malloc_impl.hpp"
|
#include "ndbd_malloc_impl.hpp"
|
||||||
#include <ndb_global.h>
|
#include <ndb_global.h>
|
||||||
|
#include <EventLogger.hpp>
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
|
#else
|
||||||
|
extern EventLogger g_eventLogger;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NDBD_MALLOC_METHOD
|
||||||
|
#if NDBD_MALLOC_METHOD == sbrk
|
||||||
|
static const char * f_method = "sbrk";
|
||||||
|
#else
|
||||||
|
static const char * f_method = "malloc";
|
||||||
|
#endif
|
||||||
|
#elif SIZEOF_CHARP == 8
|
||||||
|
static const char * f_method = "sbrk";
|
||||||
|
#else
|
||||||
|
static const char * f_method = "malloc";
|
||||||
|
#endif
|
||||||
|
#define MAX_CHUNKS 10
|
||||||
|
|
||||||
|
struct InitChunk
|
||||||
|
{
|
||||||
|
Uint32 m_cnt;
|
||||||
|
Uint32 m_start;
|
||||||
|
Alloc_page* m_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <NdbOut.hpp>
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
do_malloc(Uint32 pages, InitChunk* chunk)
|
||||||
|
{
|
||||||
|
pages += 1;
|
||||||
|
void * ptr = 0;
|
||||||
|
Uint32 sz = pages;
|
||||||
|
if (strcmp(f_method, "sbrk") == 0)
|
||||||
|
{
|
||||||
|
ptr = 0;
|
||||||
|
while (ptr == 0)
|
||||||
|
{
|
||||||
|
ptr = sbrk(sizeof(Alloc_page) * sz);
|
||||||
|
if (ptr == (void*)-1)
|
||||||
|
{
|
||||||
|
ptr = 0;
|
||||||
|
sz = 1 + (9 * sz) / 10;
|
||||||
|
if (pages >= 32 && sz < 32)
|
||||||
|
{
|
||||||
|
sz = pages;
|
||||||
|
f_method = "malloc";
|
||||||
|
g_eventLogger.info("sbrk(%lld) failed, trying malloc",
|
||||||
|
(Uint64)(sizeof(Alloc_page) * sz));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(f_method, "malloc") == 0)
|
||||||
|
{
|
||||||
|
ptr = 0;
|
||||||
|
while (ptr == 0)
|
||||||
|
{
|
||||||
|
ptr = malloc(sizeof(Alloc_page) * sz);
|
||||||
|
if (ptr == 0)
|
||||||
|
{
|
||||||
|
sz = 1 + (9 * sz) / 10;
|
||||||
|
if (pages >= 32 && sz < 32)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk->m_cnt = sz;
|
||||||
|
chunk->m_ptr = (Alloc_page*)ptr;
|
||||||
|
const UintPtr align = sizeof(Alloc_page) - 1;
|
||||||
|
if (UintPtr(ptr) & align)
|
||||||
|
{
|
||||||
|
chunk->m_cnt--;
|
||||||
|
chunk->m_ptr = (Alloc_page*)((UintPtr(ptr) + align) & ~align);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
ndbout_c("do_malloc(%d) -> %p %d", pages, ptr, chunk->m_cnt);
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
Uint32 sum = 0;
|
||||||
|
Alloc_page* page = chunk->m_ptr;
|
||||||
|
for (Uint32 i = 0; i<chunk->m_cnt; i++, page++)
|
||||||
|
{
|
||||||
|
page->m_data[0*1024] = 0;
|
||||||
|
page->m_data[1*1024] = 0;
|
||||||
|
page->m_data[2*1024] = 0;
|
||||||
|
page->m_data[3*1024] = 0;
|
||||||
|
page->m_data[4*1024] = 0;
|
||||||
|
page->m_data[5*1024] = 0;
|
||||||
|
page->m_data[6*1024] = 0;
|
||||||
|
page->m_data[7*1024] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Uint32
|
Uint32
|
||||||
Ndbd_mem_manager::log2(Uint32 input)
|
Ndbd_mem_manager::log2(Uint32 input)
|
||||||
|
@ -33,67 +139,224 @@ Ndbd_mem_manager::log2(Uint32 input)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ndbd_mem_manager::Ndbd_mem_manager(Uint32 default_grow)
|
Ndbd_mem_manager::Ndbd_mem_manager()
|
||||||
{
|
{
|
||||||
m_grow_size = default_grow;
|
|
||||||
bzero(m_buddy_lists, sizeof(m_buddy_lists));
|
|
||||||
m_base = 0;
|
|
||||||
m_base_page = 0;
|
m_base_page = 0;
|
||||||
|
bzero(m_buddy_lists, sizeof(m_buddy_lists));
|
||||||
m_pages_alloc = 0;
|
bzero(m_resource_limit, sizeof(m_resource_limit));
|
||||||
m_pages_used = 0;
|
|
||||||
|
|
||||||
if (sizeof(Free_page_data) != (4 * (1 << FPD_2LOG)))
|
if (sizeof(Free_page_data) != (4 * (1 << FPD_2LOG)))
|
||||||
{
|
{
|
||||||
|
g_eventLogger.error("Invalid build, ndbd_malloc_impl.cpp:%d", __LINE__);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
Ndbd_mem_manager::init(Uint32 pages)
|
Ndbd_mem_manager::set_resource_limit(const Resource_limit& rl)
|
||||||
{
|
{
|
||||||
assert(m_base == 0);
|
Uint32 id = rl.m_resource_id;
|
||||||
assert(m_base_page == 0);
|
assert(id < XX_RL_COUNT);
|
||||||
assert(m_pages_alloc == 0);
|
|
||||||
pages = pages ? pages : m_grow_size;
|
|
||||||
|
|
||||||
m_base = malloc((2 + pages) * sizeof(Alloc_page));
|
Uint32 reserve = id ? rl.m_min : 0;
|
||||||
UintPtr ptr = (UintPtr)m_base;
|
Uint32 current_reserved = m_resource_limit[0].m_min;
|
||||||
UintPtr rem = ptr % sizeof(Alloc_page);
|
|
||||||
if (rem)
|
m_resource_limit[id] = rl;
|
||||||
|
m_resource_limit[id].m_curr = 0;
|
||||||
|
m_resource_limit[0].m_min = current_reserved + reserve;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Ndbd_mem_manager::get_resource_limit(Uint32 id, Resource_limit& rl) const
|
||||||
|
{
|
||||||
|
if (id < XX_RL_COUNT)
|
||||||
{
|
{
|
||||||
ptr += sizeof(Alloc_page) - rem;
|
rl = m_resource_limit[id];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Ndbd_mem_manager::init(bool alloc_less_memory)
|
||||||
|
{
|
||||||
|
assert(m_base_page == 0);
|
||||||
|
|
||||||
|
Uint32 pages = 0;
|
||||||
|
Uint32 max_page = 0;
|
||||||
|
Uint32 reserved = m_resource_limit[0].m_min;
|
||||||
|
if (m_resource_limit[0].m_max)
|
||||||
|
{
|
||||||
|
pages = m_resource_limit[0].m_max;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pages++;
|
pages = m_resource_limit[0].m_min; // reserved
|
||||||
}
|
}
|
||||||
m_base_page = (Alloc_page*)ptr;
|
|
||||||
m_pages_alloc += pages;
|
if (m_resource_limit[0].m_min == 0)
|
||||||
m_pages_used += pages;
|
|
||||||
|
|
||||||
Uint32 bmp = (pages + (1 << BPP_2LOG) - 1) >> BPP_2LOG;
|
|
||||||
for(Uint32 i = 0; i < bmp; i++)
|
|
||||||
{
|
{
|
||||||
Uint32 start = i * (1 << BPP_2LOG);
|
m_resource_limit[0].m_min = pages;
|
||||||
Uint32 end = start + (1 << BPP_2LOG);
|
}
|
||||||
end = end > m_pages_alloc ? m_pages_alloc : end - 1;
|
|
||||||
Alloc_page *ptr = m_base_page + start;
|
g_eventLogger.info("Ndbd_mem_manager::init(%d) min: %dMb initial: %dMb",
|
||||||
BitmaskImpl::clear(BITMAP_WORDS, ptr->m_data);
|
alloc_less_memory,
|
||||||
|
(sizeof(Alloc_page)*m_resource_limit[0].m_min)>>20,
|
||||||
release(start+1, end - 1 - start);
|
(sizeof(Alloc_page)*pages)>>20);
|
||||||
|
|
||||||
|
if (pages == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do malloc
|
||||||
|
*/
|
||||||
|
|
||||||
|
Uint32 cnt = 0;
|
||||||
|
struct InitChunk chunks[MAX_CHUNKS];
|
||||||
|
bzero(chunks, sizeof(chunks));
|
||||||
|
|
||||||
|
Uint32 allocated = 0;
|
||||||
|
while (cnt < MAX_CHUNKS && allocated < pages)
|
||||||
|
{
|
||||||
|
InitChunk chunk;
|
||||||
|
Uint32 remaining = pages - allocated;
|
||||||
|
|
||||||
|
if (do_malloc(pages - allocated, &chunk))
|
||||||
|
{
|
||||||
|
Uint32 i = 0;
|
||||||
|
for(; i<cnt ; i++)
|
||||||
|
{
|
||||||
|
if (chunk.m_ptr < chunks[i].m_ptr)
|
||||||
|
{
|
||||||
|
for (Uint32 j = cnt; j > i; j--)
|
||||||
|
chunks[j] = chunks[j-1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
chunks[i] = chunk;
|
||||||
|
allocated += chunk.m_cnt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocated < m_resource_limit[0].m_min)
|
||||||
|
{
|
||||||
|
g_eventLogger.
|
||||||
|
error("Unable to alloc min memory from OS: min: %lldMb "
|
||||||
|
" allocated: %lldMb",
|
||||||
|
(Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_min) >> 20,
|
||||||
|
(Uint64)(sizeof(Alloc_page)*allocated) >> 20);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (allocated < pages)
|
||||||
|
{
|
||||||
|
g_eventLogger.
|
||||||
|
warning("Unable to alloc requested memory from OS: min: %lldMb"
|
||||||
|
" requested: %lldMb allocated: %lldMb",
|
||||||
|
(Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_min)>>20,
|
||||||
|
(Uint64)(sizeof(Alloc_page)*m_resource_limit[0].m_max)>>20,
|
||||||
|
(Uint64)(sizeof(Alloc_page)*allocated)>>20);
|
||||||
|
if (!alloc_less_memory)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_base_page = chunks[0].m_ptr;
|
||||||
|
|
||||||
|
for (Uint32 i = 0; i<cnt; i++)
|
||||||
|
{
|
||||||
|
UintPtr start = UintPtr(chunks[i].m_ptr) - UintPtr(m_base_page);
|
||||||
|
start >>= (2 + BMW_2LOG);
|
||||||
|
UintPtr last = start + chunks[i].m_cnt;
|
||||||
|
chunks[i].m_start = start;
|
||||||
|
assert((Uint64(start) >> 32) == 0);
|
||||||
|
|
||||||
|
if (last > max_page)
|
||||||
|
max_page = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_resource_limit[0].m_resource_id = max_page;
|
||||||
|
m_resource_limit[0].m_min = reserved;
|
||||||
|
m_resource_limit[0].m_max = 0;
|
||||||
|
|
||||||
|
for (Uint32 i = 0; i<cnt; i++)
|
||||||
|
{
|
||||||
|
grow(chunks[i].m_start, chunks[i].m_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <NdbOut.hpp>
|
||||||
|
|
||||||
|
void
|
||||||
|
Ndbd_mem_manager::grow(Uint32 start, Uint32 cnt)
|
||||||
|
{
|
||||||
|
assert(cnt);
|
||||||
|
Uint32 start_bmp = start >> BPP_2LOG;
|
||||||
|
Uint32 last_bmp = (start + cnt - 1) >> BPP_2LOG;
|
||||||
|
|
||||||
|
#if SIZEOF_CHARP == 4
|
||||||
|
assert(start_bmp == 0 && last_bmp == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (start_bmp != last_bmp)
|
||||||
|
{
|
||||||
|
Uint32 tmp = ((start_bmp + 1) << BPP_2LOG) - start;
|
||||||
|
grow(start, tmp);
|
||||||
|
grow((start_bmp + 1) << BPP_2LOG, cnt - tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((start + cnt) == ((start_bmp + 1) << BPP_2LOG))
|
||||||
|
{
|
||||||
|
cnt--; // last page is always marked as empty
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_used_bitmap_pages.get(start_bmp))
|
||||||
|
{
|
||||||
|
if (start != (start_bmp << BPP_2LOG))
|
||||||
|
{
|
||||||
|
ndbout_c("ndbd_malloc_impl.cpp:%d:grow(%d, %d) %d!=%d"
|
||||||
|
" - Unable to use due to bitmap pages missaligned!!",
|
||||||
|
__LINE__, start, cnt, start, (start_bmp << BPP_2LOG));
|
||||||
|
g_eventLogger.error("ndbd_malloc_impl.cpp:%d:grow(%d, %d)"
|
||||||
|
" - Unable to use due to bitmap pages missaligned!!",
|
||||||
|
__LINE__, start, cnt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNIT_TEST
|
||||||
|
ndbout_c("creating bitmap page %d", start_bmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Alloc_page* bmp = m_base_page + start;
|
||||||
|
memset(bmp, 0, sizeof(Alloc_page));
|
||||||
|
m_used_bitmap_pages.set(start_bmp);
|
||||||
|
cnt--;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt)
|
||||||
|
{
|
||||||
|
m_resource_limit[0].m_curr += cnt;
|
||||||
|
m_resource_limit[0].m_max += cnt;
|
||||||
|
release(start, cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Ndbd_mem_manager::release(Uint32 start, Uint32 cnt)
|
Ndbd_mem_manager::release(Uint32 start, Uint32 cnt)
|
||||||
{
|
{
|
||||||
assert(m_pages_used >= cnt);
|
assert(m_resource_limit[0].m_curr >= cnt);
|
||||||
assert(start);
|
assert(start);
|
||||||
m_pages_used -= cnt;
|
m_resource_limit[0].m_curr -= cnt;
|
||||||
|
|
||||||
set(start, start+cnt-1);
|
set(start, start+cnt-1);
|
||||||
|
|
||||||
release_impl(start, cnt);
|
release_impl(start, cnt);
|
||||||
|
@ -131,7 +394,8 @@ Ndbd_mem_manager::release_impl(Uint32 start, Uint32 cnt)
|
||||||
void
|
void
|
||||||
Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
|
Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
|
||||||
{
|
{
|
||||||
Uint32 start, i;
|
Int32 i;
|
||||||
|
Uint32 start;
|
||||||
Uint32 cnt = * pages;
|
Uint32 cnt = * pages;
|
||||||
Uint32 list = log2(cnt - 1);
|
Uint32 list = log2(cnt - 1);
|
||||||
|
|
||||||
|
@ -160,8 +424,8 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
|
||||||
clear(start, start+cnt-1);
|
clear(start, start+cnt-1);
|
||||||
}
|
}
|
||||||
* ret = start;
|
* ret = start;
|
||||||
m_pages_used += cnt;
|
m_resource_limit[0].m_curr += cnt;
|
||||||
assert(m_pages_used <= m_pages_alloc);
|
assert(m_resource_limit[0].m_curr <= m_resource_limit[0].m_max);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,8 +435,8 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
|
||||||
* search in other lists...
|
* search in other lists...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Uint32 min_list = log2(min - 1);
|
Int32 min_list = log2(min - 1);
|
||||||
assert(list >= min_list);
|
assert((Int32)list >= min_list);
|
||||||
for (i = list - 1; i >= min_list; i--)
|
for (i = list - 1; i >= min_list; i--)
|
||||||
{
|
{
|
||||||
if ((start = m_buddy_lists[i]))
|
if ((start = m_buddy_lists[i]))
|
||||||
|
@ -192,33 +456,14 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
|
||||||
|
|
||||||
* ret = start;
|
* ret = start;
|
||||||
* pages = sz;
|
* pages = sz;
|
||||||
m_pages_used += sz;
|
m_resource_limit[0].m_curr += sz;
|
||||||
assert(m_pages_used <= m_pages_alloc);
|
assert(m_resource_limit[0].m_curr <= m_resource_limit[0].m_max);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
* pages = 0;
|
* pages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
|
||||||
Ndbd_mem_manager::alloc(Uint32 *pages, Uint32 min)
|
|
||||||
{
|
|
||||||
Uint32 ret;
|
|
||||||
alloc(&ret, pages, min);
|
|
||||||
if (pages)
|
|
||||||
{
|
|
||||||
return m_base_page + ret;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Ndbd_mem_manager::release(void* ptr, Uint32 cnt)
|
|
||||||
{
|
|
||||||
Uint32 page = ((Alloc_page*)ptr) - m_base_page;
|
|
||||||
release(page, cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Ndbd_mem_manager::insert_free_list(Uint32 start, Uint32 size)
|
Ndbd_mem_manager::insert_free_list(Uint32 start, Uint32 size)
|
||||||
{
|
{
|
||||||
|
@ -284,25 +529,6 @@ Ndbd_mem_manager::remove_free_list(Uint32 start, Uint32 list)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32
|
|
||||||
Ndbd_mem_manager::get_no_allocated_pages() const
|
|
||||||
{
|
|
||||||
return m_pages_alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint32
|
|
||||||
Ndbd_mem_manager::get_no_used_pages() const
|
|
||||||
{
|
|
||||||
return m_pages_used;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint32
|
|
||||||
Ndbd_mem_manager::get_no_free_pages() const
|
|
||||||
{
|
|
||||||
return m_pages_alloc - m_pages_used;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Ndbd_mem_manager::dump() const
|
Ndbd_mem_manager::dump() const
|
||||||
{
|
{
|
||||||
|
@ -321,32 +547,139 @@ Ndbd_mem_manager::dump() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
Ndbd_mem_manager::alloc_page(Uint32 type, Uint32* i)
|
||||||
|
{
|
||||||
|
Uint32 idx = type & RG_MASK;
|
||||||
|
assert(idx && idx < XX_RL_COUNT);
|
||||||
|
Resource_limit tot = m_resource_limit[0];
|
||||||
|
Resource_limit rl = m_resource_limit[idx];
|
||||||
|
|
||||||
|
Uint32 add = (rl.m_curr < rl.m_min) ? 0 : 1; // Over min ?
|
||||||
|
Uint32 limit = (rl.m_max == 0 || rl.m_curr < rl.m_max) ? 0 : 1; // Over limit
|
||||||
|
Uint32 free = (tot.m_min + tot.m_curr < tot.m_max) ? 1 : 0; // Has free
|
||||||
|
|
||||||
|
if (likely(add == 0 || (limit == 0 && free == 1)))
|
||||||
|
{
|
||||||
|
Uint32 cnt = 1;
|
||||||
|
alloc(i, &cnt, 1);
|
||||||
|
assert(cnt);
|
||||||
|
m_resource_limit[0].m_curr = tot.m_curr + add;
|
||||||
|
m_resource_limit[idx].m_curr = rl.m_curr + 1;
|
||||||
|
return m_base_page + *i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Ndbd_mem_manager::release_page(Uint32 type, Uint32 i)
|
||||||
|
{
|
||||||
|
Uint32 idx = type & RG_MASK;
|
||||||
|
assert(idx && idx < XX_RL_COUNT);
|
||||||
|
Resource_limit tot = m_resource_limit[0];
|
||||||
|
Resource_limit rl = m_resource_limit[idx];
|
||||||
|
|
||||||
|
Uint32 sub = (rl.m_curr < rl.m_min) ? 0 : 1; // Over min ?
|
||||||
|
release(i, 1);
|
||||||
|
m_resource_limit[0].m_curr = tot.m_curr - sub;
|
||||||
|
m_resource_limit[idx].m_curr = rl.m_curr - 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UNIT_TEST
|
#ifdef UNIT_TEST
|
||||||
|
|
||||||
#include <Vector.hpp>
|
#include <Vector.hpp>
|
||||||
|
#include <NdbTick.h>
|
||||||
|
|
||||||
struct Chunk {
|
struct Chunk {
|
||||||
Uint32 pageId;
|
Uint32 pageId;
|
||||||
Uint32 pageCount;
|
Uint32 pageCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
struct Timer
|
||||||
main(void)
|
|
||||||
{
|
{
|
||||||
printf("Startar modul test av Page Manager\n");
|
Uint64 sum;
|
||||||
|
Uint32 cnt;
|
||||||
|
|
||||||
|
Timer() { sum = cnt = 0;}
|
||||||
|
|
||||||
|
struct timeval st;
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
gettimeofday(&st, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64 calc_diff() {
|
||||||
|
struct timeval st2;
|
||||||
|
gettimeofday(&st2, 0);
|
||||||
|
Uint64 diff = st2.tv_sec;
|
||||||
|
diff -= st.tv_sec;
|
||||||
|
diff *= 1000000;
|
||||||
|
diff += st2.tv_usec;
|
||||||
|
diff -= st.tv_usec;
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
add(calc_diff());
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(Uint64 diff) { sum += diff; cnt++;}
|
||||||
|
|
||||||
|
void print(const char * title) const {
|
||||||
|
float ps = sum;
|
||||||
|
ps /= cnt;
|
||||||
|
printf("%s %fus/call %lld %d\n", title, ps, sum, cnt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
int sz = 1*32768;
|
||||||
|
int run_time = 30;
|
||||||
|
if (argc > 1)
|
||||||
|
sz = 32*atoi(argv[1]);
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
run_time = atoi(argv[2]);
|
||||||
|
|
||||||
|
char buf[255];
|
||||||
|
Timer timer[4];
|
||||||
|
printf("Startar modul test av Page Manager %dMb %ds\n",
|
||||||
|
(sz >> 5), run_time);
|
||||||
|
g_eventLogger.createConsoleHandler();
|
||||||
|
g_eventLogger.setCategory("keso");
|
||||||
|
g_eventLogger.enable(Logger::LL_ON, Logger::LL_INFO);
|
||||||
|
g_eventLogger.enable(Logger::LL_ON, Logger::LL_CRITICAL);
|
||||||
|
g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);
|
||||||
|
g_eventLogger.enable(Logger::LL_ON, Logger::LL_WARNING);
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
Ndbd_mem_manager mem;
|
Ndbd_mem_manager mem;
|
||||||
mem.init(32000);
|
Resource_limit rl;
|
||||||
|
rl.m_min = 0;
|
||||||
|
rl.m_max = sz;
|
||||||
|
rl.m_curr = 0;
|
||||||
|
rl.m_resource_id = 0;
|
||||||
|
mem.set_resource_limit(rl);
|
||||||
|
rl.m_min = sz < 16384 ? sz : 16384;
|
||||||
|
rl.m_max = 0;
|
||||||
|
rl.m_resource_id = 1;
|
||||||
|
mem.set_resource_limit(rl);
|
||||||
|
|
||||||
|
mem.init();
|
||||||
|
mem.dump();
|
||||||
|
printf("pid: %d press enter to continue\n", getpid());
|
||||||
|
fgets(buf, sizeof(buf), stdin);
|
||||||
Vector<Chunk> chunks;
|
Vector<Chunk> chunks;
|
||||||
const Uint32 LOOPS = 100000;
|
time_t stop = time(0) + run_time;
|
||||||
for(Uint32 i = 0; i<LOOPS; i++){
|
for(Uint32 i = 0; time(0) < stop; i++){
|
||||||
//mem.dump();
|
//mem.dump();
|
||||||
|
|
||||||
// Case
|
// Case
|
||||||
Uint32 c = (rand() % 100);
|
Uint32 c = (rand() % 100);
|
||||||
const Uint32 free = mem.get_no_allocated_pages() - mem.get_no_used_pages();
|
if (c < 50)
|
||||||
if (c < 60)
|
|
||||||
{
|
{
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
|
@ -359,17 +692,8 @@ main(void)
|
||||||
c = 2;
|
c = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32 alloc = 0;
|
Uint32 alloc = 1 + rand() % 3200;
|
||||||
if(free <= 1)
|
|
||||||
{
|
|
||||||
c = 0;
|
|
||||||
alloc = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alloc = 1 + (rand() % (free - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(chunks.size() == 0 && c == 0)
|
if(chunks.size() == 0 && c == 0)
|
||||||
{
|
{
|
||||||
c = 1 + rand() % 2;
|
c = 1 + rand() % 2;
|
||||||
|
@ -382,38 +706,52 @@ main(void)
|
||||||
const int ch = rand() % chunks.size();
|
const int ch = rand() % chunks.size();
|
||||||
Chunk chunk = chunks[ch];
|
Chunk chunk = chunks[ch];
|
||||||
chunks.erase(ch);
|
chunks.erase(ch);
|
||||||
|
timer[0].start();
|
||||||
|
Uint64 start = NdbTick_CurrentMillisecond();
|
||||||
mem.release(chunk.pageId, chunk.pageCount);
|
mem.release(chunk.pageId, chunk.pageCount);
|
||||||
|
timer[0].stop();
|
||||||
if(DEBUG)
|
if(DEBUG)
|
||||||
printf(" release %d %d\n", chunk.pageId, chunk.pageCount);
|
printf(" release %d %d\n", chunk.pageId, chunk.pageCount);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: { // Seize(n) - fail
|
case 2: { // Seize(n) - fail
|
||||||
alloc += free;
|
alloc += sz;
|
||||||
// Fall through
|
// Fall through
|
||||||
}
|
}
|
||||||
case 1: { // Seize(n) (success)
|
case 1: { // Seize(n) (success)
|
||||||
Chunk chunk;
|
Chunk chunk;
|
||||||
chunk.pageCount = alloc;
|
chunk.pageCount = alloc;
|
||||||
mem.alloc(&chunk.pageId, &chunk.pageCount, 1);
|
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
printf(" alloc %d -> %d %d", alloc, chunk.pageId, chunk.pageCount);
|
{
|
||||||
|
printf(" alloc %d -> ", alloc); fflush(stdout);
|
||||||
|
}
|
||||||
|
timer[0].start();
|
||||||
|
mem.alloc(&chunk.pageId, &chunk.pageCount, 1);
|
||||||
|
Uint64 diff = timer[0].calc_diff();
|
||||||
|
|
||||||
|
if (DEBUG)
|
||||||
|
printf("%d %d", chunk.pageId, chunk.pageCount);
|
||||||
assert(chunk.pageCount <= alloc);
|
assert(chunk.pageCount <= alloc);
|
||||||
if(chunk.pageCount != 0){
|
if(chunk.pageCount != 0){
|
||||||
chunks.push_back(chunk);
|
chunks.push_back(chunk);
|
||||||
if(chunk.pageCount != alloc) {
|
if(chunk.pageCount != alloc) {
|
||||||
|
timer[2].add(diff);
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
printf(" - Tried to allocate %d - only allocated %d - free: %d",
|
printf(" - Tried to allocate %d - only allocated %d - free: %d",
|
||||||
alloc, chunk.pageCount, free);
|
alloc, chunk.pageCount, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer[1].add(diff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
timer[3].add(diff);
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
printf(" Failed to alloc %d pages with %d pages free",
|
printf(" Failed to alloc %d pages with %d pages free",
|
||||||
alloc, free);
|
alloc, 0);
|
||||||
}
|
}
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
if(alloc == 1 && free > 0)
|
|
||||||
assert(chunk.pageCount == alloc);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -424,6 +762,17 @@ main(void)
|
||||||
mem.release(chunk.pageId, chunk.pageCount);
|
mem.release(chunk.pageId, chunk.pageCount);
|
||||||
chunks.erase(chunks.size() - 1);
|
chunks.erase(chunks.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *title[] = {
|
||||||
|
"release ",
|
||||||
|
"alloc full",
|
||||||
|
"alloc part",
|
||||||
|
"alloc fail"
|
||||||
|
};
|
||||||
|
for(Uint32 i = 0; i<4; i++)
|
||||||
|
timer[i].print(title[i]);
|
||||||
|
|
||||||
|
mem.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
template class Vector<Chunk>;
|
template class Vector<Chunk>;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <kernel_types.h>
|
#include <kernel_types.h>
|
||||||
#include <Bitmask.hpp>
|
#include <Bitmask.hpp>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "Pool.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 13 -> 8192 words -> 32768 bytes
|
* 13 -> 8192 words -> 32768 bytes
|
||||||
|
@ -51,25 +52,25 @@ struct Free_page_data
|
||||||
class Ndbd_mem_manager
|
class Ndbd_mem_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ndbd_mem_manager(Uint32 default_grow = 32);
|
Ndbd_mem_manager();
|
||||||
|
|
||||||
|
void set_resource_limit(const Resource_limit& rl);
|
||||||
|
bool get_resource_limit(Uint32 id, Resource_limit& rl) const;
|
||||||
|
|
||||||
|
bool init(bool allow_alloc_less_than_requested = true);
|
||||||
|
void* get_memroot() const { return (void*)m_base_page;}
|
||||||
|
|
||||||
void alloc(Uint32* ret, Uint32 *pages, Uint32 min_requested);
|
void alloc(Uint32* ret, Uint32 *pages, Uint32 min_requested);
|
||||||
void release(Uint32 start, Uint32 cnt);
|
void release(Uint32 start, Uint32 cnt);
|
||||||
|
|
||||||
Uint32 get_no_allocated_pages() const;
|
|
||||||
Uint32 get_no_used_pages() const;
|
|
||||||
Uint32 get_no_free_pages() const;
|
|
||||||
|
|
||||||
bool init(Uint32 pages = 0);
|
|
||||||
bool grow(Uint32 pages = 0);
|
|
||||||
|
|
||||||
void dump() const ;
|
void dump() const ;
|
||||||
|
|
||||||
void* get_memroot() const { return (void*)m_base_page;}
|
void* alloc_page(Uint32 type, Uint32* i);
|
||||||
|
void release_page(Uint32 type, Uint32 i);
|
||||||
void* alloc(Uint32 * pages, Uint32 min_requested);
|
|
||||||
void release(void* ptr, Uint32 cnt);
|
void* alloc_pages(Uint32 type, Uint32* i, Uint32 *cnt, Uint32 min = 1);
|
||||||
|
void release_pages(Uint32 type, Uint32 i, void*p, Uint32 cnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute 2log of size
|
* Compute 2log of size
|
||||||
* @note size = 0 -> 0
|
* @note size = 0 -> 0
|
||||||
|
@ -78,18 +79,17 @@ public:
|
||||||
static Uint32 log2(Uint32 size);
|
static Uint32 log2(Uint32 size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void grow(Uint32 start, Uint32 cnt);
|
||||||
|
|
||||||
|
#define XX_RL_COUNT 3
|
||||||
/**
|
/**
|
||||||
* Return pointer to free page data on page
|
* Return pointer to free page data on page
|
||||||
*/
|
*/
|
||||||
static Free_page_data* get_free_page_data(Alloc_page*, Uint32 idx);
|
static Free_page_data* get_free_page_data(Alloc_page*, Uint32 idx);
|
||||||
|
Bitmask<1> m_used_bitmap_pages;
|
||||||
|
|
||||||
Uint32 m_pages_alloc;
|
|
||||||
Uint32 m_pages_used;
|
|
||||||
|
|
||||||
Uint32 m_grow_size;
|
|
||||||
Uint32 m_buddy_lists[16];
|
Uint32 m_buddy_lists[16];
|
||||||
|
Resource_limit m_resource_limit[XX_RL_COUNT]; // RG_COUNT in record_types.hpp
|
||||||
void * m_base;
|
|
||||||
Alloc_page * m_base_page;
|
Alloc_page * m_base_page;
|
||||||
|
|
||||||
void release_impl(Uint32 start, Uint32 cnt);
|
void release_impl(Uint32 start, Uint32 cnt);
|
||||||
|
@ -121,7 +121,7 @@ Ndbd_mem_manager::set(Uint32 first, Uint32 last)
|
||||||
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
||||||
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
||||||
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
||||||
assert(bmp < m_pages_alloc);
|
assert(bmp < m_resource_limit[0].m_resource_id);
|
||||||
|
|
||||||
first -= bmp;
|
first -= bmp;
|
||||||
last -= bmp;
|
last -= bmp;
|
||||||
|
@ -139,7 +139,7 @@ Ndbd_mem_manager::clear(Uint32 first, Uint32 last)
|
||||||
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
||||||
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
||||||
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
||||||
assert(bmp < m_pages_alloc);
|
assert(bmp < m_resource_limit[0].m_resource_id);
|
||||||
|
|
||||||
first -= bmp;
|
first -= bmp;
|
||||||
last -= bmp;
|
last -= bmp;
|
||||||
|
@ -157,7 +157,7 @@ Ndbd_mem_manager::clear_and_set(Uint32 first, Uint32 last)
|
||||||
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
||||||
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
||||||
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
||||||
assert(bmp < m_pages_alloc);
|
assert(bmp < m_resource_limit[0].m_resource_id);
|
||||||
|
|
||||||
first -= bmp;
|
first -= bmp;
|
||||||
last -= bmp;
|
last -= bmp;
|
||||||
|
@ -177,7 +177,7 @@ Ndbd_mem_manager::check(Uint32 first, Uint32 last)
|
||||||
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
|
||||||
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
Uint32 bmp = first & ~((1 << BPP_2LOG) - 1);
|
||||||
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
assert((first >> BPP_2LOG) == (last >> BPP_2LOG));
|
||||||
assert(bmp < m_pages_alloc);
|
assert(bmp < m_resource_limit[0].m_resource_id);
|
||||||
|
|
||||||
first -= bmp;
|
first -= bmp;
|
||||||
last -= bmp;
|
last -= bmp;
|
||||||
|
|
|
@ -771,6 +771,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
|
||||||
"64M",
|
"64M",
|
||||||
"4M",
|
"4M",
|
||||||
"1024G" },
|
"1024G" },
|
||||||
|
|
||||||
|
{
|
||||||
|
CFG_DB_SGA,
|
||||||
|
"SharedGlobalMemory",
|
||||||
|
DB_TOKEN,
|
||||||
|
"Total number bytes on each "DB_TOKEN_PRINT" node allocated for any use",
|
||||||
|
ConfigInfo::CI_USED,
|
||||||
|
false,
|
||||||
|
ConfigInfo::CI_INT64,
|
||||||
|
"20M",
|
||||||
|
"0",
|
||||||
|
"65536G" }, // 32k pages * 32-bit i value
|
||||||
|
|
||||||
{
|
{
|
||||||
CFG_DB_START_PARTIAL_TIMEOUT,
|
CFG_DB_START_PARTIAL_TIMEOUT,
|
||||||
|
|
|
@ -800,6 +800,7 @@ InitConfigFileParser::parse_mycnf()
|
||||||
/**
|
/**
|
||||||
* Add ndbd, ndb_mgmd, api/mysqld
|
* Add ndbd, ndb_mgmd, api/mysqld
|
||||||
*/
|
*/
|
||||||
|
Uint32 idx = options.size();
|
||||||
{
|
{
|
||||||
struct my_option opt;
|
struct my_option opt;
|
||||||
bzero(&opt, sizeof(opt));
|
bzero(&opt, sizeof(opt));
|
||||||
|
@ -809,7 +810,6 @@ InitConfigFileParser::parse_mycnf()
|
||||||
opt.var_type = GET_STR;
|
opt.var_type = GET_STR;
|
||||||
opt.arg_type = REQUIRED_ARG;
|
opt.arg_type = REQUIRED_ARG;
|
||||||
options.push_back(opt);
|
options.push_back(opt);
|
||||||
ndbd = &options.back();
|
|
||||||
|
|
||||||
opt.name = "ndb_mgmd";
|
opt.name = "ndb_mgmd";
|
||||||
opt.id = 256;
|
opt.id = 256;
|
||||||
|
@ -817,7 +817,6 @@ InitConfigFileParser::parse_mycnf()
|
||||||
opt.var_type = GET_STR;
|
opt.var_type = GET_STR;
|
||||||
opt.arg_type = REQUIRED_ARG;
|
opt.arg_type = REQUIRED_ARG;
|
||||||
options.push_back(opt);
|
options.push_back(opt);
|
||||||
ndb_mgmd = &options.back();
|
|
||||||
|
|
||||||
opt.name = "mysqld";
|
opt.name = "mysqld";
|
||||||
opt.id = 256;
|
opt.id = 256;
|
||||||
|
@ -825,7 +824,6 @@ InitConfigFileParser::parse_mycnf()
|
||||||
opt.var_type = GET_STR;
|
opt.var_type = GET_STR;
|
||||||
opt.arg_type = REQUIRED_ARG;
|
opt.arg_type = REQUIRED_ARG;
|
||||||
options.push_back(opt);
|
options.push_back(opt);
|
||||||
mysqld = &options.back();
|
|
||||||
|
|
||||||
opt.name = "api";
|
opt.name = "api";
|
||||||
opt.id = 256;
|
opt.id = 256;
|
||||||
|
@ -833,10 +831,14 @@ InitConfigFileParser::parse_mycnf()
|
||||||
opt.var_type = GET_STR;
|
opt.var_type = GET_STR;
|
||||||
opt.arg_type = REQUIRED_ARG;
|
opt.arg_type = REQUIRED_ARG;
|
||||||
options.push_back(opt);
|
options.push_back(opt);
|
||||||
api = &options.back();
|
|
||||||
|
|
||||||
bzero(&opt, sizeof(opt));
|
bzero(&opt, sizeof(opt));
|
||||||
options.push_back(opt);
|
options.push_back(opt);
|
||||||
|
|
||||||
|
ndbd = &options[idx];
|
||||||
|
ndb_mgmd = &options[idx+1];
|
||||||
|
mysqld = &options[idx+2];
|
||||||
|
api = &options[idx+3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue