static GError * _reload(struct meta0_backend_s *m0, gboolean lazy) { GError *err = NULL; EXTRA_ASSERT(m0 != NULL); GRID_TRACE("%s(%p,lazy=%d)", __FUNCTION__, m0, lazy); g_rw_lock_writer_lock(&(m0->rwlock)); if (!lazy || m0->reload_requested || !m0->array_by_prefix || !m0->array_meta1_ref) { if (m0->array_by_prefix) { meta0_utils_array_clean(m0->array_by_prefix); m0->array_by_prefix = NULL; } if (m0->array_meta1_ref) { meta0_utils_array_meta1ref_clean(m0->array_meta1_ref); m0->array_meta1_ref = NULL; } err = _load(m0); m0->reload_requested = FALSE; if (NULL != err) g_prefix_error(&err, "Loading error: "); } g_rw_lock_writer_unlock(&(m0->rwlock)); return err; }
static GError* _initContext(struct meta0_backend_s *m0) { GError * error; if ( !context ) { context = g_malloc0(sizeof(struct meta0_assign_context_s)); } else { _resetContext(); } error = meta0_backend_get_all(m0,&(context->array_meta1_by_prefix)); if ( error ) { GRID_ERROR("failed to duplicate current prefix distribution :(%d) %s", error->code, error->message); return error; } GPtrArray *meta1_ref; error = meta0_backend_get_all_meta1_ref(m0,&meta1_ref); if ( error ) { meta0_utils_array_meta1ref_clean(meta1_ref); GRID_ERROR("failed to duplicate current Meta1 reference :(%d) %s", error->code, error->message); return error; } context->map_meta1_ref = _meta1ref_array_to_map(meta1_ref); meta0_utils_array_meta1ref_clean(meta1_ref); context->working_map_meta1_ref=g_hash_table_new_full(g_str_hash, g_str_equal,g_free,_gfree_map_meta0_assign_meta1 ); context->treat_prefixes = g_malloc0(8192); context->replica=0; context->avgscore=0; if ( context->array_meta1_by_prefix->len > 0) { gchar **v =context->array_meta1_by_prefix->pdata[0]; if ( v != NULL ) { for (; *v ;v++) context->replica++; if ( context->replica > 65536) { return NEWERROR(EINVAL, "Invalid nb replica [%d]",context->replica); } } GRID_DEBUG("replica %d",context->replica); } return NULL; }
GError* meta0_assign_prefix_to_meta1(struct meta0_backend_s *m0, gchar *ns_name, gboolean nocheck) { // GET meta1 list from conscience GList *working_m1list = NULL; GSList *unref_m1list = NULL; GError *error; GPtrArray *new_meta1ref = NULL; GRID_INFO("START Assign prefix"); error = _initContext(m0); if (error) { goto errorLabel; } // build working list , list sorted by score error = _init_assign(ns_name,&working_m1list,&unref_m1list); if ( error ) { goto errorLabel; } if ( nocheck ) { error =_check(working_m1list); if ( error ) { goto errorLabel; } } error = _assign(working_m1list,unref_m1list); if ( error ) { goto errorLabel; } new_meta1ref = _updated_meta1ref(); error = meta0_backend_assign(m0, context->array_meta1_by_prefix, new_meta1ref,FALSE); if ( error ) { GRID_ERROR("failed to update BDD :(%d) %s", error->code, error->message); goto errorLabel; } context->lastAssignTime=g_date_time_new_now_local(); errorLabel : _resetContext(); if (new_meta1ref) { meta0_utils_array_meta1ref_clean(new_meta1ref); } if (working_m1list) { g_list_free(working_m1list); working_m1list=NULL; } if (unref_m1list) { g_slist_free(unref_m1list); unref_m1list=NULL; } GRID_INFO("END ASSIGN"); return error; }
void meta0_backend_clean(struct meta0_backend_s *m0) { if (!m0) return; oio_str_clean (&m0->ns); oio_str_clean (&m0->id); if (m0->array_by_prefix) meta0_utils_array_clean(m0->array_by_prefix); if (m0->array_meta1_ref) meta0_utils_array_meta1ref_clean(m0->array_meta1_ref); g_rw_lock_clear (&m0->rwlock); g_free(m0); }
GError* meta0_assign_disable_meta1(struct meta0_backend_s *m0, gchar *ns_name, char **m1urls, gboolean nocheck) { GList *working_m1list = NULL; GSList *unref_m1list = NULL; GPtrArray *new_meta1ref = NULL; GError *error; gchar * urls = g_strjoinv(" ",m1urls); GRID_INFO("START disable meta1 %s",urls); g_free(urls); error = _initContext(m0); if (error) goto errorLabel; if ( nocheck ) { error =_check(NULL); if ( error ) goto errorLabel; } error =_unref_meta1(m1urls); if ( error ) goto errorLabel; error = _init_assign(ns_name,&working_m1list,&unref_m1list); if ( error ) goto errorLabel; error = _assign(working_m1list,unref_m1list); if ( error ) goto errorLabel; new_meta1ref = _updated_meta1ref(); error = meta0_backend_assign(m0, context->array_meta1_by_prefix, new_meta1ref ,FALSE); if ( error ) { GRID_ERROR("failed to update BDD :(%d) %s", error->code, error->message); goto errorLabel; } context->lastAssignTime=g_date_time_new_now_local(); errorLabel : _resetContext(); if (new_meta1ref) { meta0_utils_array_meta1ref_clean(new_meta1ref); } if (working_m1list) { g_list_free(working_m1list); working_m1list=NULL; } if (unref_m1list) { g_slist_free(unref_m1list); unref_m1list=NULL; } GRID_INFO("END DISABLE META1"); return error; }
GError* meta0_assign_fill(struct meta0_backend_s *m0, gchar *ns_name, guint replicas, gboolean nodist) { GError *error; GList *working_m1list = NULL; GSList *unref_m1list = NULL; GPtrArray *new_meta1ref = NULL; guint idx; struct meta0_assign_meta1_s *d_aM1; GRID_INFO("START fill meta0 db , replica %d",replicas); error = _initContext(m0); if (error) goto errorLabel; context->replica=replicas; error = _init_assign(ns_name,&working_m1list,&unref_m1list); if ( error ) goto errorLabel; error =_check(NULL); if ( error ) goto errorLabel; while (replicas--) { for (idx=0; idx<65536 ;idx++) { working_m1list=g_list_sort(working_m1list,meta0_assign_sort_by_score); d_aM1 =_select_dest_assign_m1(working_m1list,NULL,(guint8*)(&idx),TRUE, nodist); if ( ! d_aM1 ) { error = NEWERROR(0, "Not enough META1 to meet the requirements (distance, number) (happened at prefix %u)", idx); goto errorLabel; } meta0_utils_array_add(context->array_meta1_by_prefix,(guint8*)(&idx),d_aM1->addr); _increase_score(d_aM1); } } new_meta1ref = _updated_meta1ref(); error = meta0_backend_assign(m0, context->array_meta1_by_prefix, new_meta1ref,TRUE); if ( error ) { GRID_ERROR("failed to update BDD :(%d) %s", error->code, error->message); goto errorLabel; } context->lastAssignTime=g_date_time_new_now_local(); errorLabel : _resetContext(); if (new_meta1ref) { meta0_utils_array_meta1ref_clean(new_meta1ref); } if (working_m1list) { g_list_free(working_m1list); working_m1list=NULL; } if (unref_m1list) { g_slist_free(unref_m1list); unref_m1list=NULL; } GRID_INFO("END FILL"); return error; }