📄 configvalues.cpp
字号:
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;}boolConfigValuesFactory::closeSection(){ ConfigValues::ConstIterator iter(* m_cfg); iter.m_currentSection = m_currentSection; const bool b = iter.closeSection(); m_currentSection = iter.m_currentSection; return b;} boolConfigValuesFactory::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; char ** ref = m_cfg->getString(index); * ref = strdup(entry.m_string ? 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;}voidConfigValuesFactory::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 intmod4(unsigned int i){ int res = i + (4 - (i % 4)); return res;}Uint32ConfigValues::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}Uint32ConfigValues::pack(void * _dst, Uint32 _len) const { Uint32 i; char * dst = (char*)_dst; memcpy(dst, Magic, sizeof(Magic)); dst += sizeof(Magic); for(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(i = 0; i<len; i++){ chk ^= htonl(sum[i]); } * (Uint32*)dst = htonl(chk); dst += 4; return 4 * (len + 1);}boolConfigValuesFactory::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 = strlen((const char*)src); 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_HPPintmain(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -