Загрузка и поиск ~12 млн. MD5-хешей (16 байт)
От: licedey  
Дата: 12.05.11 04:49
Оценка:
Здравствуйте,

Для загрузки использую хэш-таблицу с прямой адресацией. Описание здесь.

Исходник
unsigned long Array<SigT>::Hash2( const unsigned char keyMD5[MD5_DIGEST_LEN] )
{            
    unsigned int uHash1 = 0, uHash2 = 0;

    // evaluate 2 hashes of keyMD5 string:
    // uHash1 in the range [ 0 .. TOTAL_CELL_COUNT - 1 ]
    // uHash2 in the range [ 1 .. TOTAL_CELL_COUNT - 1 ]
    int p = 0;
    do
    {
        uHash1 *= STRIDE_1; uHash1 += ( STRIDE_2 * keyMD5[p] );
        uHash2 *= STRIDE_2; uHash2 += ( STRIDE_1 * keyMD5[p] );
    } while(++p < MD5_DIGEST_LEN);

    uHash1 %= this->TOTAL_CELL_COUNT;
    uHash2 %= ( this->TOTAL_CELL_COUNT - 1 ); ++uHash2;
    // searching
    while( this->bufArIxes[ uHash1 ] != SIGDATA_IDX_BAD  )
    {        
        const SigT &hashedSignature = this->signsBuffer[ bufArIxes[ uHash1 ] ];
        if( !memcmp( keyMD5, hashedSignature.MD5, MD5_DIGEST_LEN ) )        
            return bufArIxes[ uHash1 ];        

        uHash1 += uHash2; uHash1 %= this->TOTAL_CELL_COUNT;
    }

    // unique item, not found in signature buffer, this->bufArIxes[ uHash1 ] == SIGDATA_IDX_BAD
    return uHash1;
}


// fill bufArIxes with indexes in signsBuffer. Hash by MD5 key
template <class SigT>
void Array<SigT>::Make()
{    
    // order by MD5, exclude duplicates    
    for( size_t bufIx = 0; bufIx < sigCount; bufIx++ )
    {
        unsigned uHash1 = Hash2( signsBuffer[bufIx].MD5 );       // SigT *signsBuffer - сплошной массив, хранит MD-5 хэши  (сигнатуры)
        if( bufArIxes[uHash1] == SIGDATA_IDX_BAD )                 // unsigned *bufArIxes - индексы в signsBuffer, вычисленные Hash2
            bufArIxes[uHash1] = bufIx;
    }
}


template <typename SigT>
SigT *Array<SigT>::HashSearch(unsigned char MD5[MD5_DIGEST_LEN] )
{    
    unsigned uHash1 = Hash2( MD5 );    
    if( this->bufArIxes[uHash1] != SIGDATA_IDX_BAD )
        return (SigT *)&this->signsBuffer[ bufArIxes[uHash1] ];
    return NULL;
}


Алгоритм загрузки сигнатур, еще загружает vector размеров файлов, для бинарного-поиска по нему. Поиск по этому массиву размеров делается перед вычислением мд5-хэша.
Суммируя: это достойная структура для работы с МД5-хэшами загрузка/поиск? Что можно выбрать лучше И собственно алгоритм формирования хэша из файла (буфера). Вроде GetFileSignature
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.