Exemple #1
0
/**
 * Initializer
 * @arg config The configuration
 * @arg vacuum Should vacuuming be enabled. True unless in a
 * test or embedded environment using filtmgr_vacuum()
 * @arg mgr Output, resulting manager.
 * @return 0 on success.
 */
int init_filter_manager(bloom_config *config, int vacuum, bloom_filtmgr **mgr) {
    // Allocate a new object
    bloom_filtmgr *m = *mgr = calloc(1, sizeof(bloom_filtmgr));

    // Copy the config
    m->config = config;

    // Initialize the locks
    pthread_mutex_init(&m->write_lock, NULL);
    INIT_BLOOM_SPIN(&m->clients_lock);
    INIT_BLOOM_SPIN(&m->pending_lock);

    // Allocate storage for the art trees
    art_tree *trees = calloc(2, sizeof(art_tree));
    m->filter_map = trees;
    m->alt_filter_map = trees+1;

    // Allocate the initial art tree
    int res = init_art_tree(m->filter_map);
    if (res) {
        syslog(LOG_ERR, "Failed to allocate filter map!");
        free(m);
        return -1;
    }

    // Discover existing filters
    load_existing_filters(m);

    // Initialize the alternate map
    res = art_copy(m->alt_filter_map, m->filter_map);
    if (res) {
        syslog(LOG_ERR, "Failed to copy filter map to alternate!");
        destroy_filter_manager(m);
        return -1;
    }

    // Start the vacuum thread
    m->should_run = vacuum;
    if (vacuum && pthread_create(&m->vacuum_thread, NULL, filtmgr_thread_main, m)) {
        perror("Failed to start vacuum thread!");
        destroy_filter_manager(m);
        return 1;
    }

    // Done
    return 0;
}
Exemple #2
0
/**
 * Initializes a bloom filter wrapper.
 * @arg config The configuration to use
 * @arg filter_name The name of the filter
 * @arg discover Should existing data files be discovered. Otherwise
 * they will be faulted in on-demand.
 * @arg filter Output parameter, the new filter
 * @return 0 on success
 */
int init_bloom_filter(bloom_config *config, char *filter_name, int discover, bloom_filter **filter) {
    // Allocate the buffers
    bloom_filter *f = *filter = calloc(1, sizeof(bloom_filter));

    // Store the things
    f->config = config;
    f->filter_name = strdup(filter_name);

    // Copy filter configs
    f->filter_config.initial_capacity = config->initial_capacity;
    f->filter_config.capacity = config->initial_capacity;
    f->filter_config.default_probability = config->default_probability;
    f->filter_config.scale_size = config->scale_size;
    f->filter_config.probability_reduction = config->probability_reduction;
    f->filter_config.in_memory = config->in_memory;

    // Get the folder name
    char *folder_name = NULL;
    int res;
    res = asprintf(&folder_name, FILTER_FOLDER_NAME, f->filter_name);
    assert(res != -1);

    // Compute the full path
    f->full_path = join_path(config->data_dir, folder_name);
    free(folder_name);

    // Initialize the locks
    INIT_BLOOM_SPIN(&f->counter_lock);
    pthread_mutex_init(&f->sbf_lock, NULL);

    // Try to create the folder path
    res = mkdir(f->full_path, 0755);
    if (res && errno != EEXIST) {
        syslog(LOG_ERR, "Failed to create filter directory '%s'. Err: %d [%d]", f->full_path, res, errno);
        return res;
    }

    // Read in the filter_config
    char *config_name = join_path(f->full_path, (char*)CONFIG_FILENAME);
    res = filter_config_from_filename(config_name, &f->filter_config);
    free(config_name);
    if (res && res != -ENOENT) {
        syslog(LOG_ERR, "Failed to read filter '%s' configuration. Err: %d [%d]", f->filter_name, res, errno);
        return res;
    }

    // Discover the existing filters if we need to
    res = 0;
    if (discover) {
        res = thread_safe_fault(f);
        if (res) {
            syslog(LOG_ERR, "Failed to fault in the filter '%s'. Err: %d", f->filter_name, res);
        }
    }

    // Trigger a flush on first instantiation. This will create
    // a new ini file for first time filters.
    if (!res) {
        res = bloomf_flush(f);
    }

    return res;
}