X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=lib%2Fmemcached_hosts.c;h=de006dd6794b6b5125583e24dfa2bd10e5786d78;hb=8a86b578acc594d37a8638e3e0afba1286c4b6ca;hp=5661e541180fdcb64a0e1b0d8cd433f59b322bfc;hpb=a670410588e5815f1cf5c7c78ca0f53f8bbff5b0;p=m6w6%2Flibmemcached diff --git a/lib/memcached_hosts.c b/lib/memcached_hosts.c index 5661e541..de006dd6 100644 --- a/lib/memcached_hosts.c +++ b/lib/memcached_hosts.c @@ -13,9 +13,6 @@ static void rebalance_wheel(memcached_st *ptr) unsigned int x; unsigned int y; unsigned int latch; - unsigned int range; - - range= (MEMCACHED_WHEEL_SIZE / ptr->number_of_hosts); /* Seed the Wheel */ memset(ptr->wheel, 0, sizeof(unsigned int) * MEMCACHED_WHEEL_SIZE); @@ -34,19 +31,56 @@ static void rebalance_wheel(memcached_st *ptr) } } -static void host_reset(memcached_server_st *host, char *hostname, unsigned int port, +static int compare_servers(const void *p1, const void *p2) +{ + int return_value; + memcached_server_st *a= (memcached_server_st *)p1; + memcached_server_st *b= (memcached_server_st *)p2; + + return_value= strcmp(a->hostname, b->hostname); + + if (return_value == 0) + { + if (a->port > b->port) + return_value++; + else + return_value--; + } + + return return_value; +} + +static void host_reset(memcached_st *ptr, memcached_server_st *host, + char *hostname, unsigned int port, memcached_connection type) { memset(host, 0, sizeof(memcached_server_st)); strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1); + host->root= ptr ? ptr : NULL; host->port= port; host->fd= -1; host->type= type; host->read_ptr= host->read_buffer; - host->write_ptr= host->write_buffer; host->sockaddr_inited= MEMCACHED_NOT_ALLOCATED; } +void server_list_free(memcached_st *ptr, memcached_server_st *servers) +{ + unsigned int x; + + if (servers == NULL) + return; + + for (x= 0; x < servers->count; x++) + if (servers[x].address_info) + freeaddrinfo(servers[x].address_info); + + if (ptr && ptr->call_free) + ptr->call_free(ptr, servers); + else + free(servers); +} + memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list) { unsigned int x; @@ -58,9 +92,14 @@ memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *l count= list[0].count; - new_host_list= - (memcached_server_st *)realloc(ptr->hosts, - sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); + if (ptr->call_realloc) + new_host_list= + (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, + sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); + else + new_host_list= + (memcached_server_st *)realloc(ptr->hosts, + sizeof(memcached_server_st) * (count + ptr->number_of_hosts)); if (!new_host_list) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; @@ -70,12 +109,15 @@ memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *l for (x= 0; x < count; x++) { WATCHPOINT_ASSERT(list[x].hostname[0] != 0); - host_reset(&ptr->hosts[ptr->number_of_hosts], list[x].hostname, + host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, list[x].port, list[x].type); ptr->number_of_hosts++; } ptr->hosts[0].count= ptr->number_of_hosts; + if (ptr->number_of_hosts > 1) + qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); + rebalance_wheel(ptr); return MEMCACHED_SUCCESS; @@ -123,17 +165,24 @@ static memcached_return server_add(memcached_st *ptr, char *hostname, LIBMEMCACHED_MEMCACHED_SERVER_ADD_START(); - new_host_list= (memcached_server_st *)realloc(ptr->hosts, - sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); - if (!new_host_list) + if (ptr->call_realloc) + new_host_list= (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, + sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); + else + new_host_list= (memcached_server_st *)realloc(ptr->hosts, + sizeof(memcached_server_st) * (ptr->number_of_hosts+1)); + if (new_host_list == NULL) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; ptr->hosts= new_host_list; - host_reset(&ptr->hosts[ptr->number_of_hosts], hostname, port, type); + host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, type); ptr->number_of_hosts++; ptr->hosts[0].count++; + if (ptr->number_of_hosts > 1) + qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers); + rebalance_wheel(ptr); LIBMEMCACHED_MEMCACHED_SERVER_ADD_END(); @@ -148,8 +197,8 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, unsigned int count; memcached_server_st *new_host_list; - if (!hostname) - return ptr; + if (hostname == NULL || error == NULL) + return NULL; if (!port) port= MEMCACHED_DEFAULT_PORT; @@ -168,9 +217,18 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, return NULL; } - host_reset(&new_host_list[count-1], hostname, port, MEMCACHED_CONNECTION_TCP); + host_reset(NULL, &new_host_list[count-1], hostname, port, MEMCACHED_CONNECTION_TCP); + + /* Backwards compatibility hack */ new_host_list[0].count++; + count= new_host_list[0].count; + + if (new_host_list[0].count > 1) + qsort(new_host_list, count, sizeof(memcached_server_st), compare_servers); + + new_host_list[0].count= count; + *error= MEMCACHED_SUCCESS; return new_host_list; @@ -186,14 +244,5 @@ unsigned int memcached_server_list_count(memcached_server_st *ptr) void memcached_server_list_free(memcached_server_st *ptr) { - unsigned int x; - - if (ptr == NULL) - return; - - for (x= 0; x < ptr->count; x++) - if (ptr[x].address_info) - freeaddrinfo(ptr[x].address_info); - - free(ptr); + server_list_free(NULL, ptr); }