Getting everything ready for non-blocking IO.
[awesomized/libmemcached] / lib / memcached_storage.c
1 /*
2 Memcached library
3
4 memcached_set()
5 memcached_replace()
6 memcached_add()
7
8 */
9
10 #include "common.h"
11 #include "memcached_io.h"
12
13 static memcached_return memcached_send(memcached_st *ptr,
14 char *key, size_t key_length,
15 char *value, size_t value_length,
16 time_t expiration,
17 uint16_t flags,
18 char *verb)
19 {
20 size_t write_length;
21 ssize_t sent_length;
22 memcached_return rc;
23 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
24 unsigned int server_key;
25
26 assert(value);
27 assert(value_length);
28
29 memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
30
31 rc= memcached_connect(ptr);
32 if (rc != MEMCACHED_SUCCESS)
33 return rc;
34
35 /* Leaveing this assert in since only a library fubar could blow this */
36 assert(ptr->write_buffer_offset == 0);
37
38 server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
39
40 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
41 "%s %.*s %x %llu %zu\r\n", verb,
42 (int)key_length, key, flags,
43 (unsigned long long)expiration, value_length);
44 if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
45 {
46 rc= MEMCACHED_WRITE_FAILURE;
47 goto error;
48 }
49
50 if ((sent_length= memcached_io_write(ptr, server_key, buffer, write_length)) == -1)
51 {
52 rc= MEMCACHED_WRITE_FAILURE;
53 goto error;
54 }
55
56 /*
57 We have to flush after sending the command. Memcached is not smart enough
58 to just keep reading from the socket :(
59 */
60 if ((sent_length= memcached_io_flush(ptr, server_key)) == -1)
61 return MEMCACHED_WRITE_FAILURE;
62
63 if ((sent_length= memcached_io_write(ptr, server_key, value, value_length)) == -1)
64 {
65 rc= MEMCACHED_WRITE_FAILURE;
66 goto error;
67 }
68
69 if ((sent_length= memcached_io_write(ptr, server_key, "\r\n", 2)) == -1)
70 {
71 rc= MEMCACHED_WRITE_FAILURE;
72 goto error;
73 }
74
75 if ((sent_length= memcached_io_flush(ptr, server_key)) == -1)
76 return MEMCACHED_WRITE_FAILURE;
77
78 rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
79
80 if (rc == MEMCACHED_STORED)
81 return MEMCACHED_SUCCESS;
82 else
83 return rc;
84
85 error:
86 memcached_io_reset(ptr, server_key);
87
88 return rc;
89 }
90
91 memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
92 char *value, size_t value_length,
93 time_t expiration,
94 uint16_t flags)
95 {
96 memcached_return rc;
97 LIBMEMCACHED_MEMCACHED_SET_START();
98 rc= memcached_send(ptr, key, key_length, value, value_length,
99 expiration, flags, "set");
100 LIBMEMCACHED_MEMCACHED_SET_END();
101 return rc;
102 }
103
104 memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length,
105 char *value, size_t value_length,
106 time_t expiration,
107 uint16_t flags)
108 {
109 memcached_return rc;
110 LIBMEMCACHED_MEMCACHED_ADD_START();
111 rc= memcached_send(ptr, key, key_length, value, value_length,
112 expiration, flags, "add");
113 LIBMEMCACHED_MEMCACHED_ADD_END();
114 return rc;
115 }
116
117 memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length,
118 char *value, size_t value_length,
119 time_t expiration,
120 uint16_t flags)
121 {
122 memcached_return rc;
123 LIBMEMCACHED_MEMCACHED_REPLACE_START();
124 rc= memcached_send(ptr, key, key_length, value, value_length,
125 expiration, flags, "replace");
126 LIBMEMCACHED_MEMCACHED_REPLACE_END();
127 return rc;
128 }