unordered_map — правильный способ использования пользовательского указателя

Я пытаюсь использовать пользовательскую хэш-функцию и пользовательский ключ с uordered_map.
Проблема в том, что когда ключ не существует, мне нужно скопировать содержимое указателя (void * record) в (void * key.buffer), поскольку (void * record) будет освобожден, что приведет к (void * key.buffer) точке неверное местоположение.

Код работает правильно, но я думаю, есть ли лучший способ (с лучшей производительностью и кодом Elegante) сделать то же самое. Я вставляю новое значение в предложение try-catch. 🙁

СЛУЧАЙ 1:

struct Key
{
void *buffer;
int size;
};

bool operator==(Key const &p1, Key const &p2)
{
int ret = memcmp(p1.buffer, p2.buffer, p1.size);
return (ret == 0);
}//sorry, i forgot to put the hash_value
size_t hash_value(Key const& k)
{
//return (*(int *)(k.buffer));
return  MurmurHash2(k.buffer, k.size, 99);
}

BOOST_FIXTURE_TEST_CASE(  HashGroupBy_NoFilter, HashGroup_Init){

void *record = 0;
int actualBlock = 0;
typedef boost::unordered_map<Key, int>::iterator iter_type;

boost::unordered_map<Key,int> groupByMap;
Key valueKey;
ds->open();
while (ds->getNextBlock(actualBlock)){
for (int i =0; i<ds->getRecordsInBlock(); i++){
record = ds->getNextRecord(i);
valueKey.size = ds->dsMetadata->fieldSize;
valueKey.buffer = record;
try
{
int &count = groupByMap.at(valueKey);
count ++;
}
catch (...)
{
valueKey.buffer = new char[valueKey.size];
memcpy(valueKey.buffer, record, valueKey.size);

std::pair<Key,int> recValue (valueKey, 1);
groupByMap.insert(recValue);
}

matchRecords++;
}
actualBlock++;
}

}

Если я использую «count», я заплачу «hash time». В случае, если ключ существует, мне придется заплатить еще раз, чтобы получить значение. Так что я думаю, что это хуже, чем первый случай.

Вариант 2:

if (groupByMap.count(valueKey)){ //exist
//pay hash calculation to get value
} else{
//pay hash calculation to insert
}

0

Решение

Вы должны предоставить спецификацию хэша для вашего типа ключа, чтобы он работал правильно:

using std::hash;

template<> struct hash<Key> {
size_t operator()(const Key &k) {
// compute a hash value for k and return it
}
};
1

Другие решения

Я решаю проблему …

iter_type it=groupByMap.find(valueKey);
if (it == groupByMap.end()){ //nao existe
hashFunctions::Key k = clone(valueKey);
std::pair<hashFunctions::Key,int> recValue (k, 1);
groupByMap.insert(it, recValue);
}else
it->second ++;
0

По вопросам рекламы [email protected]