uordered_map でカスタム ハッシュ関数とカスタム キーを使用しようとしています。問題は、キーが存在しない場合、ポインター (void *record) の内容を (void *key.buffer) にコピーする必要があることです。これは、(void * record) が解放されて (void *key.buffer) ポイントが発生するためです。無効な場所。
コードは正しく機能していますが、同じことを行うためのより良い方法 (より優れたパフォーマンスとエレガントなコード) があるかどうかを考えています。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++;
}
}
「カウント」を使用する場合、「ハッシュ時間」を支払います。キーが存在する場合、値を取得するために別のハッシュ時間を支払う必要があります。したがって、ケース1よりも最悪だと思います。
ケース2:
if (groupByMap.count(valueKey)){ //exist
//pay hash calculation to get value
} else{
//pay hash calculation to insert
}