Exemplo n.º 1
0
bool initialize_item_tap_walker(struct default_engine *engine,
                                const void* cookie)
{
    bool linked = false;
    int ii;
    struct tap_client *client = calloc(1, sizeof(*client));
    if (client == NULL) {
        return false;
    }
    client->cursor.refcount = 1;

    /* Link the cursor! */
    for (ii = 0; ii < POWER_LARGEST && !linked; ++ii) {
        cb_mutex_enter(&engine->items.lock);
        if (engine->items.heads[ii] != NULL) {
            /* add the item at the tail */
            do_item_link_cursor(engine, &client->cursor, ii);
            linked = true;
        }
        cb_mutex_exit(&engine->items.lock);
    }

    engine->server.cookie->store_engine_specific(cookie, client);
    return true;
}
Exemplo n.º 2
0
void item_scrubber_main(struct default_engine *engine)
{
    hash_item cursor;
    int ii;

    memset(&cursor, 0, sizeof(cursor));
    cursor.refcount = 1;
    for (ii = 0; ii < POWER_LARGEST; ++ii) {
        bool skip = false;
        cb_mutex_enter(&engine->items.lock);
        if (engine->items.heads[ii] == NULL) {
            skip = true;
        } else {
            /* add the item at the tail */
            do_item_link_cursor(engine, &cursor, ii);
        }
        cb_mutex_exit(&engine->items.lock);

        if (!skip) {
            item_scrub_class(engine, &cursor);
        }
    }

    cb_mutex_enter(&engine->scrubber.lock);
    engine->scrubber.stopped = time(NULL);
    engine->scrubber.running = false;
    cb_mutex_exit(&engine->scrubber.lock);
}
Exemplo n.º 3
0
static void *item_scubber_main(void *arg)
{
    struct default_engine *engine = arg;
    hash_item cursor = { .refcount = 1 };

    for (int ii = 0; ii < POWER_LARGEST; ++ii) {
        pthread_mutex_lock(&engine->cache_lock);
        bool skip = false;
        if (engine->items.heads[ii] == NULL) {
            skip = true;
        } else {
            // add the item at the tail
            do_item_link_cursor(engine, &cursor, ii);
        }
        pthread_mutex_unlock(&engine->cache_lock);

        if (!skip) {
            item_scrub_class(engine, &cursor);
        }
    }

    pthread_mutex_lock(&engine->scrubber.lock);
    engine->scrubber.stopped = time(NULL);
    engine->scrubber.running = false;
    pthread_mutex_unlock(&engine->scrubber.lock);

    return NULL;
}

bool item_start_scrub(struct default_engine *engine)
{
    bool ret = false;
    pthread_mutex_lock(&engine->scrubber.lock);
    if (!engine->scrubber.running) {
        engine->scrubber.started = time(NULL);
        engine->scrubber.stopped = 0;
        engine->scrubber.visited = 0;
        engine->scrubber.cleaned = 0;
        engine->scrubber.running = true;

        pthread_t t;
        pthread_attr_t attr;

        if (pthread_attr_init(&attr) != 0 ||
            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 ||
            pthread_create(&t, &attr, item_scubber_main, engine) != 0)
        {
            engine->scrubber.running = false;
        } else {
            ret = true;
        }
    }
    pthread_mutex_unlock(&engine->scrubber.lock);

    return ret;
}
Exemplo n.º 4
0
static ENGINE_ERROR_CODE do_item_dcp_step(struct default_engine *engine,
                                          struct dcp_connection *connection,
                                          const void *cookie,
                                          struct dcp_message_producers *producers)
{
    ENGINE_ERROR_CODE ret = ENGINE_DISCONNECT;

    while (connection->it == NULL) {
        if (!do_item_walk_cursor(engine, &connection->cursor, 1,
                                 item_dcp_iterfunc, connection, &ret)) {
            /* find next slab class to look at.. */
            bool linked = false;
            int ii;
            for (ii = connection->cursor.slabs_clsid + 1; ii < POWER_LARGEST && !linked;  ++ii) {
                if (engine->items.heads[ii] != NULL) {
                    /* add the item at the tail */
                    do_item_link_cursor(engine, &connection->cursor, ii);
                    linked = true;
                }
            }
            if (!linked) {
                break;
            }
        }
    }

    if (connection->it != NULL) {
        rel_time_t current_time = engine->server.core->get_current_time();
        rel_time_t exptime = connection->it->exptime;

        if (exptime != 0 && exptime < current_time) {
            const hash_key* key = item_get_key(connection->it);
            ret = producers->expiration(cookie, connection->opaque,
                                        hash_key_get_client_key(key),
                                        hash_key_get_client_key_len(key),
                                        item_get_cas(connection->it),
                                        0, 0, 0, NULL, 0);
            if (ret == ENGINE_SUCCESS) {
                do_item_unlink(engine, connection->it);
                do_item_release(engine, connection->it);
            }
        } else {
            ret = producers->mutation(cookie, connection->opaque,
                                      connection->it, 0, 0, 0, 0, NULL, 0, 0);
        }

        if (ret == ENGINE_SUCCESS) {
            connection->it = NULL;
        }
    } else {
        return ENGINE_DISCONNECT;
    }

    return ret;
}
Exemplo n.º 5
0
void link_dcp_walker(struct default_engine *engine,
                     struct dcp_connection *connection)
{
    bool linked = false;
    int ii;
    connection->cursor.refcount = 1;

    /* Link the cursor! */
    for (ii = 0; ii < POWER_LARGEST && !linked; ++ii) {
        cb_mutex_enter(&engine->items.lock);
        if (engine->items.heads[ii] != NULL) {
            /* add the item at the tail */
            do_item_link_cursor(engine, &connection->cursor, ii);
            linked = true;
        }
        cb_mutex_exit(&engine->items.lock);
    }
}
Exemplo n.º 6
0
static tap_event_t do_item_tap_walker(struct default_engine *engine,
                                         const void *cookie, item **itm,
                                         void **es, uint16_t *nes, uint8_t *ttl,
                                         uint16_t *flags, uint32_t *seqno,
                                         uint16_t *vbucket)
{
    ENGINE_ERROR_CODE r;
    struct tap_client *client = engine->server.cookie->get_engine_specific(cookie);
    if (client == NULL) {
        return TAP_DISCONNECT;
    }

    *es = NULL;
    *nes = 0;
    *ttl = (uint8_t)-1;
    *seqno = 0;
    *flags = 0;
    *vbucket = 0;
    client->it = NULL;

    do {
        if (!do_item_walk_cursor(engine, &client->cursor, 1, item_tap_iterfunc, client, &r)) {
            /* find next slab class to look at.. */
            bool linked = false;
            int ii;
            for (ii = client->cursor.slabs_clsid + 1; ii < POWER_LARGEST && !linked;  ++ii) {
                if (engine->items.heads[ii] != NULL) {
                    /* add the item at the tail */
                    do_item_link_cursor(engine, &client->cursor, ii);
                    linked = true;
                }
            }
            if (!linked) {
                break;
            }
        }
    } while (client->it == NULL);
    *itm = client->it;

    return (*itm == NULL) ? TAP_DISCONNECT : TAP_MUTATION;
}