Beispiel #1
0
static void handle_flush_cmd(bloom_conn_handler *handle, char *args, int args_len) {
    
    // If we have a specfic filter, use filt_cmd
    if (args) {
        handle_filt_cmd(handle, args, args_len, filtmgr_flush_filter);
        return;
    }

    // List all the filters
    bloom_filter_list_head *head;
    int res = filtmgr_list_filters(handle->mgr, NULL, &head);
    if (res != 0) {
        INTERNAL_ERROR();
        return;
    }

    // Flush all, ignore errors since
    // filters might get deleted in the process
    bloom_filter_list *node = head->head;
    while (node) {
        filtmgr_flush_filter(handle->mgr, node->filter_name);
        node = node->next;
    }

    // Respond
    handle_client_resp(handle->conn, (char*)DONE_RESP, DONE_RESP_LEN);

    // Cleanup
    filtmgr_cleanup_list(head);
}
Beispiel #2
0
END_TEST

START_TEST(test_mgr_list_prefix)
{
    bloom_config config;
    int res = config_from_filename(NULL, &config);
    fail_unless(res == 0);

    bloom_filtmgr *mgr;
    res = init_filter_manager(&config, 0, &mgr);
    fail_unless(res == 0);

    res = filtmgr_create_filter(mgr, "bar1", NULL);
    fail_unless(res == 0);
    res = filtmgr_create_filter(mgr, "bar2", NULL);
    fail_unless(res == 0);
    res = filtmgr_create_filter(mgr, "zyx", NULL);
    fail_unless(res == 0);

    bloom_filter_list_head *head;
    res = filtmgr_list_filters(mgr, "bar", &head);
    fail_unless(res == 0);
    fail_unless(head->size == 2);

    int has_bar1 = 0;
    int has_bar2 = 0;

    bloom_filter_list *node = head->head;
    while (node) {
        if (strcmp(node->filter_name, "bar1") == 0)
            has_bar1 = 1;
        else if (strcmp(node->filter_name, "bar2") == 0)
            has_bar2 = 1;
        node = node->next;
    }
    fail_unless(has_bar1);
    fail_unless(has_bar2);

    res = filtmgr_drop_filter(mgr, "bar1");
    fail_unless(res == 0);
    res = filtmgr_drop_filter(mgr, "bar2");
    fail_unless(res == 0);
    res = filtmgr_drop_filter(mgr, "zyx");
    fail_unless(res == 0);

    filtmgr_cleanup_list(head);

    res = destroy_filter_manager(mgr);
    fail_unless(res == 0);
}
Beispiel #3
0
static void handle_list_cmd(bloom_conn_handler *handle, char *args, int args_len) {

    // cheat gcc to compile without warnings
    (void)args_len;

    // List all the filters
    bloom_filter_list_head *head;
    int res = filtmgr_list_filters(handle->mgr, args, &head);
    if (res != 0) {
        INTERNAL_ERROR();
        return;
    }

    // Allocate buffers for the responses
    int num_out = (head->size+2);
    char** output_bufs = malloc(num_out * sizeof(char*));
    int* output_bufs_len = malloc(num_out * sizeof(int));

    // Setup the START/END lines
    output_bufs[0] = (char*)&START_RESP;
    output_bufs_len[0] = START_RESP_LEN;
    output_bufs[head->size+1] = (char*)&END_RESP;
    output_bufs_len[head->size+1] = END_RESP_LEN;

    // Generate the responses
    char *resp;
    bloom_filter_list *node = head->head;
    for (int i=0; i < head->size; i++) {
        res = filtmgr_filter_cb(handle->mgr, node->filter_name, list_filter_cb, &resp);
        if (res == 0) {
            output_bufs[i+1] = resp;
            output_bufs_len[i+1] = strlen(resp);
        } else { // Skip this output
            output_bufs[i+1] = NULL;
            output_bufs_len[i+1] = 0;
        }
        node = node->next;
    }

    // Write the response
    send_client_response(handle->conn, output_bufs, output_bufs_len, num_out);

    // Cleanup
    for (int i=1; i <= head->size; i++) if(output_bufs[i]) free(output_bufs[i]);
    free(output_bufs);
    free(output_bufs_len);
    filtmgr_cleanup_list(head);
}
Beispiel #4
0
END_TEST

