我尝试使用自定义哈希函数和使用uordered_map的自定义键。 问题是:当密钥不存在时,我需要将指针(void * record)的内容复制到(void * key.buffer),因为(void * record)将被释放,导致(void * key.buffer)指向无效的位置。
代码工作正常,但我在想是否有更好的方法(具有更好的性能和优雅的代码)来做同样的事情。我在try-catch子句中插入一个新值。 :(
CASE1:
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”,我将支付“哈希时间”。在密钥存在的情况下,我将需要支付另一个哈希时间来获得该值。所以我认为这比案例1更糟糕。
CASE2:
if (groupByMap.count(valueKey)){ //exist
//pay hash calculation to get value
} else{
//pay hash calculation to insert
}
答案 0 :(得分:1)
您需要为密钥类型提供哈希特化,以使其正常工作:
using std::hash;
template<> struct hash<Key> {
size_t operator()(const Key &k) {
// compute a hash value for k and return it
}
};
答案 1 :(得分:0)
我解决了这个问题...
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 ++;