Commit 55e78a48 authored by joreland@mysql.com's avatar joreland@mysql.com

Added file(s)

parent 7037c866
#ifndef DB_CONFIG_PARAMTERS_H
#define DB_CONFIG_PARAMTERS_H
#define PRIVATE_BASE 14000
#define CFG_ACC_DIR_RANGE (PRIVATE_BASE + 1)
#define CFG_ACC_DIR_ARRAY (PRIVATE_BASE + 2)
#define CFG_ACC_FRAGMENT (PRIVATE_BASE + 3)
#define CFG_ACC_OP_RECS (PRIVATE_BASE + 4)
#define CFG_ACC_OVERFLOW_RECS (PRIVATE_BASE + 5)
#define CFG_ACC_PAGE8 (PRIVATE_BASE + 6)
#define CFG_ACC_ROOT_FRAG (PRIVATE_BASE + 7)
#define CFG_ACC_TABLE (PRIVATE_BASE + 8)
#define CFG_ACC_SCAN (PRIVATE_BASE + 9)
#define CFG_DICT_ATTRIBUTE (PRIVATE_BASE + 10)
#define CFG_DICT_CONNECT (PRIVATE_BASE + 11)
#define CFG_DICT_FRAG_CONNECT (PRIVATE_BASE + 12)
#define CFG_DICT_TABLE (PRIVATE_BASE + 13)
#define CFG_DICT_TC_CONNECT (PRIVATE_BASE + 14)
#define CFG_DIH_API_CONNECT (PRIVATE_BASE + 15)
#define CFG_DIH_CONNECT (PRIVATE_BASE + 16)
#define CFG_DIH_FRAG_CONNECT (PRIVATE_BASE + 17)
#define CFG_DIH_MORE_NODES (PRIVATE_BASE + 18)
#define CFG_DIH_REPLICAS (PRIVATE_BASE + 19)
#define CFG_DIH_TABLE (PRIVATE_BASE + 20)
#define CFG_LQH_FRAG (PRIVATE_BASE + 21)
#define CFG_LQH_CONNECT (PRIVATE_BASE + 22)
#define CFG_LQH_TABLE (PRIVATE_BASE + 23)
#define CFG_LQH_TC_CONNECT (PRIVATE_BASE + 24)
#define CFG_LQH_REPLICAS (PRIVATE_BASE + 25)
#define CFG_LQH_LOG_FILES (PRIVATE_BASE + 26)
#define CFG_LQH_SCAN (PRIVATE_BASE + 27)
#define CFG_TC_API_CONNECT (PRIVATE_BASE + 28)
#define CFG_TC_TC_CONNECT (PRIVATE_BASE + 29)
#define CFG_TC_TABLE (PRIVATE_BASE + 30)
#define CFG_TC_SCAN (PRIVATE_BASE + 31)
#define CFG_TC_LOCAL_SCAN (PRIVATE_BASE + 32)
#define CFG_TUP_FRAG (PRIVATE_BASE + 33)
#define CFG_TUP_OP_RECS (PRIVATE_BASE + 34)
#define CFG_TUP_PAGE (PRIVATE_BASE + 35)
#define CFG_TUP_PAGE_RANGE (PRIVATE_BASE + 36)
#define CFG_TUP_TABLE (PRIVATE_BASE + 37)
#define CFG_TUP_TABLE_DESC (PRIVATE_BASE + 38)
#define CFG_TUP_STORED_PROC (PRIVATE_BASE + 39)
#define CFG_TUX_INDEX (PRIVATE_BASE + 40)
#define CFG_TUX_FRAGMENT (PRIVATE_BASE + 41)
#define CFG_TUX_ATTRIBUTE (PRIVATE_BASE + 42)
#define CFG_TUX_SCAN_OP (PRIVATE_BASE + 43)
#endif
#ifndef CNTR_START_HPP
#define CNTR_START_HPP
#include <NodeBitmask.hpp>
/**
*
*/
class CntrStartReq {
/**
* Sender(s) / Reciver(s)
*/
friend class Ndbcntr;
friend bool printCNTR_START_REQ(FILE*, const Uint32 *, Uint32, Uint16);
public:
STATIC_CONST( SignalLength = 3 );
private:
Uint32 nodeId;
Uint32 startType;
Uint32 lastGci;
};
class CntrStartRef {
/**
* Sender(s) / Reciver(s)
*/
friend class Ndbcntr;
friend bool printCNTR_START_REF(FILE*, const Uint32 *, Uint32, Uint16);
public:
STATIC_CONST( SignalLength = 2 );
enum ErrorCode {
OK = 0,
NotMaster = 1,
StopInProgress = 2
};
private:
Uint32 errorCode;
Uint32 masterNodeId;
};
class CntrStartConf {
/**
* Sender(s) / Reciver(s)
*/
friend class Ndbcntr;
friend struct UpgradeStartup;
friend bool printCNTR_START_CONF(FILE*, const Uint32 *, Uint32, Uint16);
public:
STATIC_CONST( SignalLength = 4 + 2 * NdbNodeBitmask::Size );
private:
Uint32 startType;
Uint32 startGci;
Uint32 masterNodeId;
Uint32 noStartNodes;
Uint32 startedNodes[NdbNodeBitmask::Size];
Uint32 startingNodes[NdbNodeBitmask::Size];
};
#endif
#ifndef READ_CONFIG_HPP
#define READ_CONFIG_HPP
/**
*/
class ReadConfigReq {
public:
STATIC_CONST( SignalLength = 3 );
Uint32 senderRef;
Uint32 senderData;
Uint32 noOfParameters; // 0 Means read all relevant for block
Uint32 parameters[1]; // see mgmapi_config_parameters.h
};
class ReadConfigConf {
public:
STATIC_CONST( SignalLength = 2 );
Uint32 senderRef;
Uint32 senderData;
};
#endif
#ifndef NDB_UPGRADE_STARTUP
#define NDB_UPGRADE_STARTUP
struct UpgradeStartup {
static void installEXEC(SimulatedBlock*);
static const Uint32 GSN_CM_APPCHG = 131;
static const Uint32 GSN_CNTR_MASTERCONF = 148;
static const Uint32 GSN_CNTR_MASTERREF = 149;
static const Uint32 GSN_CNTR_MASTERREQ = 150;
static void sendCmAppChg(Ndbcntr&, Signal *, Uint32 startLevel);
static void execCM_APPCHG(SimulatedBlock& block, Signal*);
static void sendCntrMasterReq(Ndbcntr& cntr, Signal* signal, Uint32 n);
static void execCNTR_MASTER_REPLY(SimulatedBlock & block, Signal* signal);
struct CntrMasterReq {
STATIC_CONST( SignalLength = 4 + NdbNodeBitmask::Size );
Uint32 userBlockRef;
Uint32 userNodeId;
Uint32 typeOfStart;
Uint32 noRestartNodes;
Uint32 theNodes[NdbNodeBitmask::Size];
};
struct CntrMasterConf {
STATIC_CONST( SignalLength = 1 + NdbNodeBitmask::Size );
Uint32 noStartNodes;
Uint32 theNodes[NdbNodeBitmask::Size];
};
};
#endif
#ifndef MGMAPI_CONFIG_PARAMTERS_H
#define MGMAPI_CONFIG_PARAMTERS_H
#define CFG_SYS_NAME 3
#define CFG_SYS_PRIMARY_MGM_NODE 1
#define CFG_SYS_CONFIG_GENERATION 2
#define CFG_SYS_REPLICATION_ROLE 7
#define CFG_NODE_ID 3
#define CFG_NODE_BYTE_ORDER 4
#define CFG_NODE_HOST 5
#define CFG_NODE_SYSTEM 6
/**
* DB config parameters
*/
#define CFG_DB_NO_SAVE_MSGS 100
#define CFG_DB_NO_REPLICAS 101
#define CFG_DB_NO_TABLES 102
#define CFG_DB_NO_ATTRIBUTES 103
#define CFG_DB_NO_INDEXES 104
#define CFG_DB_NO_TRIGGERS 105
#define CFG_DB_NO_TRANSACTIONS 106
#define CFG_DB_NO_OPS 107
#define CFG_DB_NO_SCANS 108
#define CFG_DB_NO_TRIGGER_OPS 109
#define CFG_DB_NO_INDEX_OPS 110
#define CFG_DB_TRANS_BUFFER_MEM 111
#define CFG_DB_DATA_MEM 112
#define CFG_DB_INDEX_MEM 113
#define CFG_DB_MEMLOCK 114
#define CFG_DB_START_PARTIAL_TIMEOUT 115
#define CFG_DB_START_PARTITION_TIMEOUT 116
#define CFG_DB_START_FAILURE_TIMEOUT 117
#define CFG_DB_HEARTBEAT_INTERVAL 118
#define CFG_DB_API_HEARTBEAT_INTERVAL 119
#define CFG_DB_LCP_INTERVAL 120
#define CFG_DB_GCP_INTERVAL 121
#define CFG_DB_ARBIT_TIMEOUT 122
#define CFG_DB_WATCHDOG_INTERVAL 123
#define CFG_DB_STOP_ON_ERROR 124
#define CFG_DB_FILESYSTEM_PATH 125
#define CFG_DB_NO_REDOLOG_FILES 126
#define CFG_DB_DISC_BANDWIDTH 127
#define CFG_DB_SR_DISC_BANDWITH 128
#define CFG_DB_TRANSACTION_CHECK_INTERVAL 129
#define CFG_DB_TRANSACTION_INACTIVE_TIMEOUT 130
#define CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT 131
#define CFG_DB_PARALLEL_BACKUPS 132
#define CFG_DB_BACKUP_MEM 133
#define CFG_DB_BACKUP_DATA_BUFFER_MEM 134
#define CFG_DB_BACKUP_LOG_BUFFER_MEM 135
#define CFG_DB_BACKUP_WRITE_SIZE 136
#define CFG_LOGLEVEL_STARTUP 137
#define CFG_LOGLEVEL_SHUTDOWN 138
#define CFG_LOGLEVEL_STATISTICS 139
#define CFG_LOGLEVEL_CHECKPOINT 140
#define CFG_LOGLEVEL_NODERESTART 141
#define CFG_LOGLEVEL_CONNECTION 142
#define CFG_LOGLEVEL_INFO 143
#define CFG_LOGLEVEL_WARNING 144
#define CFG_LOGLEVEL_ERROR 145
#define CFG_LOGLEVEL_GREP 146
#define CFG_LOG_DESTINATION 147
#define CFG_NODE_ARBIT_RANK 200
#define CFG_NODE_ARBIT_DELAY 201
#define CFG_MGM_PORT 300
#define CFG_CONNECTION_NODE_1 400
#define CFG_CONNECTION_NODE_2 401
#define CFG_CONNECTION_SEND_SIGNAL_ID 402
#define CFG_CONNECTION_CHECKSUM 403
#define CFG_CONNECTION_NODE_1_SYSTEM 404
#define CFG_CONNECTION_NODE_2_SYSTEM 405
#define CFG_TCP_HOSTNAME_1 450
#define CFG_TCP_HOSTNAME_2 451
#define CFG_TCP_SERVER 452
#define CFG_TCP_SERVER_PORT 453
#define CFG_TCP_SEND_BUFFER_SIZE 454
#define CFG_TCP_RECEIVE_BUFFER_SIZE 455
#define CFG_TCP_PROXY 456
#define CFG_SHM_SEND_SIGNAL_ID 500
#define CFG_SHM_CHECKSUM 501
#define CFG_SHM_KEY 502
#define CFG_SHM_BUFFER_MEM 503
#define CFG_SCI_ID_0 550
#define CFG_SCI_ID_1 551
#define CFG_SCI_SEND_LIMIT 552
#define CFG_SCI_BUFFER_MEM 553
#define CFG_SCI_NODE1_ADAPTERS 554
#define CFG_SCI_NODE1_ADAPTER0 555
#define CFG_SCI_NODE1_ADAPTER1 556
#define CFG_SCI_NODE2_ADAPTERS 554
#define CFG_SCI_NODE2_ADAPTER0 555
#define CFG_SCI_NODE2_ADAPTER1 556
#define CFG_OSE_HOSTNAME_1 600
#define CFG_OSE_HOSTNAME_2 601
#define CFG_OSE_PRIO_A_SIZE 602
#define CFG_OSE_PRIO_B_SIZE 603
#define CFG_OSE_RECEIVE_ARRAY_SIZE 604
#define CFG_REP_HEARTBEAT_INTERVAL 700
/**
* Internal
*/
#define CFG_DB_STOP_ON_ERROR_INSERT 1
#define CFG_TYPE_OF_SECTION 999
#define CFG_SECTION_SYSTEM 1000
#define CFG_SECTION_NODE 2000
#define CFG_SECTION_CONNECTION 3000
#define NODE_TYPE_DB 0
#define NODE_TYPE_API 1
#define NODE_TYPE_MGM 2
#define NODE_TYPE_REP 3
#define NODE_TYPE_EXT_REP 4
#define CONNECTION_TYPE_TCP 0
#define CONNECTION_TYPE_SHM 1
#define CONNECTION_TYPE_SCI 2
#define CONNECTION_TYPE_OSE 3
#endif
#ifndef MGMAPI_CONFIG_PARAMTERS_DEBUG_H
#define MGMAPI_CONFIG_PARAMTERS_DEBUG_H
#include "mgmapi_config_parameters.h"
#define CFG_DB_STOP_ON_ERROR_INSERT 1
#endif
#ifndef __CONFIG_VALUES_HPP
#define __CONFIG_VALUES_HPP
#include <ndb_types.h>
#include <UtilBuffer.hpp>
class ConfigValues {
friend class ConfigValuesFactory;
ConfigValues(Uint32 sz, Uint32 data);
public:
~ConfigValues();
enum ValueType {
InvalidType = 0,
IntType = 1,
StringType = 2,
SectionType = 3,
Int64Type = 4
};
struct Entry {
Uint32 m_key;
ValueType m_type;
union {
Uint32 m_int;
const char * m_string;
Uint64 m_int64;
};
};
class ConstIterator {
friend class ConfigValuesFactory;
const ConfigValues & m_cfg;
protected:
Uint32 m_currentSection;
public:
ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;}
bool openSection(Uint32 key, Uint32 no);
bool closeSection();
bool get(Uint32 key, Entry *) const;
bool get(Uint32 key, Uint32 * value) const;
bool get(Uint32 key, Uint64 * value) const;
bool get(Uint32 key, const char ** value) const;
bool getTypeOf(Uint32 key, ValueType * type) const;
Uint32 get(Uint32 key, Uint32 notFound) const;
Uint64 get64(Uint32 key, Uint64 notFound) const;
const char * get(Uint32 key, const char * notFound) const;
ValueType getTypeOf(Uint32 key) const;
};
class Iterator : public ConstIterator {
ConfigValues & m_cfg;
public:
Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {}
bool set(Uint32 key, Uint32 value);
bool set(Uint32 key, Uint64 value);
bool set(Uint32 key, const char * value);
};
Uint32 getPackedSize() const; // get size in bytes needed to pack
Uint32 pack(UtilBuffer&) const;
Uint32 pack(void * dst, Uint32 len) const;// pack into dst(of len %d);
private:
friend class Iterator;
friend class ConstIterator;
bool getByPos(Uint32 pos, Entry *) const;
Uint64 & get64(Uint32 index) const;
char * & getString(Uint32 index) const;
Uint32 m_size;
Uint32 m_dataSize;
Uint32 m_stringCount;
Uint32 m_int64Count;
Uint32 m_values[1];
void * m_data[1];
};
class ConfigValuesFactory {
Uint32 m_currentSection;
public:
Uint32 m_sectionCounter;
Uint32 m_freeKeys;
Uint32 m_freeData;
public:
ConfigValuesFactory(Uint32 keys = 50, Uint32 data = 10); // Initial
ConfigValuesFactory(ConfigValues * m_cfg); //
ConfigValues * m_cfg;
ConfigValues * getConfigValues();
bool openSection(Uint32 key, Uint32 no);
bool put(const ConfigValues::Entry & );
bool put(Uint32 key, Uint32 value);
bool put64(Uint32 key, Uint64 value);
bool put(Uint32 key, const char * value);
bool closeSection();
void expand(Uint32 freeKeys, Uint32 freeData);
void shrink();
bool unpack(const UtilBuffer&);
bool unpack(const void * src, Uint32 len);
static ConfigValues * extractCurrentSection(const ConfigValues::ConstIterator &);
private:
static ConfigValues * create(Uint32 keys, Uint32 data);
void put(const ConfigValues & src);
};
inline
bool
ConfigValues::ConstIterator::get(Uint32 key, Uint32 * value) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == IntType){
* value = tmp.m_int;
return true;
}
return false;
}
inline
bool
ConfigValues::ConstIterator::get(Uint32 key, Uint64 * value) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == Int64Type){
* value = tmp.m_int64;
return true;
}
return false;
}
inline
bool
ConfigValues::ConstIterator::get(Uint32 key, const char ** value) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == StringType){
* value = tmp.m_string;
return true;
}
return false;
}
inline
bool
ConfigValues::ConstIterator::getTypeOf(Uint32 key, ValueType * type) const{
Entry tmp;
if(get(key, &tmp)){
* type = tmp.m_type;
return true;
}
return false;
}
inline
Uint32
ConfigValues::ConstIterator::get(Uint32 key, Uint32 notFound) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == IntType){
return tmp.m_int;
}
return notFound;
}
inline
Uint64
ConfigValues::ConstIterator::get64(Uint32 key, Uint64 notFound) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == Int64Type){
return tmp.m_int64;
}
return notFound;
}
inline
const char *
ConfigValues::ConstIterator::get(Uint32 key, const char * notFound) const {
Entry tmp;
if(get(key, &tmp) && tmp.m_type == StringType){
return tmp.m_string;
}
return notFound;
}
inline
ConfigValues::ValueType
ConfigValues::ConstIterator::getTypeOf(Uint32 key) const{
Entry tmp;
if(get(key, &tmp)){
return tmp.m_type;
}
return ConfigValues::InvalidType;
}
inline
bool
ConfigValuesFactory::put(Uint32 key, Uint32 val){
ConfigValues::Entry tmp;
tmp.m_key = key;
tmp.m_type = ConfigValues::IntType;
tmp.m_int = val;
return put(tmp);
}
inline
bool
ConfigValuesFactory::put64(Uint32 key, Uint64 val){
ConfigValues::Entry tmp;
tmp.m_key = key;
tmp.m_type = ConfigValues::Int64Type;
tmp.m_int64 = val;
return put(tmp);
}
inline
bool
ConfigValuesFactory::put(Uint32 key, const char * val){
ConfigValues::Entry tmp;
tmp.m_key = key;
tmp.m_type = ConfigValues::StringType;
tmp.m_string = val;
return put(tmp);
}
inline
Uint32
ConfigValues::pack(UtilBuffer& buf) const {
Uint32 len = getPackedSize();
void * tmp = buf.append(len);
if(tmp == 0){
return 0;
}
return pack(tmp, len);
}
inline
bool
ConfigValuesFactory::unpack(const UtilBuffer& buf){
return unpack(buf.get_data(), buf.length());
}
#endif
#include <signaldata/CntrStart.hpp>
bool
printCNTR_START_REQ(FILE * output, const Uint32 * theData,
Uint32 len, Uint16 receiverBlockNo) {
const CntrStartReq * const sig = (CntrStartReq *)theData;
fprintf(output, " nodeId: %x\n", sig->nodeId);
fprintf(output, " startType: %x\n", sig->startType);
fprintf(output, " lastGci: %x\n", sig->lastGci);
return true;
}
bool
printCNTR_START_REF(FILE * output, const Uint32 * theData,
Uint32 len, Uint16 receiverBlockNo) {
const CntrStartRef * const sig = (CntrStartRef *)theData;
fprintf(output, " errorCode: %x\n", sig->errorCode);
fprintf(output, " masterNodeId: %x\n", sig->masterNodeId);
return true;
}
bool
printCNTR_START_CONF(FILE * output, const Uint32 * theData,
Uint32 len, Uint16 receiverBlockNo) {
const CntrStartConf * const sig = (CntrStartConf *)theData;
fprintf(output, " startType: %x\n", sig->startType);
fprintf(output, " startGci: %x\n", sig->startGci);
fprintf(output, " masterNodeId: %x\n", sig->masterNodeId);
fprintf(output, " noStartNodes: %x\n", sig->noStartNodes);
char buf[32*NdbNodeBitmask::Size+1];
fprintf(output, " startedNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf));
fprintf(output, " startingNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf));
return true;
}
#include <signaldata/ReadNodesConf.hpp>
bool
printREAD_NODES_CONF(FILE * output, const Uint32 * theData,
Uint32 len, Uint16 receiverBlockNo) {
const ReadNodesConf * const sig = (ReadNodesConf *)theData;
fprintf(output, " noOfNodes: %x\n", sig->noOfNodes);
fprintf(output, " ndynamicId: %x\n", sig->ndynamicId);
fprintf(output, " masterNodeId: %x\n", sig->masterNodeId);
char buf[32*NdbNodeBitmask::Size+1];
fprintf(output, " allNodes(defined): %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->allNodes, buf));
fprintf(output, " inactiveNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->inactiveNodes, buf));
fprintf(output, " clusterNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->clusterNodes, buf));
fprintf(output, " startedNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startedNodes, buf));
fprintf(output, " startingNodes: %s\n",
BitmaskImpl::getText(NdbNodeBitmask::Size, sig->startingNodes, buf));
return true;
}
#include <ConfigValues.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <new>
#include <NdbOut.hpp>
#include <NdbTCP.h>
static Uint32 hash(Uint32 key, Uint32 size);
static Uint32 nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count);
static bool findKey(const Uint32 * vals, Uint32 sz, Uint32 key, Uint32 * pos);
/**
* Key
*
* t = Type - 4 bits 0-15
* s = Section - 14 bits 0-16383
* k = Key value - 14 bits 0-16383
*
* 1111111111222222222233
* 01234567890123456789012345678901
* kkkkkkkkkkkkkkssssssssssssssoooo
*/
#define KP_TYPE_MASK (15)
#define KP_TYPE_SHIFT (28)
#define KP_SECTION_MASK (0x3FFF)
#define KP_SECTION_SHIFT (14)
#define KP_KEYVAL_MASK (0x3FFF)
#define KP_KEYVAL_SHIFT (0)
#define KP_MASK (0x0FFFFFFF)
static const Uint32 CFV_KEY_PARENT = (KP_KEYVAL_MASK - 1);
static const Uint32 CFV_KEY_FREE = ~0;
static const char Magic[] = { 'N', 'D', 'B', 'C', 'O', 'N', 'F', 'V' };
//#define DEBUG_CV
#ifdef DEBUG_CV
#define DEBUG
#else
#define DEBUG if(0)
#endif
inline
ConfigValues::ValueType
getTypeOf(Uint32 k) {
return (ConfigValues::ValueType)((k >> KP_TYPE_SHIFT) & KP_TYPE_MASK);
}
ConfigValues::ConfigValues(Uint32 sz, Uint32 dsz){
m_size = sz;
m_dataSize = dsz;
m_stringCount = 0;
m_int64Count = 0;
for(Uint32 i = 0; i<m_size; i++){
m_values[i << 1] = CFV_KEY_FREE;
}
}
ConfigValues::~ConfigValues(){
for(Uint32 i = 0; i<m_stringCount; i++){
free(getString(i));
}
}
bool
ConfigValues::ConstIterator::get(Uint32 key, Entry * result) const {
Uint32 pos;
if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){
return false;
}
result->m_key = key;
return m_cfg.getByPos(pos, result);
}
bool
ConfigValues::getByPos(Uint32 pos, Entry * result) const {
assert(pos < (2 * m_size));
Uint32 keypart = m_values[pos];
Uint32 val = m_values[pos+1];
switch(::getTypeOf(keypart)){
case IntType:
case SectionType:
result->m_int = val;
break;
case StringType:
result->m_string = getString(val);
break;
case Int64Type:
result->m_int64 = get64(val);
break;
case InvalidType:
default:
return false;
}
result->m_type = ::getTypeOf(keypart);
return true;
}
Uint64 &
ConfigValues::get64(Uint32 index) const {
assert(index < m_int64Count);
Uint64 * ptr = (Uint64*)(&m_values[m_size << 1]);
return ptr[index];
}
char * &
ConfigValues::getString(Uint32 index) const {
assert(index < m_stringCount);
char ** ptr = (char**)(((char *)&(m_values[m_size << 1])) + m_dataSize);
return ptr[-index];
}
bool
ConfigValues::ConstIterator::openSection(Uint32 key, Uint32 no){
Uint32 curr = m_currentSection;
Entry tmp;
if(get(key, &tmp) && tmp.m_type == SectionType){
m_currentSection = tmp.m_int;
if(get(no, &tmp) && tmp.m_type == IntType){
m_currentSection = tmp.m_int;
/**
* Validate
*/
if(get(CFV_KEY_PARENT, &tmp)){
return true;
}
}
}
m_currentSection = curr;
return false;
}
bool
ConfigValues::ConstIterator::closeSection() {
Entry tmp;
if(get(CFV_KEY_PARENT, &tmp) && tmp.m_type == IntType){
m_currentSection = tmp.m_int;
return true;
}
return false;
}
bool
ConfigValues::Iterator::set(Uint32 key, Uint32 value){
Uint32 pos;
if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){
return false;
}
if(::getTypeOf(m_cfg.m_values[pos]) != IntType){
return false;
}
m_cfg.m_values[pos+1] = value;
return true;
}
bool
ConfigValues::Iterator::set(Uint32 key, Uint64 value){
Uint32 pos;
if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){
return false;
}
if(::getTypeOf(m_cfg.m_values[pos]) != Int64Type){
return false;
}
m_cfg.get64(m_cfg.m_values[pos+1]) = value;
return true;
}
bool
ConfigValues::Iterator::set(Uint32 key, const char * value){
Uint32 pos;
if(!findKey(m_cfg.m_values, m_cfg.m_size, key | m_currentSection, &pos)){
return false;
}
if(::getTypeOf(m_cfg.m_values[pos]) != StringType){
return false;
}
char * & str = m_cfg.getString(m_cfg.m_values[pos+1]);
free(str);
str = strdup(value);
return true;
}
static
bool
findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){
Uint32 pos = hash(key, sz);
Uint32 count = 0;
while((values[pos] & KP_MASK) != key && count < sz){
pos = nextHash(key, sz, pos, ++count);
}
if((values[pos] & KP_MASK)== key){
*_pos = pos;
return true;
}
return false;
}
static
Uint32
hash(Uint32 key, Uint32 size){
Uint32 tmp = (key >> 16) ^ (key & 0xFFFF);
return (((tmp << 16) | tmp) % size) << 1;
}
static
Uint32
nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){
Uint32 p = (pos >> 1);
if((key % size) != 0)
p += key;
else
p += 1;
return (p % size) << 1;
}
static
Uint32
directory(Uint32 sz){
const Uint32 _input = sz;
if((sz & 1) == 0)
sz ++;
bool prime = false;
while(!prime){
prime = true;
for(Uint32 n = 3; n*n <= sz; n += 2){
if((sz % n) == 0){
prime = false;
sz += 2;
break;
}
}
}
DEBUG printf("directory %d -> %d\n", _input, sz);
return sz;
}
ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){
m_sectionCounter = (1 << KP_SECTION_SHIFT);
m_freeKeys = directory(keys);
m_freeData = data;
m_currentSection = 0;
m_cfg = create(m_freeKeys, data);
}
ConfigValuesFactory::ConfigValuesFactory(ConfigValues * cfg){
m_cfg = cfg;
m_freeKeys = 0;
m_freeData = m_cfg->m_dataSize;
m_sectionCounter = (1 << KP_SECTION_SHIFT);
m_currentSection = 0;
const Uint32 sz = 2 * m_cfg->m_size;
for(Uint32 i = 0; i<sz; i += 2){
const Uint32 key = m_cfg->m_values[i];
if(key == CFV_KEY_FREE){
m_freeKeys++;
} else {
switch(::getTypeOf(key)){
case ConfigValues::IntType:
case ConfigValues::SectionType:
break;
case ConfigValues::Int64Type:
m_freeData -= sizeof(Uint64);
break;
case ConfigValues::StringType:
m_freeData -= sizeof(char *);
break;
case ConfigValues::InvalidType:
abort();
}
Uint32 sec = key & (KP_SECTION_MASK << KP_SECTION_SHIFT);
m_sectionCounter = (sec > m_sectionCounter ? sec : m_sectionCounter);
}
}
}
ConfigValues *
ConfigValuesFactory::create(Uint32 keys, Uint32 data){
Uint32 sz = sizeof(ConfigValues);
sz += (2 * keys * sizeof(Uint32));
sz += data;
void * tmp = malloc(sz);
return new (tmp) ConfigValues(keys, data);
}
void
ConfigValuesFactory::expand(Uint32 fk, Uint32 fs){
if(m_freeKeys >= fk && m_freeData >= fs){
return ;
}
m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size);
m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize);
m_freeKeys = directory(m_freeKeys);
ConfigValues * m_tmp = m_cfg;
m_cfg = create(m_freeKeys, m_freeData);
put(* m_tmp);
m_tmp->~ConfigValues();
free(m_tmp);
}
void
ConfigValuesFactory::shrink(){
if(m_freeKeys == 0 && m_freeData == 0){
return ;
}
m_freeKeys = m_cfg->m_size - m_freeKeys;
m_freeData = m_cfg->m_dataSize - m_freeData;
m_freeKeys = directory(m_freeKeys);
ConfigValues * m_tmp = m_cfg;
m_cfg = create(m_freeKeys, m_freeData);
put(* m_tmp);
m_tmp->~ConfigValues();
free(m_tmp);
}
bool
ConfigValuesFactory::openSection(Uint32 key, Uint32 no){
ConfigValues::Entry tmp;
const Uint32 parent = m_currentSection;
ConfigValues::ConstIterator iter(* m_cfg);
iter.m_currentSection = m_currentSection;
if(!iter.get(key, &tmp)){
tmp.m_key = key;
tmp.m_type = ConfigValues::SectionType;
tmp.m_int = m_sectionCounter;
m_sectionCounter += (1 << KP_SECTION_SHIFT);
if(!put(tmp)){
return false;
}
}
if(tmp.m_type != ConfigValues::SectionType){
return false;
}
m_currentSection = tmp.m_int;
tmp.m_key = no;
tmp.m_type = ConfigValues::IntType;
tmp.m_int = m_sectionCounter;
if(!put(tmp)){
m_currentSection = parent;
return false;
}
m_sectionCounter += (1 << KP_SECTION_SHIFT);
m_currentSection = tmp.m_int;
tmp.m_type = ConfigValues::IntType;
tmp.m_key = CFV_KEY_PARENT;
tmp.m_int = parent;
if(!put(tmp)){
m_currentSection = parent;
return false;
}
return true;
}
bool
ConfigValuesFactory::closeSection(){
ConfigValues::ConstIterator iter(* m_cfg);
iter.m_currentSection = m_currentSection;
const bool b = iter.closeSection();
m_currentSection = iter.m_currentSection;
return b;
}
bool
ConfigValuesFactory::put(const ConfigValues::Entry & entry){
if(m_freeKeys == 0 ||
(entry.m_type == ConfigValues::StringType && m_freeData < sizeof(char *))
|| (entry.m_type == ConfigValues::Int64Type && m_freeData < 8 )){
DEBUG ndbout_c("m_freeKeys = %d, m_freeData = %d -> expand",
m_freeKeys, m_freeData);
expand(31, 20);
}
const Uint32 tmp = entry.m_key | m_currentSection;
const Uint32 sz = m_cfg->m_size;
Uint32 pos = hash(tmp, sz);
Uint32 count = 0;
Uint32 val = m_cfg->m_values[pos];
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
pos = nextHash(tmp, sz, pos, ++count);
val = m_cfg->m_values[pos];
}
if((val & KP_MASK) == tmp){
DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos);
return false;
}
if(count >= sz){
pos = hash(tmp, sz);
count = 0;
Uint32 val = m_cfg->m_values[pos];
printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz));
printf("pos: %d", pos);
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
pos = nextHash(tmp, sz, pos, ++count);
val = m_cfg->m_values[pos];
printf(" %d", pos);
}
printf("\n");
abort();
printf("Full\n");
return false;
}
assert(pos < (sz << 1));
Uint32 key = tmp;
key |= (entry.m_type << KP_TYPE_SHIFT);
m_cfg->m_values[pos] = key;
switch(entry.m_type){
case ConfigValues::IntType:
case ConfigValues::SectionType:
m_cfg->m_values[pos+1] = entry.m_int;
m_freeKeys--;
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n",
pos, sz, count,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
entry.m_int);
return true;
case ConfigValues::StringType:{
Uint32 index = m_cfg->m_stringCount++;
m_cfg->m_values[pos+1] = index;
m_cfg->getString(index) = strdup(entry.m_string);
m_freeKeys--;
m_freeData -= sizeof(char *);
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n",
pos, sz, count,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
index,
entry.m_string);
return true;
}
case ConfigValues::Int64Type:{
Uint32 index = m_cfg->m_int64Count++;
m_cfg->m_values[pos+1] = index;
m_cfg->get64(index) = entry.m_int64;
m_freeKeys--;
m_freeData -= 8;
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n",
pos, sz, count,
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
index,
entry.m_int64);
return true;
}
case ConfigValues::InvalidType:
default:
return false;
}
return false;
}
void
ConfigValuesFactory::put(const ConfigValues & cfg){
Uint32 curr = m_currentSection;
m_currentSection = 0;
ConfigValues::Entry tmp;
for(Uint32 i = 0; i < 2 * cfg.m_size; i += 2){
if(cfg.m_values[i] != CFV_KEY_FREE){
tmp.m_key = cfg.m_values[i];
cfg.getByPos(i, &tmp);
put(tmp);
}
}
m_currentSection = curr;
}
ConfigValues *
ConfigValuesFactory::extractCurrentSection(const ConfigValues::ConstIterator & cfg){
ConfigValuesFactory * fac = new ConfigValuesFactory(20, 20);
Uint32 curr = cfg.m_currentSection;
ConfigValues::Entry tmp;
for(Uint32 i = 0; i < 2 * cfg.m_cfg.m_size; i += 2){
Uint32 keypart = cfg.m_cfg.m_values[i];
const Uint32 sec = keypart & (KP_SECTION_MASK << KP_SECTION_SHIFT);
const Uint32 key = keypart & KP_KEYVAL_MASK;
if(sec == curr && key != CFV_KEY_PARENT){
tmp.m_key = cfg.m_cfg.m_values[i];
cfg.m_cfg.getByPos(i, &tmp);
tmp.m_key = key;
fac->put(tmp);
}
}
ConfigValues * ret = fac->m_cfg;
delete fac;
return ret;
}
ConfigValues *
ConfigValuesFactory::getConfigValues(){
ConfigValues * ret = m_cfg;
m_cfg = create(10, 10);
return ret;
}
static int
mod4(unsigned int i){
int res = i + (4 - (i % 4));
return res;
}
Uint32
ConfigValues::getPackedSize() const {
Uint32 size = 0;
for(Uint32 i = 0; i < 2 * m_size; i += 2){
Uint32 key = m_values[i];
if(key != CFV_KEY_FREE){
switch(::getTypeOf(key)){
case IntType:
case SectionType:
size += 8;
break;
case Int64Type:
size += 12;
break;
case StringType:
size += 8; // key + len
size += mod4(strlen(getString(m_values[i+1])) + 1);
break;
case InvalidType:
default:
abort();
}
}
}
return size + sizeof(Magic) + 4; // checksum also
}
Uint32
ConfigValues::pack(void * _dst, Uint32 _len) const {
char * dst = (char*)_dst;
memcpy(dst, Magic, sizeof(Magic)); dst += sizeof(Magic);
for(Uint32 i = 0; i < 2 * m_size; i += 2){
Uint32 key = m_values[i];
Uint32 val = m_values[i+1];
if(key != CFV_KEY_FREE){
switch(::getTypeOf(key)){
case IntType:
case SectionType:
* (Uint32*)dst = htonl(key); dst += 4;
* (Uint32*)dst = htonl(val); dst += 4;
break;
case Int64Type:{
Uint64 i64 = get64(val);
Uint32 hi = (i64 >> 32);
Uint32 lo = (i64 & 0xFFFFFFFF);
* (Uint32*)dst = htonl(key); dst += 4;
* (Uint32*)dst = htonl(hi); dst += 4;
* (Uint32*)dst = htonl(lo); dst += 4;
}
break;
case StringType:{
const char * str = getString(val);
Uint32 len = strlen(str) + 1;
* (Uint32*)dst = htonl(key); dst += 4;
* (Uint32*)dst = htonl(len); dst += 4;
memcpy(dst, str, len);
memset(dst+len, 0, mod4(len) - len);
dst += mod4(len);
}
break;
case InvalidType:
default:
abort();
}
}
}
const Uint32 * sum = (Uint32*)_dst;
const Uint32 len = ((Uint32*)dst) - sum;
Uint32 chk = 0;
for(Uint32 i = 0; i<len; i++){
chk ^= htonl(sum[i]);
}
* (Uint32*)dst = htonl(chk); dst += 4;
return 4 * (len + 1);
}
bool
ConfigValuesFactory::unpack(const void * _src, Uint32 len){
if(len < sizeof(Magic) + 4){
DEBUG abort();
return false;
}
if(memcmp(_src, Magic, sizeof(Magic)) != 0){
DEBUG abort();
return false;
}
const char * src = (const char *)_src;
{
Uint32 len32 = (len >> 2);
const Uint32 * tmp = (const Uint32*)_src;
Uint32 chk = 0;
for(Uint32 i = 0; (i+1)<len32; i++){
chk ^= ntohl(tmp[i]);
}
if(chk != ntohl(tmp[len32-1])){
DEBUG abort();
return false;
}
}
const char * end = src + len - 4;
src += sizeof(Magic);
ConfigValues::Entry entry;
while(end - src > 4){
Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
entry.m_key = tmp & KP_MASK;
entry.m_type = ::getTypeOf(tmp);
switch(entry.m_type){
case ConfigValues::IntType:
case ConfigValues::SectionType:
entry.m_int = ntohl(* (const Uint32 *)src); src += 4;
break;
case ConfigValues::Int64Type:{
Uint64 hi = ntohl(* (const Uint32 *)src); src += 4;
Uint64 lo = ntohl(* (const Uint32 *)src); src += 4;
entry.m_int64 = (hi <<32) | lo;
}
break;
case ConfigValues::StringType:{
Uint32 s_len = ntohl(* (const Uint32 *)src); src += 4;
size_t s_len2 = strnlen((const char*)src, s_len);
if(s_len2 + 1 != s_len){
DEBUG abort();
return false;
}
entry.m_string = (const char*)src; src+= mod4(s_len);
}
break;
case ConfigValues::InvalidType:
default:
DEBUG abort();
return false;
}
if(!put(entry)){
DEBUG abort();
return false;
}
}
if(src != end){
DEBUG abort();
return false;
}
return true;
}
#ifdef __TEST_CV_HASH_HPP
int
main(void){
srand(time(0));
for(int t = 0; t<100; t++){
const size_t len = directory(rand() % 1000);
printf("size = %d\n", len);
unsigned * buf = new unsigned[len];
for(size_t key = 0; key<len; key++){
Uint32 p = hash(key, len);
for(size_t j = 0; j<len; j++){
buf[j] = p;
p = nextHash(key, len, p, j+1);
}
for(size_t j = 0; j<len; j++){
Uint32 pos = buf[j];
int unique = 0;
for(size_t k = j + 1; k<len; k++){
if(pos == buf[k]){
if(unique > 0)
printf("size=%d key=%d pos(%d)=%d buf[%d]=%d\n", len, key, j, pos, k, buf[k]);
unique ++;
}
}
if(unique > 1){
printf("key = %d size = %d not uniqe!!\n", key, len);
for(size_t k = 0; k<len; k++){
printf("%d ", buf[k]);
}
printf("\n");
}
}
}
delete[] buf;
}
return 0;
}
#endif
#include <ConfigValues.hpp>
#include <NdbOut.hpp>
#include <stdlib.h>
#include <string.h>
#define CF_NODES 1
#define CF_LOG_PAGES 2
#define CF_MEM_PAGES 3
#define CF_START_TO 4
#define CF_STOP_TO 5
void print(Uint32 i, ConfigValues::ConstIterator & cf){
ndbout_c("---");
for(Uint32 j = 2; j<=7; j++){
switch(cf.getTypeOf(j)){
case ConfigValues::IntType:
ndbout_c("Node %d : CFG(%d) : %d",
i, j, cf.get(j, 999));
break;
case ConfigValues::Int64Type:
ndbout_c("Node %d : CFG(%d) : %lld (64)",
i, j, cf.get64(j, 999));
break;
case ConfigValues::StringType:
ndbout_c("Node %d : CFG(%d) : %s",
i, j, cf.get(j, "<NOT FOUND>"));
break;
default:
ndbout_c("Node %d : CFG(%d) : TYPE: %d",
i, j, cf.getTypeOf(j));
}
}
}
void print(Uint32 i, ConfigValues & _cf){
ConfigValues::ConstIterator cf(_cf);
print(i, cf);
}
void
print(ConfigValues & _cf){
ConfigValues::ConstIterator cf(_cf);
Uint32 i = 0;
while(cf.openSection(CF_NODES, i)){
print(i, cf);
cf.closeSection();
i++;
}
}
inline
void
require(bool b){
if(!b)
abort();
}
int
main(void){
{
ConfigValuesFactory cvf(10, 20);
cvf.openSection(1, 0);
cvf.put(2, 12);
cvf.put64(3, 13);
cvf.put(4, 14);
cvf.put64(5, 15);
cvf.put(6, "Keso");
cvf.put(7, "Kent");
cvf.closeSection();
cvf.openSection(1, 1);
cvf.put(2, 22);
cvf.put64(3, 23);
cvf.put(4, 24);
cvf.put64(5, 25);
cvf.put(6, "Kalle");
cvf.put(7, "Anka");
cvf.closeSection();
ndbout_c("-- print --");
print(* cvf.m_cfg);
cvf.shrink();
ndbout_c("shrink\n-- print --");
print(* cvf.m_cfg);
cvf.expand(10, 10);
ndbout_c("expand\n-- print --");
print(* cvf.m_cfg);
ndbout_c("packed size: %d", cvf.m_cfg->getPackedSize());
ConfigValues::ConstIterator iter(* cvf.m_cfg);
iter.openSection(CF_NODES, 0);
ConfigValues * cfg2 = ConfigValuesFactory::extractCurrentSection(iter);
print(99, * cfg2);
cvf.shrink();
ndbout_c("packed size: %d", cfg2->getPackedSize());
UtilBuffer buf;
Uint32 l1 = cvf.m_cfg->pack(buf);
Uint32 l2 = cvf.m_cfg->getPackedSize();
require(l1 == l2);
ConfigValuesFactory cvf2;
require(cvf2.unpack(buf));
UtilBuffer buf2;
cvf2.shrink();
Uint32 l3 = cvf2.m_cfg->pack(buf2);
require(l1 == l3);
ndbout_c("unpack\n-- print --");
print(* cvf2.m_cfg);
cfg2->~ConfigValues();;
cvf.m_cfg->~ConfigValues();
free(cfg2);
free(cvf.m_cfg);
}
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment