~brianaker/libmemcached/embedded

« back to all changes in this revision

Viewing changes to lib/memcached_hosts.c

  • Committer: brian@gir-2.local
  • Date: 2008-03-10 15:04:41 UTC
  • mto: (317.6.1)
  • mto: This revision was merged to the branch mainline in revision 321.
  • Revision ID: brian@gir-2.local-20080310150441-jyhbjx6bwo46f6tg
Huge refactoring of directory structure.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#define MEMCACHED_WHEEL_SIZE 1024
10
 
#define MEMCACHED_STRIDE 4
11
 
static void rebalance_wheel(memcached_st *ptr)
12
 
{
13
 
  unsigned int x;
14
 
  unsigned int y;
15
 
  unsigned int latch;
16
 
 
17
 
  /* Seed the Wheel */
18
 
  memset(ptr->wheel, 0, sizeof(unsigned int) * MEMCACHED_WHEEL_SIZE);
19
 
 
20
 
  for (latch= y= x= 0; x < MEMCACHED_WHEEL_SIZE; x++, latch++)
21
 
  {
22
 
    if (latch == MEMCACHED_STRIDE)
23
 
    {
24
 
      y++;
25
 
      if (y == ptr->number_of_hosts)
26
 
        y= 0;
27
 
      latch= 0;
28
 
    }
29
 
 
30
 
    ptr->wheel[x]= y;
31
 
  }
32
 
}
33
 
 
34
 
static int compare_servers(const void *p1, const void *p2)
35
 
{
36
 
  int return_value;
37
 
  memcached_server_st *a= (memcached_server_st *)p1;
38
 
  memcached_server_st *b= (memcached_server_st *)p2;
39
 
 
40
 
  return_value= strcmp(a->hostname, b->hostname);
41
 
 
42
 
  if (return_value == 0)
43
 
  {
44
 
    if (a->port > b->port)
45
 
      return_value++;
46
 
    else
47
 
      return_value--;
48
 
  }
49
 
 
50
 
  return return_value;
51
 
}
52
 
 
53
 
static void host_reset(memcached_st *ptr, memcached_server_st *host, 
54
 
                       char *hostname, unsigned int port,
55
 
                       memcached_connection type)
56
 
{
57
 
  memset(host,  0, sizeof(memcached_server_st));
58
 
  strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
59
 
  host->root= ptr ? ptr : NULL;
60
 
  host->port= port;
61
 
  host->fd= -1;
62
 
  host->type= type;
63
 
  host->read_ptr= host->read_buffer;
64
 
  if (ptr)
65
 
    host->next_retry= ptr->retry_timeout;
66
 
  host->sockaddr_inited= MEMCACHED_NOT_ALLOCATED;
67
 
}
68
 
 
69
 
void server_list_free(memcached_st *ptr, memcached_server_st *servers)
70
 
{
71
 
  unsigned int x;
72
 
 
73
 
  if (servers == NULL)
74
 
    return;
75
 
 
76
 
  for (x= 0; x < servers->count; x++)
77
 
    if (servers[x].address_info)
78
 
      freeaddrinfo(servers[x].address_info);
79
 
 
80
 
  if (ptr && ptr->call_free)
81
 
    ptr->call_free(ptr, servers);
82
 
  else
83
 
    free(servers);
84
 
}
85
 
 
86
 
memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
87
 
{
88
 
  unsigned int x;
89
 
  uint16_t count;
90
 
  memcached_server_st *new_host_list;
91
 
 
92
 
  if (!list)
93
 
    return MEMCACHED_SUCCESS;
94
 
 
95
 
  count= list[0].count;
96
 
 
97
 
  if (ptr->call_realloc)
98
 
    new_host_list= 
99
 
      (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, 
100
 
                                               sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
101
 
  else
102
 
    new_host_list= 
103
 
      (memcached_server_st *)realloc(ptr->hosts, 
104
 
                                     sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
105
 
 
106
 
  if (!new_host_list)
107
 
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
108
 
 
109
 
  ptr->hosts= new_host_list;
110
 
                                   
111
 
  for (x= 0; x < count; x++)
112
 
  {
113
 
    WATCHPOINT_ASSERT(list[x].hostname[0] != 0);
114
 
    host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname, 
115
 
               list[x].port, list[x].type);
116
 
    ptr->number_of_hosts++;
117
 
  }
118
 
  ptr->hosts[0].count= ptr->number_of_hosts;
119
 
 
120
 
  if (ptr->number_of_hosts > 1)
121
 
    qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers);
122
 
 
123
 
  rebalance_wheel(ptr);
124
 
 
125
 
  return MEMCACHED_SUCCESS;
126
 
}
127
 
 
128
 
memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename)
129
 
{
130
 
  if (!filename)
131
 
    return MEMCACHED_FAILURE;
132
 
 
133
 
  return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
134
 
}
135
 
 
136
 
memcached_return memcached_server_add_udp(memcached_st *ptr, 
137
 
                                          char *hostname,
138
 
                                          unsigned int port)
139
 
{
140
 
  if (!port)
141
 
    port= MEMCACHED_DEFAULT_PORT; 
142
 
 
143
 
  if (!hostname)
144
 
    hostname= "localhost"; 
145
 
 
146
 
  return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_UDP);
147
 
}
148
 
 
149
 
memcached_return memcached_server_add(memcached_st *ptr, 
150
 
                                      char *hostname, 
151
 
                                      unsigned int port)
152
 
{
153
 
  if (!port)
154
 
    port= MEMCACHED_DEFAULT_PORT; 
155
 
 
156
 
  if (!hostname)
157
 
    hostname= "localhost"; 
158
 
 
159
 
  return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP);
160
 
}
161
 
 
162
 
static memcached_return server_add(memcached_st *ptr, char *hostname, 
163
 
                                   unsigned int port,
164
 
                                   memcached_connection type)
165
 
{
166
 
  memcached_server_st *new_host_list;
167
 
  LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
168
 
 
169
 
 
170
 
  if (ptr->call_realloc)
171
 
    new_host_list= (memcached_server_st *)ptr->call_realloc(ptr, ptr->hosts, 
172
 
                                                            sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
173
 
  else
174
 
    new_host_list= (memcached_server_st *)realloc(ptr->hosts, 
175
 
                                                  sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
176
 
  if (new_host_list == NULL)
177
 
    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
178
 
 
179
 
  ptr->hosts= new_host_list;
180
 
 
181
 
  host_reset(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, type);
182
 
  ptr->number_of_hosts++;
183
 
  ptr->hosts[0].count++;
184
 
 
185
 
  if (ptr->number_of_hosts > 1)
186
 
    qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers);
187
 
 
188
 
  rebalance_wheel(ptr);
189
 
 
190
 
  LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
191
 
 
192
 
  return MEMCACHED_SUCCESS;
193
 
}
194
 
 
195
 
memcached_server_st *memcached_server_list_append(memcached_server_st *ptr, 
196
 
                                                  char *hostname, unsigned int port, 
197
 
                                                  memcached_return *error)
198
 
{
199
 
  unsigned int count;
200
 
  memcached_server_st *new_host_list;
201
 
 
202
 
  if (hostname == NULL || error == NULL)
203
 
    return NULL;
204
 
 
205
 
  if (!port)
206
 
    port= MEMCACHED_DEFAULT_PORT; 
207
 
 
208
 
  /* Increment count for hosts */
209
 
  count= 1;
210
 
  if (ptr != NULL)
211
 
  {
212
 
    count+= ptr[0].count;
213
 
  } 
214
 
 
215
 
  new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
216
 
  if (!new_host_list)
217
 
  {
218
 
    *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
219
 
    return NULL;
220
 
  }
221
 
 
222
 
  host_reset(NULL, &new_host_list[count-1], hostname, port, MEMCACHED_CONNECTION_TCP);
223
 
 
224
 
  /* Backwards compatibility hack */
225
 
  new_host_list[0].count++;
226
 
 
227
 
  count= new_host_list[0].count;
228
 
 
229
 
  if (new_host_list[0].count > 1)
230
 
    qsort(new_host_list, count, sizeof(memcached_server_st), compare_servers);
231
 
 
232
 
  new_host_list[0].count= count;
233
 
 
234
 
 
235
 
  *error= MEMCACHED_SUCCESS;
236
 
  return new_host_list;
237
 
}
238
 
 
239
 
unsigned int memcached_server_list_count(memcached_server_st *ptr)
240
 
{
241
 
  if (ptr == NULL)
242
 
    return 0;
243
 
 
244
 
  return ptr[0].count;
245
 
}
246
 
 
247
 
void memcached_server_list_free(memcached_server_st *ptr)
248
 
{
249
 
  server_list_free(NULL, ptr);
250
 
}