START_TEST(test_mgr_list_no_filters)
{
    bloom_config config;
    int res = config_from_filename(NULL, &config);
    fail_unless(res == 0);

    bloom_filtmgr *mgr;
    res = init_filter_manager(&config, &mgr);
    fail_unless(res == 0);

    bloom_filter_list_head *head;
    res = filtmgr_list_filters(mgr, &head);
    fail_unless(res == 0);
    fail_unless(head->size == 0);
    filtmgr_cleanup_list(head);

    res = destroy_filter_manager(mgr);
    fail_unless(res == 0);
}
Beispiel #5
0
static void* flush_thread_main(void *in) {
    bloom_config *config;
    bloom_filtmgr *mgr;
    int *should_run;
    UNPACK_ARGS();

    // Perform the initial checkpoint with the manager
    filtmgr_client_checkpoint(mgr);

    syslog(LOG_INFO, "Flush thread started. Interval: %d seconds.", config->flush_interval);
    unsigned int ticks = 0;
    while (*should_run) {
        sleep(1);
        filtmgr_client_checkpoint(mgr);
        if ((++ticks % config->flush_interval) == 0 && *should_run) {
            // List all the filters
            syslog(LOG_INFO, "Scheduled flush started.");
            bloom_filter_list_head *head;
            int res = filtmgr_list_filters(mgr, &head);
            if (res != 0) {
                syslog(LOG_WARNING, "Failed to list filters for flushing!");
                continue;
            }

            // Flush all, ignore errors since
            // filters might get deleted in the process
            bloom_filter_list *node = head->head;
            while (node) {
                filtmgr_flush_filter(mgr, node->filter_name);
                node = node->next;
            }

            // Cleanup
            filtmgr_cleanup_list(head);
        }
    }
    return NULL;
}
Beispiel #6
0
static void handle_get_cmd(bloom_conn_handler *handle, char *args, int args_len) {
    
    #define CHECK_KEY_ERR() { \
        handle_client_err(handle->conn, (char*)&KEY_NEEDED, FILT_KEY_NEEDED_LEN); \
        return; \
    }    

    // If we have no args, complain.
    if (!args) CHECK_KEY_ERR();

    // List all the filters
    bloom_filter_list_head *head;
    int res = filtmgr_list_filters(handle->mgr, NULL, &head);
    if (res != 0) {
        INTERNAL_ERROR();
        return;
    }
    
    // setup list node
    bloom_filter_list *node;

    // Scan all the keys
    char *key = args;
    int key_len = args_len;

    // Parse any options
    char *curr_key = key;
    int index = 0;
    
    // count filters (segmets)
    int filters_count = 0;
    node = head->head;
    while(node) { filters_count++; node = node->next; }
    
    // count keys    
    int keys_count = 1;
    for(int i=0; i<args_len; i++) if(args[i] == ' ') keys_count++;

    // Setup the buffers
    char *key_buf[keys_count];
    char result_buf[keys_count];
    
    // result matrix
    char *key_filter_mat[keys_count][filters_count];
    memset(key_filter_mat, 0, sizeof(key_filter_mat));

    // counter for positive rezults
    int key_filter_len[keys_count];
    memset(key_filter_len, 0, sizeof(key_filter_len));

    node = head->head;
    while(node) {
        
        int j = 0;

        // Check buffer of keys 
        #define REQUEST_BUF() {                                                 \
            int err = filtmgr_check_keys(                                       \
                handle->mgr,                                                    \
                node->filter_name,                                              \
                (char**)&key_buf,                                               \
                index,                                                          \
                (char*)&result_buf);                                            \
            if (err) {                                                          \
                INTERNAL_ERROR();                                               \
                return;                                                         \
            };                                                                  \
            for(int i=0; i<index; i++, j++) {                                   \
                if(result_buf[i] == 1)                                          \
                    key_filter_mat[j][key_filter_len[j]++] = node->filter_name; \
            };                                                                  \
            index = 0;                                                          \
        }
        #define HAS_ANOTHER_KEY() (curr_key && *curr_key != '\0')
        while (HAS_ANOTHER_KEY()) {
            // Adds a zero terminator to the current key, scans forward
            buffer_after_terminator(key, key_len, ' ', &key, &key_len);
            // Set the key
            key_buf[index] = curr_key;
            // Advance to the next key
            curr_key = key;
            // If we have filled the buffer, check now
            if (index++ == MULTI_OP_SIZE) REQUEST_BUF();
        }

        // Handle any remaining keys
        if (index) REQUEST_BUF();
        
        // revert args termintators back to \32 because buffer_affter_terminatoir() changes it
        for(int i=0; i<args_len-1;i++) if(args[i]=='\0') args[i] = ' ';
        
        curr_key = key = args;
        key_len = args_len;
        index = 0;

        node = node->next;
    }

    // collect key names
    char  *key_names[keys_count];
    char **key_names_it = key_names;
    while (HAS_ANOTHER_KEY()) {            
        *(key_names_it++) = key;
        buffer_after_terminator(key, key_len, ' ', &key, &key_len);
        curr_key = key;
    }

    // send key filters
    int buf_len = 1024*1024;
    char *send_buf = (char*) malloc(buf_len);
    
    for(int i=0; i<keys_count; i++) {
        strcat(send_buf, key_names[i]);
        int l = key_filter_len[i]-1;
        char *d = l>=0 ? "\t" : "\n"; 
        strcat(send_buf, d);
        for(int j=0; j<=l; j++) {
            if(j) strcat(send_buf, "/");
            strcat(send_buf, key_filter_mat[i][j]);
        }
        strcat(send_buf, "\n");
    }

    handle_client_resp(handle->conn, send_buf, strlen(send_buf));
    // Respond
    handle_client_resp(handle->conn, (char*)DONE_RESP, DONE_RESP_LEN);

    // Cleanup
    filtmgr_cleanup_list(head);
    free(send_buf);
}