Added buffered IO to write calls
[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 assert(ptr->write_buffer_offset == 0);
36
37 server_key= memcached_generate_hash(key, key_length) % ptr->number_of_hosts;
38
39 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
40 "%s %.*s %x %llu %zu\r\n", verb,
41 (int)key_length, key, flags,
42 (unsigned long long)expiration, value_length);
43 if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
44 {
45 rc= MEMCACHED_WRITE_FAILURE;
46 goto error;
47 }
48
49 if ((sent_length= memcached_io_write(ptr, server_key, buffer, write_length)) == -1)
50 {
51 rc= MEMCACHED_WRITE_FAILURE;
52 goto error;
53 }
54 assert(write_length == sent_length);
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 assert(value_length == sent_length);
69
70 if ((sent_length= memcached_io_write(ptr, server_key, "\r\n", 2)) == -1)
71 {
72 rc= MEMCACHED_WRITE_FAILURE;
73 goto error;
74 }
75
76 assert(2 == sent_length);
77
78 if ((sent_length= memcached_io_flush(ptr, server_key)) == -1)
79 return MEMCACHED_WRITE_FAILURE;
80
81 //assert(sent_length == write_length + value_length + 2);
82
83 sent_length= recv(ptr->hosts[server_key].fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 0);
84
85 if (sent_length && buffer[0] == 'S') /* STORED */
86 return MEMCACHED_SUCCESS;
87 else if (write_length && buffer[0] == 'N') /* NOT_STORED */
88 return MEMCACHED_NOTSTORED;
89 else if (write_length && buffer[0] == 'E') /* ERROR */
90 {
91 printf("BUFFER :%s:\n", buffer);
92 return MEMCACHED_PROTOCOL_ERROR;
93 }
94 else
95 return MEMCACHED_READ_FAILURE;
96
97 error:
98 memcached_io_reset(ptr, server_key);
99
100 return rc;
101 }
102
103 memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
104 char *value, size_t value_length,
105 time_t expiration,
106 uint16_t flags)
107 {
108 memcached_return rc;
109 LIBMEMCACHED_MEMCACHED_SET_START();
110 rc= memcached_send(ptr, key, key_length, value, value_length,
111 expiration, flags, "set");
112 LIBMEMCACHED_MEMCACHED_SET_END();
113 return rc;
114 }
115
116 memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length,
117 char *value, size_t value_length,
118 time_t expiration,
119 uint16_t flags)
120 {
121 memcached_return rc;
122 LIBMEMCACHED_MEMCACHED_ADD_START();
123 rc= memcached_send(ptr, key, key_length, value, value_length,
124 expiration, flags, "add");
125 LIBMEMCACHED_MEMCACHED_ADD_END();
126 return rc;
127 }
128
129 memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length,
130 char *value, size_t value_length,
131 time_t expiration,
132 uint16_t flags)
133 {
134 memcached_return rc;
135 LIBMEMCACHED_MEMCACHED_REPLACE_START();
136 rc= memcached_send(ptr, key, key_length, value, value_length,
137 expiration, flags, "replace");
138 LIBMEMCACHED_MEMCACHED_REPLACE_END();
139 return rc;
140 }