/* ------------------------------------------------------------------------- */ static gboolean _is_usable_meta0(addr_info_t *m0addr, GSList *exclude) { GSList *l = NULL; for (l = exclude; l && l->data; l=l->next) { if(addr_info_equal(l->data, m0addr)) return FALSE; } return TRUE; }
static GError* _unref_meta1(gchar **urls) { GError *error = NULL; GSList *prefixByMeta1 = meta0_utils_array_to_list(context->array_meta1_by_prefix); guint8 *prefix_mask = g_malloc0(8192); for(;*urls;urls++) { addr_info_t addr; GRID_DEBUG("unref url %s",*urls); grid_string_to_addrinfo(*urls,NULL,&addr); GSList *l=prefixByMeta1; for (;l;l=l->next) { struct meta0_info_s *m0info; if (!(m0info = l->data)) continue; if (addr_info_equal(&(m0info->addr),&addr)) { guint16 *p, *max; p = (guint16*) m0info->prefixes; max = (guint16*) (m0info->prefixes + m0info->prefixes_size); for (; p<max; p++) { if (_is_treat_prefix(prefix_mask,(guint8*)p) ) { GRID_WARN("prefix %02X%02X manage by two meta1 present in the request",((guint8*)p)[0],((guint8*)p)[1]); error = NEWERROR(0, "prefix %02X%02X manage by two meta1 present in the request",((guint8*)p)[0],((guint8*)p)[1]); goto errorLabel; } _treat_prefix(prefix_mask,(guint8*)p); } } } struct meta0_assign_meta1_s *aM1=NULL; aM1=g_hash_table_lookup(context->map_meta1_ref,*urls); if( !aM1) { aM1 = g_malloc0(sizeof(struct meta0_assign_meta1_s)); aM1->addr=g_strdup(*urls); aM1->score=0; aM1->used=FALSE; g_hash_table_insert(context->map_meta1_ref,strdup(*urls),aM1); } else { aM1->used=FALSE; } } errorLabel : meta0_utils_list_clean(prefixByMeta1); g_free(prefix_mask); return error; }
gboolean service_info_equal(const struct service_info_s * si1, const struct service_info_s * si2) { if (si1 == si2) return TRUE; if (si1 == NULL || si2 == NULL) return FALSE; return addr_info_equal(&(si1->addr), &(si2->addr)) && !strcmp(si1->ns_name, si2->ns_name) && !strcmp(si1->type, si2->type); }
static gboolean _is_rawx_in_garbage(service_info_t *rawx, GSList *garbage) { /* ensure service not in garbage */ GSList *r = NULL; for(r = garbage; r && r->data; r = r->next) { if(addr_info_equal(&(rawx->addr), &(((service_info_t*)r->data)->addr))) { return TRUE; } } return FALSE; }
static guint8* _cache_from_m0l(GSList *l, const struct addr_info_s *ai) { guint8 *result; result = g_malloc0(8192); for (; l ;l=l->next) { struct meta0_info_s *m0info; if (!(m0info = l->data)) continue; if (addr_info_equal(&(m0info->addr), ai)) { guint16 *p, *max; p = (guint16*) m0info->prefixes; max = (guint16*) (m0info->prefixes + m0info->prefixes_size); for (; p<max ;p++) _cache_manage(result, (guint8*)p); } } return result; }
static GError * _init_assign(gchar *ns_name, GList **working_m1list,GSList **unref_m1list) { GError *error = NULL; GSList *m1_list = NULL; m1_list = list_namespace_services(ns_name, "meta1", &error); if (!m1_list) { if ( error) { GRID_ERROR("failed to init meta1 service list :(%d) %s", error->code, error->message); goto errorLabel; } } GRID_INFO("nb m1 cs %d",g_slist_length(m1_list)); if ( context->replica > g_slist_length(m1_list)) { GRID_ERROR("Number of meta1 services [%d] less than number of replication [%d]",g_slist_length(m1_list),context->replica); error = NEWERROR(EINVAL, "Number of meta1 services [%d] less than number of replication [%d]",g_slist_length(m1_list),context->replica); goto errorLabel; } if ( context->replica <= 0 ) { GRID_ERROR("Invalid replica number [%d]",context->replica); error = NEWERROR(EINVAL, "Invalid replica number [%d]",context->replica); goto errorLabel; } // Duplicate the current prefix distribution and build a List GSList *prefixByMeta1 = meta0_utils_array_to_list(context->array_meta1_by_prefix); GSList *l=NULL; for (;m1_list;m1_list=m1_list->next) { struct meta0_assign_meta1_s *aM1; struct service_info_s *sInfo; gchar url[128]; url[0] = '\0'; aM1 = g_malloc0(sizeof(struct meta0_assign_meta1_s)); sInfo=m1_list->data; grid_addrinfo_to_string(&(sInfo->addr), url, sizeof(url)); aM1->addr=g_strdup(url); aM1->score=0; aM1->available=FALSE; aM1->used=TRUE; l = prefixByMeta1; for (;l;l=l->next) { struct meta0_info_s *m0info; if (!(m0info = l->data)) continue; if (addr_info_equal(&(m0info->addr),&(sInfo->addr))) { guint16 *p, *max; guint i=0; GArray *pfx = g_array_new(FALSE, FALSE, 2); p = (guint16*) m0info->prefixes; max = (guint16*) (m0info->prefixes + m0info->prefixes_size); for (; p<max; p++) { i++; pfx=g_array_append_vals(pfx,(guint8*)p,1); } aM1->assignPrefixes=pfx; aM1->score=i; GRID_DEBUG("aM1 %s , score %d",aM1->addr,aM1->score); prefixByMeta1=g_slist_remove(prefixByMeta1,m0info); meta0_info_clean(m0info); break; } } struct meta0_assign_meta1_s *m1ref = g_hash_table_lookup(context->map_meta1_ref,aM1->addr); if ( m1ref && !m1ref->used) { // unref meta1 aM1->used=FALSE; if (aM1->score != 0 ) { // meta1 refer always prefixe *unref_m1list=g_slist_prepend(*unref_m1list,aM1); } } else { *working_m1list = g_list_prepend(*working_m1list,aM1); } g_hash_table_insert(context->working_map_meta1_ref,strdup(aM1->addr),aM1); } GRID_TRACE("len working %d, len reste pref %d",g_list_length(*working_m1list),g_slist_length(prefixByMeta1)); guint nb_M1 = g_list_length(*working_m1list) + g_slist_length(prefixByMeta1); //defined the average assign score if (nb_M1 == 0 ) { GRID_ERROR("No Meta1 available"); error = NEWERROR(0, "No Meta1 service available"); goto errorLabel; } context->avgscore = (65536* context->replica)/nb_M1; GRID_DEBUG("average meta1 score %d",context->avgscore); GList *work = g_list_first(*working_m1list); for (;work;work=work->next) { struct meta0_assign_meta1_s *aM1 = work->data; if ( aM1->score > context->avgscore) { aM1->available=TRUE; } } GRID_DEBUG("init meta1 list, find %d meta1",g_list_length(*working_m1list)); GRID_DEBUG("init unref meta1 list, find %d meta1",g_slist_length(*unref_m1list)); meta0_utils_list_clean(prefixByMeta1); errorLabel : if (m1_list) { g_slist_foreach(m1_list, service_info_gclean, NULL); g_slist_free(m1_list); } return error; }