ee48cad317c9781f94d8f1750792386fc25a1bcd
[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 typedef enum {
14 SET_OP,
15 REPLACE_OP,
16 ADD_OP,
17 PREPEND_OP,
18 APPEND_OP,
19 CAS_OP,
20 } memcached_storage_action;
21
22 /* Inline this */
23 char *storage_op_string(memcached_storage_action verb)
24 {
25 switch (verb)
26 {
27 case SET_OP:
28 return "set";
29 case REPLACE_OP:
30 return "replace";
31 case ADD_OP:
32 return "add";
33 case PREPEND_OP:
34 return "prepend";
35 case APPEND_OP:
36 return "append";
37 case CAS_OP:
38 return "cas";
39 };
40
41 return SET_OP;
42 }
43
44 static inline memcached_return memcached_send(memcached_st *ptr,
45 char *key, size_t key_length,
46 char *value, size_t value_length,
47 time_t expiration,
48 uint16_t flags,
49 uint64_t cas,
50 memcached_storage_action verb)
51 {
52 char to_write;
53 size_t write_length;
54 ssize_t sent_length;
55 memcached_return rc;
56 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
57 unsigned int server_key;
58
59 WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
60 WATCHPOINT_ASSERT(!(value && value_length == 0));
61
62 if (key_length == 0)
63 return MEMCACHED_NO_KEY_PROVIDED;
64
65 if (ptr->number_of_hosts == 0)
66 return MEMCACHED_NO_SERVERS;
67
68 server_key= memcached_generate_hash(ptr, key, key_length);
69
70 if (cas)
71 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
72 "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb),
73 (int)key_length, key, flags,
74 (unsigned long long)expiration, value_length,
75 (unsigned long long)cas);
76 else
77 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
78 "%s %.*s %u %llu %zu\r\n", storage_op_string(verb),
79 (int)key_length, key, flags,
80 (unsigned long long)expiration, value_length);
81
82 if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
83 {
84 rc= MEMCACHED_WRITE_FAILURE;
85 goto error;
86 }
87
88 rc= memcached_do(ptr, server_key, buffer, write_length, 0);
89 if (rc != MEMCACHED_SUCCESS)
90 goto error;
91
92 if ((sent_length= memcached_io_write(ptr, server_key, value, value_length, 0)) == -1)
93 {
94 rc= MEMCACHED_WRITE_FAILURE;
95 goto error;
96 }
97
98 if ((ptr->flags & MEM_NO_BLOCK) && verb == SET_OP)
99 to_write= 0;
100 else
101 to_write= 1;
102
103 if ((sent_length= memcached_io_write(ptr, server_key, "\r\n", 2, to_write)) == -1)
104 {
105 memcached_quit_server(ptr, server_key);
106 rc= MEMCACHED_WRITE_FAILURE;
107 goto error;
108 }
109
110 if (to_write == 0)
111 {
112 rc= MEMCACHED_SUCCESS;
113 memcached_server_response_increment(ptr, server_key);
114 }
115 else
116 {
117 rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
118 }
119 if (rc == MEMCACHED_STORED)
120 return MEMCACHED_SUCCESS;
121 else
122 return rc;
123
124 error:
125 memcached_io_reset(ptr, server_key);
126
127 return rc;
128 }
129
130 memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
131 char *value, size_t value_length,
132 time_t expiration,
133 uint16_t flags)
134 {
135 memcached_return rc;
136 LIBMEMCACHED_MEMCACHED_SET_START();
137 rc= memcached_send(ptr, key, key_length, value, value_length,
138 expiration, flags, 0, SET_OP);
139 LIBMEMCACHED_MEMCACHED_SET_END();
140 return rc;
141 }
142
143 memcached_return memcached_add(memcached_st *ptr,
144 char *key, size_t key_length,
145 char *value, size_t value_length,
146 time_t expiration,
147 uint16_t flags)
148 {
149 memcached_return rc;
150 LIBMEMCACHED_MEMCACHED_ADD_START();
151 rc= memcached_send(ptr, key, key_length, value, value_length,
152 expiration, flags, 0, ADD_OP);
153 LIBMEMCACHED_MEMCACHED_ADD_END();
154 return rc;
155 }
156
157 memcached_return memcached_replace(memcached_st *ptr,
158 char *key, size_t key_length,
159 char *value, size_t value_length,
160 time_t expiration,
161 uint16_t flags)
162 {
163 memcached_return rc;
164 LIBMEMCACHED_MEMCACHED_REPLACE_START();
165 rc= memcached_send(ptr, key, key_length, value, value_length,
166 expiration, flags, 0, REPLACE_OP);
167 LIBMEMCACHED_MEMCACHED_REPLACE_END();
168 return rc;
169 }
170
171 memcached_return memcached_prepend(memcached_st *ptr,
172 char *key, size_t key_length,
173 char *value, size_t value_length,
174 time_t expiration,
175 uint16_t flags)
176 {
177 memcached_return rc;
178 rc= memcached_send(ptr, key, key_length, value, value_length,
179 expiration, flags, 0, PREPEND_OP);
180 return rc;
181 }
182
183 memcached_return memcached_append(memcached_st *ptr,
184 char *key, size_t key_length,
185 char *value, size_t value_length,
186 time_t expiration,
187 uint16_t flags)
188 {
189 memcached_return rc;
190 rc= memcached_send(ptr, key, key_length, value, value_length,
191 expiration, flags, 0, APPEND_OP);
192 return rc;
193 }
194
195 memcached_return memcached_cas(memcached_st *ptr,
196 char *key, size_t key_length,
197 char *value, size_t value_length,
198 time_t expiration,
199 uint16_t flags,
200 uint64_t cas)
201 {
202 memcached_return rc;
203 rc= memcached_send(ptr, key, key_length, value, value_length,
204 expiration, flags, cas, APPEND_OP);
205 return rc;
206 }