Branch merge.
[awesomized/libmemcached] / lib / memcached_mget.c
1 #include "common.h"
2 #include "memcached_io.h"
3
4 memcached_return memcached_mget(memcached_st *ptr,
5 char **keys, size_t *key_length,
6 unsigned int number_of_keys)
7 {
8 return memcached_mget_by_key(ptr, NULL, 0, keys, key_length, number_of_keys);
9 }
10
11 memcached_return memcached_mget_by_key(memcached_st *ptr,
12 char *master_key, size_t master_key_length,
13 char **keys, size_t *key_length,
14 unsigned int number_of_keys)
15 {
16 unsigned int x;
17 memcached_return rc= MEMCACHED_NOTFOUND;
18 char *get_command= "get ";
19 uint8_t get_command_length= 4;
20 unsigned int master_server_key= 0;
21
22 LIBMEMCACHED_MEMCACHED_MGET_START();
23 ptr->cursor_server= 0;
24
25 if (number_of_keys == 0)
26 return MEMCACHED_NOTFOUND;
27
28 if (ptr->number_of_hosts == 0)
29 return MEMCACHED_NO_SERVERS;
30
31 if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(keys, key_length, number_of_keys) == MEMCACHED_BAD_KEY_PROVIDED))
32 return MEMCACHED_BAD_KEY_PROVIDED;
33
34 if (ptr->flags & MEM_SUPPORT_CAS)
35 {
36 get_command= "gets ";
37 get_command_length= 5;
38 }
39
40 if (master_key && master_key_length)
41 master_server_key= memcached_generate_hash(ptr, master_key, master_key_length);
42
43 /*
44 Here is where we pay for the non-block API. We need to remove any data sitting
45 in the queue before we start our get.
46
47 It might be optimum to bounce the connection if count > some number.
48 */
49 for (x= 0; x < ptr->number_of_hosts; x++)
50 {
51 if (memcached_server_response_count(&ptr->hosts[x]))
52 {
53 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
54
55 if (ptr->flags & MEM_NO_BLOCK)
56 (void)memcached_io_write(&ptr->hosts[x], NULL, 0, 1);
57
58 while(memcached_server_response_count(&ptr->hosts[x]))
59 (void)memcached_response(&ptr->hosts[x], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result);
60 }
61 }
62
63 /*
64 If a server fails we warn about errors and start all over with sending keys
65 to the server.
66 */
67 for (x= 0; x < number_of_keys; x++)
68 {
69 unsigned int server_key;
70
71 if (master_server_key)
72 server_key= master_server_key;
73 else
74 server_key= memcached_generate_hash(ptr, keys[x], key_length[x]);
75
76 if (memcached_server_response_count(&ptr->hosts[server_key]) == 0)
77 {
78 rc= memcached_connect(&ptr->hosts[server_key]);
79
80 if (rc != MEMCACHED_SUCCESS)
81 continue;
82
83 if ((memcached_io_write(&ptr->hosts[server_key], get_command, get_command_length, 0)) == -1)
84 {
85 rc= MEMCACHED_SOME_ERRORS;
86 continue;
87 }
88 WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 0);
89 memcached_server_response_increment(&ptr->hosts[server_key]);
90 WATCHPOINT_ASSERT(ptr->hosts[server_key].cursor_active == 1);
91 }
92
93 if ((memcached_io_write(&ptr->hosts[server_key], keys[x], key_length[x], 0)) == -1)
94 {
95 memcached_server_response_reset(&ptr->hosts[server_key]);
96 rc= MEMCACHED_SOME_ERRORS;
97 continue;
98 }
99
100 if ((memcached_io_write(&ptr->hosts[server_key], " ", 1, 0)) == -1)
101 {
102 memcached_server_response_reset(&ptr->hosts[server_key]);
103 rc= MEMCACHED_SOME_ERRORS;
104 continue;
105 }
106 }
107
108 /*
109 Should we muddle on if some servers are dead?
110 */
111 for (x= 0; x < ptr->number_of_hosts; x++)
112 {
113 if (memcached_server_response_count(&ptr->hosts[x]))
114 {
115 /* We need to do something about non-connnected hosts in the future */
116 if ((memcached_io_write(&ptr->hosts[x], "\r\n", 2, 1)) == -1)
117 {
118 rc= MEMCACHED_SOME_ERRORS;
119 }
120 }
121 }
122
123 LIBMEMCACHED_MEMCACHED_MGET_END();
124 return rc;
125 }