qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v6 10/15] qht: QEMU's fast, resizable and scalab


From: Sergey Fedorov
Subject: Re: [Qemu-devel] [PATCH v6 10/15] qht: QEMU's fast, resizable and scalable Hash Table
Date: Sun, 29 May 2016 22:55:57 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0

On 29/05/16 22:52, Sergey Fedorov wrote:
> On 25/05/16 04:13, Emilio G. Cota wrote:
>> +
>> +/* call with head->lock held */
>> +static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
>> +                               struct qht_bucket *head, void *p, uint32_t 
>> hash,
>> +                               bool *needs_resize)
>> +{
>> +    struct qht_bucket *b = head;
>> +    struct qht_bucket *prev = NULL;
>> +    struct qht_bucket *new = NULL;
>> +    int i;
>> +
>> +    for (;;) {
>> +        if (b == NULL) {
>> +            b = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*b));
>> +            memset(b, 0, sizeof(*b));
>> +            new = b;
>> +            atomic_inc(&map->n_added_buckets);
>> +            if (unlikely(qht_map_needs_resize(map)) && needs_resize) {
>> +                *needs_resize = true;
>> +            }
>> +        }
>> +        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
>> +            if (b->pointers[i]) {
>> +                if (unlikely(b->pointers[i] == p)) {
>> +                    return false;
>> +                }
>> +                continue;
>> +            }
>> +            /* found an empty key: acquire the seqlock and write */
>> +            seqlock_write_begin(&head->sequence);
>> +            if (new) {
>> +                atomic_rcu_set(&prev->next, b);
>> +            }
>> +            b->hashes[i] = hash;
>> +            atomic_set(&b->pointers[i], p);
>> +            seqlock_write_end(&head->sequence);
>> +            return true;
>> +        }
>> +        prev = b;
>> +        b = b->next;
>> +    }
>> +}
> Here is my attempt:

static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
                               struct qht_bucket *head, void *p,
uint32_t hash,
                               bool *needs_resize)
{
    struct qht_bucket **bpp = &head, *new;
    int i = 0;

    do {
        while (i < QHT_BUCKET_ENTRIES) {
            if ((*bpp)->pointers[i]) {
                if (unlikely((*bpp)->pointers[i] == p)) {
                    return false;
                }
                i++;
                continue;
            }
            goto found;
        }
        bpp = &(*bpp)->next;
        i = 0;
    } while (*bpp);

    new = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*new));
    memset(new, 0, sizeof(*new));
    atomic_rcu_set(bpp, new);
    atomic_inc(&map->n_added_buckets);
    if (unlikely(qht_map_needs_resize(map)) && needs_resize) {
        *needs_resize = true;
    }
found:
    /* found an empty key: acquire the seqlock and write */
    seqlock_write_begin(&head->sequence);
    (*bpp)->hashes[i] = hash;
    atomic_set(&(*bpp)->pointers[i], p);
    seqlock_write_end(&head->sequence);
    return true;
}

> Feel free to use it as you wish.

Sorry for the chopped email. Hope this one will be better :)

Kind regards,
Sergey



reply via email to

[Prev in Thread] Current Thread [Next in Thread]