First version of replication.
[awesomized/libmemcached] / lib / memcached_behavior.c
1 #include "common.h"
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <netinet/tcp.h>
5
6 /*
7 This function is used to modify the behabior of running client.
8
9 We quit all connections so we can reset the sockets.
10 */
11
12 void set_behavior_flag(memcached_st *ptr, memcached_flags temp_flag, void *data)
13 {
14 uint8_t truefalse;
15
16 if (data)
17 truefalse= *(unsigned int *)data;
18 else
19 truefalse= 0;
20
21 if (truefalse)
22 ptr->flags|= temp_flag;
23 else
24 ptr->flags+= temp_flag;
25 }
26
27 memcached_return memcached_behavior_set(memcached_st *ptr,
28 memcached_behavior flag,
29 void *data)
30 {
31 switch (flag)
32 {
33 case MEMCACHED_BEHAVIOR_REPLICAS:
34 {
35 uint8_t number_of_replicas= (uint8_t)data;
36
37 if (number_of_replicas > ptr->number_of_hosts || number_of_replicas == 0 || number_of_replicas > MEMCACHED_MAX_REPLICAS)
38 return MEMCACHED_FAILURE;
39 else
40 ptr->number_of_replicas= number_of_replicas;
41 break;
42 }
43 case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
44 set_behavior_flag(ptr, MEM_SUPPORT_CAS, data);
45 break;
46 case MEMCACHED_BEHAVIOR_NO_BLOCK:
47 set_behavior_flag(ptr, MEM_NO_BLOCK, data);
48 memcached_quit(ptr);
49 case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS:
50 set_behavior_flag(ptr, MEM_BUFFER_REQUESTS, data);
51 memcached_quit(ptr);
52 break;
53 case MEMCACHED_BEHAVIOR_TCP_NODELAY:
54 set_behavior_flag(ptr, MEM_TCP_NODELAY, data);
55 memcached_quit(ptr);
56 break;
57 case MEMCACHED_BEHAVIOR_DISTRIBUTION:
58 ptr->distribution= *(memcached_server_distribution *)(data);
59 break;
60 case MEMCACHED_BEHAVIOR_HASH:
61 ptr->hash= *(memcached_hash *)(data);
62 break;
63 case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS:
64 set_behavior_flag(ptr, MEM_USE_CACHE_LOOKUPS, data);
65 memcached_quit(ptr);
66 break;
67 case MEMCACHED_BEHAVIOR_VERIFY_KEY:
68 set_behavior_flag(ptr, MEM_VERIFY_KEY, data);
69 break;
70 case MEMCACHED_BEHAVIOR_KETAMA:
71 set_behavior_flag(ptr, MEM_USE_KETAMA, data);
72 break;
73 case MEMCACHED_BEHAVIOR_SORT_HOSTS:
74 set_behavior_flag(ptr, MEM_USE_SORT_HOSTS, data);
75 break;
76 case MEMCACHED_BEHAVIOR_USER_DATA:
77 ptr->user_data= data;
78 break;
79 case MEMCACHED_BEHAVIOR_POLL_TIMEOUT:
80 {
81 int32_t timeout= (*((int32_t *)data));
82
83 ptr->poll_timeout= timeout;
84 break;
85 }
86 case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
87 {
88 int32_t timeout= (*((int32_t *)data));
89
90 ptr->connect_timeout= timeout;
91 break;
92 }
93 case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
94 {
95 ptr->send_size= (*((int *)data));
96 memcached_quit(ptr);
97 break;
98 }
99 case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE:
100 {
101 ptr->recv_size= (*((int *)data));
102 memcached_quit(ptr);
103 break;
104 }
105
106
107 }
108
109 return MEMCACHED_SUCCESS;
110 }
111
112 unsigned long long memcached_behavior_get(memcached_st *ptr,
113 memcached_behavior flag)
114 {
115 memcached_flags temp_flag= 0;
116
117 switch (flag)
118 {
119 case MEMCACHED_BEHAVIOR_REPLICAS:
120 return (unsigned long long)ptr->number_of_replicas;
121 case MEMCACHED_BEHAVIOR_SUPPORT_CAS:
122 temp_flag= MEM_SUPPORT_CAS;
123 break;
124 case MEMCACHED_BEHAVIOR_CACHE_LOOKUPS:
125 temp_flag= MEM_USE_CACHE_LOOKUPS;
126 break;
127 case MEMCACHED_BEHAVIOR_NO_BLOCK:
128 temp_flag= MEM_NO_BLOCK;
129 break;
130 case MEMCACHED_BEHAVIOR_BUFFER_REQUESTS:
131 temp_flag= MEM_BUFFER_REQUESTS;
132 break;
133 case MEMCACHED_BEHAVIOR_TCP_NODELAY:
134 temp_flag= MEM_TCP_NODELAY;
135 break;
136 case MEMCACHED_BEHAVIOR_VERIFY_KEY:
137 temp_flag= MEM_VERIFY_KEY;
138 break;
139 case MEMCACHED_BEHAVIOR_DISTRIBUTION:
140 return ptr->distribution;
141 case MEMCACHED_BEHAVIOR_HASH:
142 return ptr->hash;
143 case MEMCACHED_BEHAVIOR_KETAMA:
144 temp_flag= MEM_USE_KETAMA;
145 break;
146 case MEMCACHED_BEHAVIOR_SORT_HOSTS:
147 temp_flag= MEM_USE_SORT_HOSTS;
148 break;
149 case MEMCACHED_BEHAVIOR_USER_DATA:
150 return 0;
151 case MEMCACHED_BEHAVIOR_POLL_TIMEOUT:
152 {
153 return (unsigned long long)ptr->poll_timeout;
154 }
155 case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
156 {
157 return (unsigned long long)ptr->connect_timeout;
158 }
159 case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
160 {
161 int sock_size;
162 socklen_t sock_length= sizeof(int);
163
164 /* REFACTOR */
165 /* We just try the first host, and if it is down we return zero */
166 if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
167 return 0;
168
169 if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
170 SO_SNDBUF, &sock_size, &sock_length))
171 return 0; /* Zero means error */
172
173 return sock_size;
174 }
175 case MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE:
176 {
177 int sock_size;
178 socklen_t sock_length= sizeof(int);
179
180 /* REFACTOR */
181 /* We just try the first host, and if it is down we return zero */
182 if ((memcached_connect(&ptr->hosts[0])) != MEMCACHED_SUCCESS)
183 return 0;
184
185 if (getsockopt(ptr->hosts[0].fd, SOL_SOCKET,
186 SO_RCVBUF, &sock_size, &sock_length))
187 return 0; /* Zero means error */
188
189 return sock_size;
190 }
191 }
192
193 WATCHPOINT_ASSERT(temp_flag); /* Programming mistake if it gets this far */
194 if (ptr->flags & temp_flag)
195 return 1;
196 else
197 return 0;
198
199 return MEMCACHED_SUCCESS;
200 }