Adding Tim
[awesomized/libmemcached] / libmemcached / 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
12 /* Inline this */
13 static char *storage_op_string(memcached_storage_action verb)
14 {
15 switch (verb)
16 {
17 case SET_OP:
18 return "set";
19 case REPLACE_OP:
20 return "replace";
21 case ADD_OP:
22 return "add";
23 case PREPEND_OP:
24 return "prepend";
25 case APPEND_OP:
26 return "append";
27 case CAS_OP:
28 return "cas";
29 };
30
31 return SET_OP;
32 }
33
34 memcached_return memcached_send(memcached_st *ptr,
35 char *master_key, size_t master_key_length,
36 char *key, size_t key_length,
37 char *value, size_t value_length,
38 time_t expiration,
39 uint32_t flags,
40 uint64_t cas,
41 memcached_storage_action verb)
42 {
43 char to_write;
44 size_t write_length;
45 ssize_t sent_length;
46 memcached_return rc;
47 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
48 unsigned int server_key;
49
50 WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
51 WATCHPOINT_ASSERT(!(value && value_length == 0));
52
53 unlikely (key_length == 0)
54 return MEMCACHED_NO_KEY_PROVIDED;
55
56 unlikely (ptr->number_of_hosts == 0)
57 return MEMCACHED_NO_SERVERS;
58
59 if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test(&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
60 return MEMCACHED_BAD_KEY_PROVIDED;
61
62 server_key= memcached_generate_hash(ptr, master_key, master_key_length);
63
64 if (cas)
65 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
66 "%s %.*s %u %llu %zu %llu\r\n", storage_op_string(verb),
67 (int)key_length, key, flags,
68 (unsigned long long)expiration, value_length,
69 (unsigned long long)cas);
70 else
71 write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
72 "%s %.*s %u %llu %zu\r\n", storage_op_string(verb),
73 (int)key_length, key, flags,
74 (unsigned long long)expiration, value_length);
75
76 if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
77 {
78 rc= MEMCACHED_WRITE_FAILURE;
79 goto error;
80 }
81
82 rc= memcached_do(&ptr->hosts[server_key], buffer, write_length, 0);
83 if (rc != MEMCACHED_SUCCESS)
84 goto error;
85
86 if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1)
87 {
88 rc= MEMCACHED_WRITE_FAILURE;
89 goto error;
90 }
91
92 if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP)
93 to_write= 0;
94 else
95 to_write= 1;
96
97 if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
98 {
99 rc= MEMCACHED_WRITE_FAILURE;
100 goto error;
101 }
102
103 if (to_write == 0)
104 return MEMCACHED_BUFFERED;
105
106 rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
107
108 if (rc == MEMCACHED_STORED)
109 return MEMCACHED_SUCCESS;
110 else
111 return rc;
112
113 error:
114 memcached_io_reset(&ptr->hosts[server_key]);
115
116 return rc;
117 }