75e44d0ca76450d62bd0cc8e2a93dd25aa129452
[awesomized/libmemcached] / libmemcached / memcached_server.c
1 /*
2 This is a partial implementation for fetching/creating memcached_server_st objects.
3 */
4 #include "common.h"
5
6 memcached_server_st *memcached_server_create(memcached_st *memc, memcached_server_st *ptr)
7 {
8 if (ptr == NULL)
9 {
10 ptr= (memcached_server_st *)malloc(sizeof(memcached_server_st));
11
12 if (!ptr)
13 return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */
14
15 memset(ptr, 0, sizeof(memcached_server_st));
16 ptr->is_allocated= true;
17 }
18 else
19 memset(ptr, 0, sizeof(memcached_server_st));
20
21 ptr->root= memc;
22
23 return ptr;
24 }
25
26 memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_server_st *host,
27 const char *hostname, unsigned int port,
28 uint32_t weight, memcached_connection type)
29 {
30 host= memcached_server_create(memc, host);
31
32 if (host == NULL)
33 return NULL;
34
35 strncpy(host->hostname, hostname, MEMCACHED_MAX_HOST_LENGTH - 1);
36 host->root= memc ? memc : NULL;
37 host->port= port;
38 host->weight= weight;
39 host->fd= -1;
40 host->type= type;
41 host->read_ptr= host->read_buffer;
42 if (memc)
43 host->next_retry= memc->retry_timeout;
44
45 return host;
46 }
47
48 void memcached_server_free(memcached_server_st *ptr)
49 {
50 memcached_quit_server(ptr, 0);
51
52 if (ptr->address_info)
53 {
54 freeaddrinfo(ptr->address_info);
55 ptr->address_info= NULL;
56 }
57
58 if (ptr->is_allocated)
59 {
60 if (ptr->root && ptr->root->call_free)
61 ptr->root->call_free(ptr->root, ptr);
62 else
63 free(ptr);
64 }
65 else
66 memset(ptr, 0, sizeof(memcached_server_st));
67 }
68
69 /*
70 If we do not have a valid object to clone from, we toss an error.
71 */
72 memcached_server_st *memcached_server_clone(memcached_server_st *clone, memcached_server_st *ptr)
73 {
74 /* We just do a normal create if ptr is missing */
75 if (ptr == NULL)
76 return NULL;
77
78 /* TODO We should check return type */
79 return memcached_server_create_with(ptr->root, clone,
80 ptr->hostname, ptr->port, ptr->weight,
81 ptr->type);
82 }
83
84 memcached_return memcached_server_cursor(memcached_st *ptr,
85 memcached_server_function *callback,
86 void *context,
87 unsigned int number_of_callbacks)
88 {
89 unsigned int y;
90
91 for (y= 0; y < ptr->number_of_hosts; y++)
92 {
93 unsigned int x;
94
95 for (x= 0; x < number_of_callbacks; x++)
96 {
97 unsigned int iferror;
98
99 iferror= (*callback[x])(ptr, &ptr->hosts[y], context);
100
101 if (iferror)
102 continue;
103 }
104 }
105
106 return MEMCACHED_SUCCESS;
107 }
108
109 memcached_server_st *memcached_server_by_key(memcached_st *ptr, const char *key, size_t key_length, memcached_return *error)
110 {
111 uint32_t server_key;
112
113 unlikely (key_length == 0)
114 {
115 *error= MEMCACHED_NO_KEY_PROVIDED;
116 return NULL;
117 }
118
119 unlikely (ptr->number_of_hosts == 0)
120 {
121 *error= MEMCACHED_NO_SERVERS;
122 return NULL;
123 }
124
125 if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test((char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
126 {
127 *error= MEMCACHED_BAD_KEY_PROVIDED;
128 return NULL;
129 }
130
131 server_key= memcached_generate_hash(ptr, key, key_length);
132
133 return memcached_server_clone(NULL, &ptr->hosts[server_key]);
134
135 }