📄 configvalues.cpp
字号:
#include <ndb_global.h>#include <ConfigValues.hpp>#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)#endifinlineConfigValues::ValueTypegetTypeOf(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)); }}boolConfigValues::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);}boolConfigValues::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); const Uint32 * data = m_values + (m_size << 1); Uint64 * ptr = (Uint64*)data; ptr += index; return ptr;}char **ConfigValues::getString(Uint32 index) const { assert(index < m_stringCount); const Uint32 * data = m_values + (m_size << 1); char * ptr = (char*)data; ptr += m_dataSize; ptr -= (index * sizeof(char *)); return (char**)ptr;}boolConfigValues::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;}boolConfigValues::ConstIterator::closeSection() { Entry tmp; if(get(CFV_KEY_PARENT, &tmp) && tmp.m_type == IntType){ m_currentSection = tmp.m_int; return true; } return false;}boolConfigValues::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;}boolConfigValues::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;}boolConfigValues::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 ? value : ""); return true;}staticboolfindKey(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;}staticUint32hash(Uint32 key, Uint32 size){ Uint32 tmp = (key >> 16) ^ (key & 0xFFFF); return (((tmp << 16) | tmp) % size) << 1;}staticUint32nextHash(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;}staticUint32directory(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 + 7) & ~7; m_currentSection = 0; m_cfg = create(m_freeKeys, m_freeData);}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);}voidConfigValuesFactory::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); m_freeData = (m_freeData + 7) & ~7; ConfigValues * m_tmp = m_cfg; m_cfg = create(m_freeKeys, m_freeData); put(* m_tmp); m_tmp->~ConfigValues(); free(m_tmp);}voidConfigValuesFactory::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); m_freeData = (m_freeData + 7) & ~7; ConfigValues * m_tmp = m_cfg; m_cfg = create(m_freeKeys, m_freeData); put(* m_tmp); m_tmp->~ConfigValues(); free(m_tmp);}boolConfigValuesFactory::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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -