Rework of the server connect so that "hostname" lookup does not occur for
[awesomized/libmemcached] / lib / memcached_hosts.c
1 #include <memcached.h>
2 #include "common.h"
3
4 /* Protoypes (static) */
5 static memcached_return server_add(memcached_st *ptr, char *hostname,
6 unsigned int port,
7 memcached_connection type);
8
9 static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port,
10 memcached_connection type)
11 {
12 memset(host, 0, sizeof(memcached_server_st));
13 host->hostname= new_hostname;
14 host->port= port;
15 host->fd= -1;
16 host->type= type;
17 host->read_ptr= host->read_buffer;
18 }
19
20 memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
21 {
22 unsigned int x;
23 unsigned int count;
24 memcached_server_st *new_host_list;
25
26 if (!list)
27 return MEMCACHED_SUCCESS;
28
29 for (count= 0; list[count].hostname; count++);
30
31 new_host_list=
32 (memcached_server_st *)realloc(ptr->hosts,
33 sizeof(memcached_server_st) * (count + ptr->number_of_hosts + 1));
34
35 if (!new_host_list)
36 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
37
38 ptr->hosts= new_host_list;
39
40 for (x= 0; list[x].hostname; x++)
41 {
42 ptr->hosts[ptr->number_of_hosts].hostname= strdup(list[x].hostname);
43 ptr->hosts[ptr->number_of_hosts].port= list[x].port;
44 ptr->hosts[ptr->number_of_hosts].fd= list[x].fd;
45 ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses;
46 ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active;
47 ptr->hosts[ptr->number_of_hosts].type= list[x].type;
48 ptr->number_of_hosts++;
49 }
50 host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0,
51 MEMCACHED_CONNECTION_UNKNOWN);
52
53 return MEMCACHED_SUCCESS;
54 }
55
56 memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename)
57 {
58 if (!filename)
59 return MEMCACHED_FAILURE;
60
61 return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
62 }
63
64 memcached_return memcached_server_add_udp(memcached_st *ptr,
65 char *hostname,
66 unsigned int port)
67 {
68 if (!port)
69 port= MEMCACHED_DEFAULT_PORT;
70
71 if (!hostname)
72 hostname= "localhost";
73
74 return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_UDP);
75 }
76
77 memcached_return memcached_server_add(memcached_st *ptr,
78 char *hostname,
79 unsigned int port)
80 {
81 if (!port)
82 port= MEMCACHED_DEFAULT_PORT;
83
84 if (!hostname)
85 hostname= "localhost";
86
87 return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP);
88 }
89
90 static memcached_return server_add(memcached_st *ptr, char *hostname,
91 unsigned int port,
92 memcached_connection type)
93 {
94 memcached_server_st *new_host_list;
95 char *new_hostname;
96 LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
97
98
99 if (ptr->number_of_hosts)
100 {
101 new_host_list= (memcached_server_st *)realloc(ptr->hosts,
102 sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
103 if (!new_host_list)
104 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
105 host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0,
106 MEMCACHED_CONNECTION_UNKNOWN);
107 }
108 else
109 {
110 new_host_list=
111 (memcached_server_st *)malloc(sizeof(memcached_server_st) * 2);
112 if (!new_host_list)
113 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
114 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
115 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
116 }
117
118 ptr->hosts= new_host_list;
119
120 new_hostname=
121 (char *)malloc(sizeof(char) * (strlen(hostname)+1));
122
123 if (!new_hostname)
124 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
125
126 memset(new_hostname, 0, strlen(hostname)+1);
127 memcpy(new_hostname, hostname, strlen(hostname));
128 host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port, type);
129 ptr->number_of_hosts++;
130
131 LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
132
133 return MEMCACHED_SUCCESS;
134 }
135
136 memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
137 char *hostname, unsigned int port,
138 memcached_return *error)
139 {
140 unsigned int count;
141 memcached_server_st *new_host_list;
142 char *new_hostname;
143
144 if (!hostname)
145 return ptr;
146
147 if (!port)
148 port= MEMCACHED_DEFAULT_PORT;
149
150 /* Always count so that we keep a free host at the end */
151 if (ptr)
152 {
153 for (count= 0; ptr[count].hostname; count++);
154 count+= 2;
155 new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
156 if (!new_host_list)
157 goto error;
158 host_reset(&new_host_list[count-1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
159 }
160 else
161 {
162 count= 2;
163 new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count);
164 if (!new_host_list)
165 goto error;
166 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
167 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
168 }
169
170 new_hostname= strdup(hostname);
171
172 if (!new_hostname)
173 goto error;
174
175 host_reset(&new_host_list[count-2], new_hostname, port, MEMCACHED_CONNECTION_TCP);
176
177 *error= MEMCACHED_SUCCESS;
178 return new_host_list;
179 error:
180 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
181
182 return NULL;
183 }
184
185 unsigned int memcached_server_list_count(memcached_server_st *ptr)
186 {
187 unsigned int x;
188
189 for (x= 0; ptr[x].hostname; x++);
190
191 return x;
192 }
193
194 void memcached_server_list_free(memcached_server_st *ptr)
195 {
196 unsigned int x;
197
198 for (x= 0; ptr[x].hostname; x++)
199 free(ptr[x].hostname);
200
201 free(ptr);
202 }