DESCRIPTION inserts a new element to a hash. it will have a _copy_ of data, not a pointer to it. RETURN 0 - inserted 1 - didn't (unique key conflict) -1 - out of memory NOTE see linsert() for pin usage notes */
| 365 | see linsert() for pin usage notes |
| 366 | */ |
| 367 | int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data) |
| 368 | { |
| 369 | int csize, bucket, hashnr; |
| 370 | LF_SLIST *node, * volatile *el; |
| 371 | |
| 372 | lf_rwlock_by_pins(pins); |
| 373 | node= (LF_SLIST *)_lf_alloc_new(pins); |
| 374 | if (unlikely(!node)) |
| 375 | return -1; |
| 376 | memcpy(node+1, data, hash->element_size); |
| 377 | node->key= hash_key(hash, (uchar *)(node+1), &node->keylen); |
| 378 | hashnr= calc_hash(hash, node->key, node->keylen); |
| 379 | bucket= hashnr % hash->size; |
| 380 | el= _lf_dynarray_lvalue(&hash->array, bucket); |
| 381 | if (unlikely(!el)) |
| 382 | return -1; |
| 383 | if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins))) |
| 384 | return -1; |
| 385 | node->hashnr= my_reverse_bits(hashnr) | 1; /* normal node */ |
| 386 | if (linsert(el, hash->charset, node, pins, hash->flags)) |
| 387 | { |
| 388 | _lf_alloc_free(pins, node); |
| 389 | lf_rwunlock_by_pins(pins); |
| 390 | return 1; |
| 391 | } |
| 392 | csize= hash->size; |
| 393 | if ((my_atomic_add32(&hash->count, 1)+1.0) / csize > MAX_LOAD) |
| 394 | my_atomic_cas32(&hash->size, &csize, csize*2); |
| 395 | lf_rwunlock_by_pins(pins); |
| 396 | return 0; |
| 397 | } |
| 398 | |
| 399 | /* |
| 400 | DESCRIPTION |
no test coverage detected