static ssize_t addrs_count(backend_t *chain, request_t *request){ size_t units; data_t *buffer; data_ctx_t *buffer_ctx; file_userdata *data = ((file_userdata *)chain->userdata); if( (buffer = hash_get_data(request, HK(buffer))) == NULL) return -EINVAL; buffer_ctx = hash_get_data_ctx(request, HK(buffer)); if(hash_find(request, HK(blocks)) == NULL){ if(tree_size(data->tree, &units) != 0) return -EINVAL; }else{ units = tree_blocks_count(data->tree); } data_t dt_units = DATA_PTR_OFFT(&units); return data_transfer( buffer, buffer_ctx, &dt_units, NULL ); }
static ssize_t mphf_configure_any(backend_t *backend, config_t *config, request_t *fork_req){ // {{{ ssize_t ret; uintmax_t fork_only = 0; char *mphf_type_str = NULL; mphf_userdata *userdata = (mphf_userdata *)backend->userdata; hash_data_copy(ret, TYPE_STRINGT, mphf_type_str, config, HK(type)); hash_data_copy(ret, TYPE_UINTT, fork_only, config, HK(fork_only)); hash_data_copy(ret, TYPE_HASHKEYT, userdata->input, config, HK(input)); hash_data_copy(ret, TYPE_HASHKEYT, userdata->output, config, HK(output)); if(fork_only == 1 && fork_req == NULL) return 0; if( (userdata->mphf_proto = mphf_string_to_proto(mphf_type_str)) == NULL) return error("backend mphf parameter mphf_type invalid or not supplied"); memset(&userdata->mphf, 0, sizeof(userdata->mphf)); userdata->mphf.config = config; userdata->broken = 0; if(fork_req == NULL){ if( (ret = userdata->mphf_proto->func_load(&userdata->mphf)) < 0) return ret; }else{ if( (ret = userdata->mphf_proto->func_fork(&userdata->mphf, fork_req)) < 0) return ret; } return 0; } // }}}
ssize_t action_crud_to_fast(void *userdata, request_t *request, f_hash_to_fast callback){ // {{{ ssize_t ret; action_t action; data_t *key; data_t *value; hash_data_get(ret, TYPE_ACTIONT, action, request, HK(action)); if(ret != 0) return ret; key = hash_data_find(request, HK(key)); value = hash_data_find(request, HK(value)); if(key){ data_realholder(ret, key, key); if(ret < 0) return ret; } if(value){ data_realholder(ret, value, value); if(ret < 0) return ret; } fastcall_crud fargs = { { 4, action }, key, value }; ret = callback(userdata, &fargs); return ret; } // }}}
ssize_t action_write_to_fast(void *userdata, request_t *request, f_hash_to_fast callback){ // {{{ ssize_t ret; data_t *r_buffer; data_t *r_size; uintmax_t offset = 0; uintmax_t size = ~0; hash_data_get(ret, TYPE_UINTT, offset, request, HK(offset)); if( (r_size = hash_data_find(request, HK(size))) != NULL){ data_get(ret, TYPE_UINTT, size, r_size); } if( (r_buffer = hash_data_find(request, HK(buffer))) == NULL) return -EINVAL; data_t d_slice = DATA_SLICET(userdata, offset, size); // FIXME fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &d_slice, FORMAT(native) }; ret = data_query(r_buffer, &r_convert); fastcall_write r_write = { { 5, ACTION_WRITE }, 0, &r_convert.transfered, sizeof(r_convert.transfered) }; if(r_size) data_query(r_size, &r_write); return ret; } // }}}
ssize_t action_crud_to_hash(void *userdata, fastcall_crud *fargs, f_fast_to_hash callback){ // {{{ ssize_t ret; request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, hash_null, hash_null, hash_end }; if(fargs->key){ r_next[1].key = HK(key); r_next[1].data = *fargs->key; } if(fargs->value){ r_next[2].key = HK(value); r_next[2].data = *fargs->value; } ret = callback(userdata, r_next); if(fargs->key) *fargs->key = r_next[1].data; if(fargs->value) *fargs->value = r_next[2].data; return ret; } // }}}
static ssize_t data_triplet_format_t_from_config(data_t *data, config_t *config) { // {{{ ssize_t ret; data_t storage; data_t slave; hash_holder_consume(ret, storage, config, HK(data)); if(ret < 0) goto error1; hash_holder_consume(ret, slave, config, HK(slave)); if(ret < 0) goto error2; if( (ret = data_triplet_format_t(data, storage, slave)) < 0) goto error3; return 0; error3: data_free(&slave); error2: data_free(&storage); error1: return ret; } // }}}
static int addrs_configure(backend_t *chain, hash_t *config){ ssize_t ret; DT_UINT32T elements_per_level = 0; DT_UINT32T read_per_calc = READ_PER_CALC_DEFAULT; addrs_userdata *data = (addrs_userdata *)chain->userdata; hash_data_copy(ret, TYPE_UINT32T, elements_per_level, config, HK(perlevel)); hash_data_copy(ret, TYPE_UINT32T, read_per_calc, config, HK(read_size)); if(elements_per_level <= 1) return -EINVAL; // "chain blocks-address variable 'per-level' invalid"); if(read_per_calc < 1) read_per_calc = READ_PER_CALC_DEFAULT; if( (data->tree = tree_alloc(chain, elements_per_level, read_per_calc)) == NULL) return error("chain blocks-address no memory"); if(tree_recalc(data->tree) != 0){ tree_free(data->tree); return error("chain blocks-address tree recalc failed"); } return 0; }
static ssize_t data_length_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ ssize_t ret; length_t *fdata; if(dst->ptr != NULL) return -EINVAL; switch(fargs->format){ case FORMAT(hash):; hash_t *config; data_get(ret, TYPE_HASHT, config, fargs->src); if(ret != 0) return ret; if( (fdata = malloc(sizeof(length_t))) == NULL) return -ENOMEM; hash_holder_consume(ret, fdata->data, config, HK(data)); if(ret != 0){ free(fdata); return -EINVAL; } fdata->format = FORMAT(clean); hash_data_get(ret, TYPE_FORMATT, fdata->format, config, HK(format)); dst->ptr = fdata; return 0; default: break; } return -ENOSYS; } // }}}
ssize_t action_query_to_hash(void *userdata, fastcall_query *fargs, f_fast_to_hash callback){ // {{{ request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(request), DATA_PTR_HASHT( fargs->request ) }, hash_end }; return callback(userdata, r_next); } // }}}
static int call_configure(backend_t *backend, config_t *config){ // {{{ ssize_t ret; call_userdata *userdata = (call_userdata *)backend->userdata; hash_data_copy(ret, TYPE_HASHKEYT, userdata->hk_backend, config, HK(input)); hash_data_copy(ret, TYPE_UINTT, userdata->retry_request, config, HK(retry)); return 0; } // }}}
ssize_t action_resize_to_hash(void *userdata, fastcall_resize *fargs, f_fast_to_hash callback){ // {{{ request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(size), DATA_UINTT( fargs->length ) }, hash_end }; return callback(userdata, r_next); } // }}}
ssize_t action_enum_to_hash(void *userdata, fastcall_enum *fargs, f_fast_to_hash callback){ // {{{ request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(data), *fargs->dest }, hash_end }; return callback(userdata, r_next); } // }}}
static ssize_t data_list_t_convert_to(data_t *src, fastcall_convert_to *fargs){ // {{{ ssize_t ret = 0; ssize_t qret; list_chunk_t *chunk; list_t *fdata = (list_t *)src->ptr; data_t sl_output = DATA_SLIDERT(fargs->dest, 0); switch(fargs->format){ case FORMAT(packed):; for(chunk = fdata->head; chunk; chunk = chunk->cnext){ // remove ref_t from top hash_t r_key[] = { { 0, DATA_HASHKEYT(HK(data)) }, hash_end }; data_t d_key = DATA_PTR_HASHT(r_key); fastcall_control r_control = { { 5, ACTION_CONTROL }, HK(data), &d_key, NULL }; if( (ret = data_query(&chunk->data, &r_control)) < 0) break; data_t d_data = DATA_PTR_DATAT(r_control.value); fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &sl_output, FORMAT(packed) }; ret = data_query(&d_data, &r_convert); data_slider_t_set_offset(&sl_output, r_convert.transfered, SEEK_CUR); if(ret < 0) break; } // terminate list data_t terminator = { TYPE_LISTENDT, NULL }; data_t d_data = DATA_PTR_DATAT(&terminator); fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &sl_output, FORMAT(packed) }; qret = data_query(&d_data, &r_convert); data_slider_t_set_offset(&sl_output, r_convert.transfered, SEEK_CUR); if(qret < 0) ret = qret; break; default: return -ENOSYS; } if(fargs->header.nargs >= 5) fargs->transfered = data_slider_t_get_offset(&sl_output); return ret; } // }}}
static int mphf_init(backend_t *backend){ // {{{ mphf_userdata *userdata = backend->userdata = calloc(1, sizeof(mphf_userdata)); if(userdata == NULL) return error("calloc failed"); userdata->input = HK(key); userdata->output = HK(offset); return 0; } // }}}
static ssize_t try_handler(machine_t *machine, request_t *request){ // {{{ ssize_t ret; data_t freeme; request_t *try_request; try_userdata *userdata = (try_userdata *)machine->userdata; try_threaddata *threaddata = thread_data_get(&userdata->thread_data); threaddata->machine = machine; threaddata->request = request; threaddata->ret = 0; data_set_void(&freeme); if(userdata->request == 0){ try_request = request; }else{ if( (ret = get_hash(hash_data_find(request, userdata->request), &freeme, &try_request)) < 0) return ret; } request_t r_next[] = { { userdata->return_to, DATA_MACHINET(userdata->try_end) }, hash_inline(try_request), hash_end }; fastcall_query r_query = { { 3, ACTION_QUERY }, r_next }; if( (ret = data_query(&userdata->machine, &r_query)) < 0){ if(userdata->request == 0){ request_t r_pass[] = { { HK(ret), DATA_PTR_SIZET(&ret) }, hash_inline(request), hash_end }; threaddata->ret = machine_pass(machine, r_pass); }else{ request_t r_pass[] = { { HK(ret), DATA_PTR_SIZET(&ret) }, hash_inline(try_request), hash_end }; request_t r_next[] = { { HK(ret), DATA_PTR_SIZET(&ret) }, { userdata->request_out, DATA_PTR_HASHT(r_pass) }, hash_inline(request), hash_end }; threaddata->ret = machine_pass(machine, r_next); } } data_free(&freeme); return threaddata->ret; } // }}}
static ssize_t murmur_configure(machine_t *machine, hash_t *config){ // {{{ ssize_t ret; murmur_userdata *userdata = (murmur_userdata *)machine->userdata; hash_data_get(ret, TYPE_HASHKEYT, userdata->input, config, HK(input)); hash_data_get(ret, TYPE_HASHKEYT, userdata->output, config, HK(output)); hash_data_get(ret, TYPE_UINTT, userdata->fatal, config, HK(fatal)); userdata->fatal = ( userdata->fatal == 0 ) ? 0 : 1; return 0; } // }}}
ssize_t action_pop_to_hash(void *userdata, fastcall_pop *fargs, f_fast_to_hash callback){ // {{{ if(fargs->data == NULL) return -EINVAL; request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(data), *fargs->data }, hash_end }; return callback(userdata, r_next); } // }}}
static int tcp_configure(machine_t *machine, hash_t *config){ // {{{ ssize_t ret; tcp_userdata *userdata = (tcp_userdata *)machine->userdata; hash_data_convert(ret, TYPE_STRINGT, userdata->tcp_addr, config, HK(addr)); hash_data_get (ret, TYPE_UINTT, userdata->tcp_port, config, HK(port)); hash_data_get (ret, TYPE_HASHT, userdata->machine, config, HK(machine)); tcp_control_start(machine); return 0; } // }}}
static int hashtable_configure(backend_t *backend, config_t *config){ // {{{ ssize_t ret; hashtable_userdata *userdata = (hashtable_userdata *)backend->userdata; hash_data_copy(ret, TYPE_HASHKEYT, userdata->input, config, HK(input)); hash_data_copy(ret, TYPE_UINTT, userdata->hashtable_size, config, HK(nelements)); if(userdata->hashtable_size == 0) return error("invalid hashtable size"); return 0; } // }}}
static ssize_t allocator_new(allocator_fixed_t **pfdata, hash_t *config){ // {{{ ssize_t ret; data_t *sample; allocator_fixed_t *fdata; if((fdata = calloc(1, sizeof(allocator_fixed_t))) == NULL) return error("calloc failed"); pthread_rwlock_init(&fdata->rwlock, NULL); // get removed items tracker hash_holder_consume(ret, fdata->removed_items, config, HK(removed_items)); hash_holder_consume(ret, fdata->storage, config, HK(storage)); if(ret != 0){ ret = error("invalid storage supplied"); goto error; } hash_data_get(ret, TYPE_UINTT, fdata->item_size, config, HK(item_size)); if(ret != 0){ if( (sample = hash_data_find(config, HK(item_sample))) == NULL){ ret = error("no item_size nor item_sample supplied"); goto error; } fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, FORMAT(binary) }; if( data_query(sample, &r_len) != 0 ){ ret = error("bad item_sample"); goto error; } fdata->item_size = r_len.length; } if(fdata->item_size == 0){ ret = error("bad item size"); goto error; } // get last id fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, FORMAT(clean) }; if( data_query(&fdata->storage, &r_len) != 0){ ret = error("bad underlying storage"); goto error; } fdata->last_id = r_len.length / fdata->item_size; *pfdata = fdata; return 0; error: allocator_destroy(fdata); return ret; } // }}}
static ssize_t morph_configure(machine_t *machine, config_t *config){ // {{{ ssize_t ret; morph_userdata *userdata = (morph_userdata *)machine->userdata; hash_data_get (ret, TYPE_UINTT, userdata->pass_first, config, HK(pass_first)); hash_data_consume(ret, TYPE_HASHT, userdata->machine_config, config, HK(config)); if(ret != 0) return error("HK(config) not supplied"); //userdata->running = 0; // calloc in init already set it return 0; } // }}}
static ssize_t chm_imp_configure (mphf_t *mphf, request_t *config){ // {{{ ssize_t ret; chm_imp_t *data = (chm_imp_t *)&mphf->data; data->nelements_min = CAPACITY_MIN_DEFAULT; data->nelements_step = CAPACITY_STEP_DEFAULT; data->nelements_mul = CAPACITY_MUL_DEFAULT; data->readonly = 0; hash_data_get(ret, TYPE_UINTT, data->nelements_min, config, HK(nelements_min)); hash_data_get(ret, TYPE_UINTT, data->nelements_step, config, HK(nelements_step)); hash_data_get(ret, TYPE_UINTT, data->nelements_mul, config, HK(nelements_mul)); hash_data_get(ret, TYPE_UINTT, data->bt_value, config, HK(value_size)); hash_data_get(ret, TYPE_UINTT, data->readonly, config, HK(readonly)); // run in read-only mode if(data->bt_value > sizeof(uintmax_t)) return error("value_size is too big"); hash_holder_consume(ret, data->be_v, config, HK(data_v)); if(ret != 0) data->readonly = 1; hash_holder_consume(ret, data->be_e, config, HK(data_e)); if(ret != 0) data->readonly = 1; hash_holder_consume(ret, data->be_g, config, HK(data_g)); if(ret != 0) return error("data chm_imp parameter data_g invalid"); return 0; } // }}}
static int lookup_configure(backend_t *backend, config_t *config){ // {{{ ssize_t ret; lookup_userdata *userdata = (lookup_userdata *)backend->userdata; hash_data_copy(ret, TYPE_HASHKEYT, userdata->output, config, HK(output)); hash_data_copy(ret, TYPE_DATATYPET, userdata->output_type, config, HK(output_type)); hash_data_copy(ret, TYPE_UINTT, userdata->fatal, config, HK(fatal)); hash_data_copy(ret, TYPE_UINTT, userdata->force_query, config, HK(force_query)); hash_data_copy(ret, TYPE_BACKENDT, userdata->backend_index, config, HK(index)); if(ret != 0) return error("supplied index backend not valid, or not found"); return 0; } // }}}
static ssize_t data_emitter_t_handler (data_t *data, fastcall_header *hargs) { // {{{ ssize_t ret = 0; emitter_t *fdata = (emitter_t *)data->ptr; switch(hargs->action) { case ACTION_CONVERT_FROM: ; hash_t *parameters; fastcall_convert_from *fargs = (fastcall_convert_from *)hargs; data_get(ret, TYPE_HASHT, parameters, fargs->src); if(ret != 0) return -EINVAL; if(fdata == NULL) { if( (data->ptr = fdata = calloc(1, sizeof(emitter_t))) == NULL) return -ENOMEM; fdata->allocated = 1; } hash_data_consume(ret, TYPE_MACHINET, fdata->machine, parameters, HK(machine)); hash_data_consume(ret, TYPE_HASHT, fdata->request, parameters, HK(request)); if(fdata->machine != NULL && fdata->request != NULL) break; fdata->request = NULL; ret = -EFAULT; // fall case ACTION_FREE: if(fdata == NULL) return -EFAULT; shop_destroy(fdata->machine); hash_free(fdata->request); if(fdata->allocated) free(data->ptr); data->ptr = NULL; break; default: if(fdata == NULL) return -EFAULT; return machine_query(fdata->machine, fdata->request); } return ret; } // }}}
ssize_t action_io_to_hash(void *userdata, fastcall_io *fargs, f_fast_to_hash callback){ // {{{ ssize_t ret; request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(offset), DATA_UINTT( fargs->offset ) }, { HK(buffer), DATA_RAW( fargs->buffer, fargs->buffer_size ) }, { HK(size), DATA_UINTT( fargs->buffer_size ) }, hash_end }; ret = callback(userdata, r_next); fargs->offset = DEREF_TYPE_UINTT(&r_next[1].data); fargs->buffer_size = DEREF_TYPE_UINTT(&r_next[3].data); return ret; } // }}}
ssize_t action_length_to_hash(void *userdata, fastcall_length *fargs, f_fast_to_hash callback){ // {{{ ssize_t ret; format_t format = fargs->format; request_t r_next[] = { { HK(action), DATA_PTR_ACTIONT( &fargs->header.action ) }, { HK(size), DATA_UINTT( fargs->length ) }, { HK(format), DATA_PTR_FORMATT( &format ) }, hash_end }; ret = callback(userdata, r_next); fargs->length = DEREF_TYPE_UINTT(&r_next[1].data); return ret; } // }}}
static ssize_t data_env_t_alloc(data_t *data, fastcall_alloc *hargs){ // {{{ if( (data->ptr = malloc(sizeof(env_t))) == NULL) return -ENOMEM; ((env_t *)data->ptr)->key = HK(input); return 0; } // }}}
static int implode_configure(machine_t *machine, hash_t *config){ // {{{ ssize_t ret; implode_userdata *userdata = (implode_userdata *)machine->userdata; hash_data_get(ret, TYPE_HASHKEYT, userdata->buffer, config, HK(buffer)); return 0; } // }}}
static int null_configure(machine_t *machine, config_t *config){ // {{{ ssize_t ret; null_userdata *userdata = (null_userdata *)machine->userdata; hash_data_get(ret, TYPE_UINTT, userdata->testparam, config, HK(test)); return 0; } // }}}
static ssize_t addrs_set(backend_t *chain, request_t *request){ ssize_t ret; uint32_t r_block_vid, r_block_off, r_block_size, insert = 1; addrs_userdata *data = (addrs_userdata *)chain->userdata; hash_data_copy(ret, TYPE_UINT32T, r_block_size, request, HK(block_size)); if(ret != 0) return error("no block_size supplied"); hash_data_copy(ret, TYPE_UINT32T, r_block_off, request, HK(block_off)); if(ret != 0) insert = 0; hash_data_copy(ret, TYPE_UINT32T, r_block_vid, request, HK(block_vid)); if(ret != 0) r_block_vid = tree_blocks_count(data->tree); if(insert == 0){ return tree_resize_block(data->tree, r_block_vid, r_block_size); } return tree_insert(data->tree, r_block_vid, r_block_off, r_block_size); }