2 #include "memcached_io.h"
5 What happens if no servers exist?
7 char *memcached_get(memcached_st
*ptr
, char *key
, size_t key_length
,
10 memcached_return
*error
)
12 return memcached_get_by_key(ptr
, NULL
, 0, key
, key_length
, value_length
,
16 char *memcached_get_by_key(memcached_st
*ptr
,
17 char *master_key
, size_t master_key_length
,
18 char *key
, size_t key_length
,
21 memcached_return
*error
)
26 memcached_return dummy_error
;
29 *error
= memcached_mget_by_key(ptr
,
32 &key
, &key_length
, 1);
34 value
= memcached_fetch(ptr
, NULL
, NULL
,
35 value_length
, flags
, error
);
36 /* This is for historical reasons */
37 if (*error
== MEMCACHED_END
)
38 *error
= MEMCACHED_NOTFOUND
;
42 if (ptr
->get_key_failure
)
46 memcached_result_reset(&ptr
->result
);
47 rc
= ptr
->get_key_failure(ptr
, key
, key_length
, &ptr
->result
);
49 /* On all failure drop to returning NULL */
50 if (rc
== MEMCACHED_SUCCESS
|| rc
== MEMCACHED_BUFFERED
)
52 uint8_t latch
; /* We use latch to track the state of the original socket */
54 if (rc
== MEMCACHED_BUFFERED
)
56 latch
= memcached_behavior_get(ptr
, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
);
58 memcached_behavior_set(ptr
, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
, 1);
61 rc
= memcached_set(ptr
, key
, key_length
,
62 memcached_result_value(&ptr
->result
),
63 memcached_result_length(&ptr
->result
),
64 0, memcached_result_flags(&ptr
->result
));
66 if (rc
== MEMCACHED_BUFFERED
&& latch
== 0)
67 memcached_behavior_set(ptr
, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
, 0);
69 if (rc
== MEMCACHED_SUCCESS
|| rc
== MEMCACHED_BUFFERED
)
72 *value_length
= memcached_result_length(&ptr
->result
);
73 *flags
= memcached_result_flags(&ptr
->result
);
74 return memcached_string_c_copy(&ptr
->result
.value
);
82 (void)memcached_fetch(ptr
, NULL
, NULL
,
83 &dummy_length
, &dummy_flags
,
85 WATCHPOINT_ASSERT(dummy_length
== 0);
90 memcached_return
memcached_mget(memcached_st
*ptr
,
91 char **keys
, size_t *key_length
,
92 unsigned int number_of_keys
)
94 return memcached_mget_by_key(ptr
, NULL
, 0, keys
, key_length
, number_of_keys
);
97 memcached_return
memcached_mget_by_key(memcached_st
*ptr
,
98 char *master_key
, size_t master_key_length
,
99 char **keys
, size_t *key_length
,
100 unsigned int number_of_keys
)
103 memcached_return rc
= MEMCACHED_NOTFOUND
;
104 char *get_command
= "get ";
105 uint8_t get_command_length
= 4;
106 unsigned int master_server_key
= 0;
108 LIBMEMCACHED_MEMCACHED_MGET_START();
109 ptr
->cursor_server
= 0;
111 if (number_of_keys
== 0)
112 return MEMCACHED_NOTFOUND
;
114 if (ptr
->number_of_hosts
== 0)
115 return MEMCACHED_NO_SERVERS
;
117 if ((ptr
->flags
& MEM_VERIFY_KEY
) && (memcachd_key_test(keys
, key_length
, number_of_keys
) == MEMCACHED_BAD_KEY_PROVIDED
))
118 return MEMCACHED_BAD_KEY_PROVIDED
;
120 if (ptr
->flags
& MEM_SUPPORT_CAS
)
122 get_command
= "gets ";
123 get_command_length
= 5;
126 if (master_key
&& master_key_length
)
127 master_server_key
= memcached_generate_hash(ptr
, master_key
, master_key_length
);
130 Here is where we pay for the non-block API. We need to remove any data sitting
131 in the queue before we start our get.
133 It might be optimum to bounce the connection if count > some number.
135 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
137 if (memcached_server_response_count(&ptr
->hosts
[x
]))
139 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
141 if (ptr
->flags
& MEM_NO_BLOCK
)
142 (void)memcached_io_write(&ptr
->hosts
[x
], NULL
, 0, 1);
144 while(memcached_server_response_count(&ptr
->hosts
[x
]))
145 (void)memcached_response(&ptr
->hosts
[x
], buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, &ptr
->result
);
150 If a server fails we warn about errors and start all over with sending keys
153 for (x
= 0; x
< number_of_keys
; x
++)
155 unsigned int server_key
;
157 if (master_server_key
)
158 server_key
= master_server_key
;
160 server_key
= memcached_generate_hash(ptr
, keys
[x
], key_length
[x
]);
162 if (memcached_server_response_count(&ptr
->hosts
[server_key
]) == 0)
164 rc
= memcached_connect(&ptr
->hosts
[server_key
]);
166 if (rc
!= MEMCACHED_SUCCESS
)
169 if ((memcached_io_write(&ptr
->hosts
[server_key
], get_command
, get_command_length
, 0)) == -1)
171 rc
= MEMCACHED_SOME_ERRORS
;
174 WATCHPOINT_ASSERT(ptr
->hosts
[server_key
].cursor_active
== 0);
175 memcached_server_response_increment(&ptr
->hosts
[server_key
]);
176 WATCHPOINT_ASSERT(ptr
->hosts
[server_key
].cursor_active
== 1);
179 if ((memcached_io_write(&ptr
->hosts
[server_key
], keys
[x
], key_length
[x
], 0)) == -1)
181 memcached_server_response_reset(&ptr
->hosts
[server_key
]);
182 rc
= MEMCACHED_SOME_ERRORS
;
186 if ((memcached_io_write(&ptr
->hosts
[server_key
], " ", 1, 0)) == -1)
188 memcached_server_response_reset(&ptr
->hosts
[server_key
]);
189 rc
= MEMCACHED_SOME_ERRORS
;
195 Should we muddle on if some servers are dead?
197 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
199 if (memcached_server_response_count(&ptr
->hosts
[x
]))
201 /* We need to do something about non-connnected hosts in the future */
202 if ((memcached_io_write(&ptr
->hosts
[x
], "\r\n", 2, 1)) == -1)
204 rc
= MEMCACHED_SOME_ERRORS
;
209 LIBMEMCACHED_MEMCACHED_MGET_END();