configvalues.cpp

来自「MySQL源码文件5.X系列, 可自已编译到服务器」· C++ 代码 · 共 805 行 · 第 1/2 页

CPP
805
字号
/* Copyright (C) 2004, 2006 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; version 2 of the License.   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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#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 if(getenv("CV_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 lo = 0;  Uint32 hi = sz;  Uint32 pos = (hi + lo) >> 1;  DEBUG printf("findKey(H'%.8x %d)", key, sz);  if (sz == 0)  {    DEBUG ndbout_c(" -> false, 0");    * _pos = 0;    return false;  }  Uint32 val = 0;  Uint32 oldpos = pos + 1;  while (pos != oldpos)   {    DEBUG printf(" [ %d %d %d ] ", lo, pos, hi);    assert(pos < hi);    assert(pos >= lo);    val = values[2*pos] & KP_MASK;    if (key > val)    {      lo = pos;    }    else if (key < val)    {      hi = pos;    }    else     {      * _pos = 2*pos;      DEBUG ndbout_c(" -> true, %d", pos);      return true;    }    oldpos = pos;    pos = (hi + lo) >> 1;  }   DEBUG printf(" pos: %d (key %.8x val: %.8x values[pos]: %x) key>val: %d ",	       pos, key, val, values[2*pos] & KP_MASK,	       key > val);  pos += (key > val) ? 1 : 0;    * _pos = 2*pos;  DEBUG ndbout_c(" -> false, %d", pos);  return false;}ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){  m_sectionCounter = (1 << KP_SECTION_SHIFT);  m_freeKeys = 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);    }  }}ConfigValuesFactory::~ConfigValuesFactory(){  if(m_cfg)    free(m_cfg);}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 ;  }  DEBUG printf("[ fk fd ] : [ %d %d ]", m_freeKeys, m_freeData);    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_freeData = (m_freeData + 7) & ~7;    DEBUG ndbout_c(" [ %d %d ]", m_freeKeys, m_freeData);  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_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);    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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?