lockfree_hashmap( size_t num = 65535, Hash inhasher = boost::hash< Tkey* >() ) :
element_num( num ) {
hashmap = new container[num];
- hasher = inhasher;
+ hasher = inhasher;
__sync_lock_test_and_set( &all_ctr, 0 );
}
do{
if( likely( !find_bucket( hashvalue, key, pre_key, true ) ) ) return;
}
- while( !__sync_bool_compare_and_swap( &hashmap[hashvalue].key, pre_key, key ) );
+ while( unlikely( !__sync_bool_compare_and_swap( &hashmap[hashvalue].key, pre_key, key ) ) );
hashmap[hashvalue].value = const_cast< Tvalue* >( value );
__sync_add_and_fetch( &all_ctr, 1 );
}
do{
if( unlikely( !find_bucket( hashvalue, key, pre_key, false ) ) ) return;
}
- while( !__sync_bool_compare_and_swap( &hashmap[hashvalue].key, pre_key, NULL ) );
+ while( unlikely( !__sync_bool_compare_and_swap( &hashmap[hashvalue].key, pre_key, NULL ) ) );
hashmap[hashvalue].value = NULL;
__sync_sub_and_fetch( &all_ctr, 1 );
}
//poper
void pop( Tkey*& key, Tvalue*& value ){
- for( size_t i = 0 ; i < element_num; ++i ){
- if( hashmap[i].key ){
+ for( size_t i = 0 ; likely( i < element_num ) ; ++i ){
+ if( unlikely( hashmap[i].key ) ){
key = hashmap[i].key;
value = hashmap[i].value;
hashmap[i].key = NULL;
// functor
void do_all( boost::function< void( Tvalue* ) > func ){
- for( size_t i = 0; i < element_num; ++i ){
- if( hashmap[i].key != NULL ){
+ for( size_t i = 0; likely( i < element_num ) ; ++i ){
+ if( unlikely( hashmap[i].key ) ){
func( hashmap[i].value );
}
}
//bucket finder
bool find_bucket( size_t& hash_value, const Tkey*& key, Tkey*& pre_key, bool insert ){
for(;;){
- if( hashmap[hash_value].key == NULL ){
+ if( unlikely (hashmap[hash_value].key == NULL ) ){
if( insert ) return true;
if( unlikely( hashmap[hash_value].rehash ) )
hash_value = re_hashvalue( hash_value );
else
return( false );
}
- else if( hashmap[hash_value].key == key ) {
+ else if( likely( hashmap[hash_value].key == key ) ){
pre_key = hashmap[hash_value].key;
return true;
}
else{
- if( insert ){
+ if( unlikely( insert ) ){
hashmap[hash_value].rehash = true;
hash_value = re_hashvalue( hash_value );
}
}
}
}
+ //get array number by hasher
size_t get_hashvalue(const Tkey* key ){
return hasher( const_cast<Tkey*>(key) ) % element_num;
}
+ //reget array number case of collision(method chain)
size_t re_hashvalue( size_t& key ){
return ((key+1) % element_num);
}
delete [] node;
}
+ //pusher
bool push(const Tvalue* value){
size_t tail,nexttail;
//transaction st
start:
tail = tailloc;
nexttail = get_num_next(tail);
- if ( unlikely( node[tail].value ) ) {
+ if ( unlikely( node[tail].value ) ){
//return false;
+ //do spin case of full queue
goto start;
}
if ( likely( __sync_bool_compare_and_swap(&tailloc,tail,nexttail) ) ) break;
return true;
}
+ //poper
Tvalue* pop() {
size_t head,nexthead;
Tvalue* rtnvalue;
while(true){
head = headloc;
nexthead = get_num_next(head);
- if( unlikely( !(node[head].value) ) ) {
- if( unlikely( headloc==tailloc ) ) {
+ if( unlikely( !(node[head].value) ) ){
+ if( unlikely( headloc==tailloc ) ){
//false
return NULL;
}
}else{
- if( likely( __sync_bool_compare_and_swap(&headloc,head,nexthead) ) ) {
+ if( likely( __sync_bool_compare_and_swap(&headloc,head,nexthead) ) ){
rtnvalue = node[head].value;
break;
}
return rtnvalue;
}
- bool empty() const{
- if( counter ) return false;
- return true;
- }
- size_t size() const{
- return counter;
- }
+ //size
+ size_t size() const{ return counter; }
+
+ //empty
+ bool empty() const{ return !counter; }
private:
+ //get next value head and tail cyclic over elemental number
size_t get_num_next( const size_t num ){
if( unlikely( num >= element_num ) ){
return 0;