* Added additional HASHing methods of FNV1_64,FNV1A_64, FNV1_32, FNV1A_32
* Added pkgconfig support
* Fixed conflict with defined type in MySQL
+ * Added memcached_result_st structure and functions to manipulate it.
0.7 Tue Oct 30 09:24:05 PDT 2007
* Poved to poll() from select()
memcached_get.3: memcached_get.pod\r
pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_get.3\r
\r
+memcached_fetch_result.3: memcached_get.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_fetch_result.3\r
+\r
memcached_mget.3: memcached_get.pod\r
pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_mget.3\r
\r
memcached_stat_get_keys.3: memcached_stats.pod\r
pod2man -c "libmemcached" -r "" -s 3 memcached_stats.pod > memcached_stat_get_keys.3\r
\r
+memcached_result_st.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_st.3\r
+\r
+memcached_result_create.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_create.3\r
+\r
+memcached_result_free.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_free.3\r
+\r
+memcached_result_key_value.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_key_value.3\r
+\r
+memcached_result_key_length.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_key_length.3\r
+\r
+memcached_result_value.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_value.3\r
+\r
+memcached_result_length.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_length.3\r
+\r
+memcached_result_flags.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_flags.3\r
+\r
+memcached_result_cas.3: memcached_result_st.pod\r
+ pod2man -c "libmemcached" -r "" -s 3 memcached_result_st.pod > memcached_result_cas.3\r
+\r
memcp.1: memcp.pod\r
pod2man -c "libmemcached" -r "" -s 1 memcp.pod > memcp.1\r
\r
=head1 SEE ALSO
-memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3) memcached_server_add_unix_socket(3)
-
+memcached(1) libmemcached_examples(3) libmemcached(1) memcat(1) memcp(1) memflush(1) memrm(1) memslap(1) memstat(1) memcached_fetch(3) memcached_replace(3) memcached_server_list_free(3) libmemcached_examples(3) memcached_clone(3) memcached_free(3) memcached_server_add(3) memcached_server_push(3) memcached_add(3) memcached_get(3) memcached_server_count(3) memcached_servers_parse(3) memcached_create(3) memcached_increment(3) memcached_server_list(3) memcached_set(3) memcached_decrement(3) memcached_mget(3) memcached_server_list_append(3) memcached_strerror(3) memcached_delete(3) memcached_quit(3) memcached_server_list_count(3) memcached_verbosity(3) memcached_server_add_unix_socket(3) memcahed_result_create(3) memcached_result_free(3) memcached_result_key_value(3) memcached_result_key_length(3) memcached_result_value(3) memcached_result_length(3) memcached_result_flags(3) memcached_result_cas(3) memcached_result_st(3)
=cut
#include <memcached.h>
+ memcached_result_st *
+ memcached_fetch_result(memcached_st *ptr,
+ memcached_result_st *result,
+ memcached_return *error);
+
char *memcached_get (memcached_st *ptr,
char *key, size_t key_length,
size_t *value_length,
memcached_return pointer to hold any error. The object will be returned
upon success and NULL will be returned on failure.
+memcached_fetch_result() is used to return a memcached_result_st(3) structure
+from a memcached server. The result object is forward compatible with changes
+to the server. For more information please refer to the memcached_result_st(3)
+help. This function will dynamically allocate a result structure for you
+if you do not pass one to the function.
+
=head1 RETURN
All objects returned must be freed by the calling application.
--- /dev/null
+=head1 NAME
+
+memcahed_result_create, memcached_result_free,
+memcached_result_key_value, memcached_result_key_length,
+memcached_result_value, memcached_result_length,
+memcached_result_flags, memcached_result_cas
+
+
+=head1 LIBRARY
+
+C Client Library for memcached (libmemcached, -lmemcached)
+
+=head1 SYNOPSIS
+
+ #include <memcached.h>
+
+ memcached_result_st *memcached_result_create(memcached_st *ptr,
+ memcached_result_st *result);
+
+ void memcached_result_free(memcached_result_st *result);
+
+ char * memcached_result_key_value(memcached_result_st *result);
+
+ size_t memcached_result_key_length(memcached_result_st *result);
+
+ char *memcached_result_value(memcached_result_st *ptr);
+
+ size_t memcached_result_length(memcached_result_st *ptr);
+
+ uint16_t memcached_result_flags(memcached_result_st *result)
+
+ uint64_t memcached_result_cas(memcached_result_st *result);
+
+=head1 DESCRIPTION
+
+libmemcached(3) can optionally return a memcached_result_st which acts as a
+result object. The result objects have added benefits over the character
+pointer returns in that they are forward compatible with new return items
+that future memcached servers may implement (the best currect example of
+this is the CAS return iteam). The structures can also be reused which will
+save on calls to malloc(3). It is suggested that you use result objects over
+char * return functions.
+
+The structure of memcached_result_st has been encapsulated, you should not
+write code to directly access members of the structure.
+
+memcached_result_create() will either allocate memory for a
+memcached_result_st or will initialize a structure passed to it.
+
+memcached_result_free() will deallocate any memory attached to the
+structure. If the structure was also alloacted, it will deallocate it.
+
+memcached_result_key_value() returns the key value associated with the
+current result object.
+
+memcached_result_key_length() returns the key length associated with the
+current result object.
+
+memcached_result_value() returns the result value associated with the
+current result object.
+
+memcached_result_length() returns the result length associated with the
+current result object.
+
+memcached_result_flags() returns the flags associated with the
+current result object.
+
+memcached_result_cas() returns the cas associated with the
+current result object. This value will only be available if the server
+supports it.
+
+
+=head1 RETURN
+
+Varies, see particular functions. All structures must have
+memcached_result_free() called on them for cleanup purposes. Failure to
+do this will result in leaked memory.
+
+=head1 HOME
+
+To find out more information please check:
+L<http://tangent.org/552/libmemcached.html>
+
+=head1 AUTHOR
+
+Brian Aker, E<lt>brian@tangent.orgE<gt>
+
+=head1 SEE ALSO
+
+memcached(1) libmemcached(3) memcached_strerror(3)
+
+=cut
+
struct memcached_result_st {
memcached_allocated is_allocated;
memcached_st *root;
- memcached_string_st key;
+ char key[MEMCACHED_MAX_KEY];
+ size_t key_length;
memcached_string_st value;
uint16_t flags;
uint64_t cas;
char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
size_t *value_length, uint16_t *flags,
memcached_return *error);
-memcached_result_st *memcached_fetch_object(memcached_st *ptr, memcached_return *error);
+memcached_result_st *memcached_fetch_result(memcached_st *ptr,
+ memcached_result_st *result,
+ memcached_return *error);
/* Server Public functions */
#define memcached_server_count(A) A->number_of_hosts
memcached_return *error);
/* Result Struct */
-#define memcache_result_key_value(A) memcached_string_value(A->key)
-#define memcache_result_key_length(A) memcached_string_length(A->key)
-#define memcache_result_result_value(A) memcached_string_value(A->value)
-#define memcache_result_result_length(A) memcached_string_length(A->value)
-#define memcache_result_flags(A) A->flags
-#define memcache_result_cas(A) A->cas
+void memcached_result_free(memcached_result_st *result);
+memcached_result_st *memcached_result_create(memcached_st *ptr,
+ memcached_result_st *result);
+#define memcached_result_key_value(A) A->key
+#define memcached_result_key_length(A) A->key_length
+#ifdef FIX
+#define memcached_result_value(A) memcached_string_value(A->value)
+#define memcached_result_length(A) memcached_string_length(A->value)
+#else
+char *memcached_result_value(memcached_result_st *ptr);
+size_t memcached_result_length(memcached_result_st *ptr);
+#endif
+#define memcached_result_flags(A) A->flags
+#define memcached_result_cas(A) A->cas
+
/* Some personal debugging functions */
#ifdef HAVE_DEBUG
memcached_return memcached_string_reset(memcached_string_st *string);
void memcached_string_free(memcached_string_st *string);
-/* Result Struct */
-#define memcache_result_key_value(A) memcached_string_value(A->key)
-#define memcache_result_key_length(A) memcached_string_length(A->key)
-#define memcache_result_result_value(A) memcached_string_value(A->value)
-#define memcache_result_result_length(A) memcached_string_length(A->value)
-#define memcache_result_flags(A) A->flags
-#define memcache_result_cas(A) A->cas
-
-memcached_result_st *memcached_result_create(memcached_st *ptr,
- memcached_result_st *result);
-void memcached_result_free(memcached_result_st *result);
-
#endif /* __COMMON_H__ */
else if (*error == MEMCACHED_END)
{
WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
+ return NULL;
}
else if (*error != MEMCACHED_SUCCESS)
return NULL;
return NULL;
}
-#ifdef NOT_YET
-char *memcached_fetch_result(memcached_st *ptr, memcached_result_st *result,
- memcached_return *error)
+memcached_result_st *memcached_fetch_result(memcached_st *ptr,
+ memcached_result_st *result,
+ memcached_return *error)
{
- char *value_check;
+ if (result == NULL)
+ result= memcached_result_create(ptr, NULL);
while (ptr->cursor_server < ptr->number_of_hosts)
{
continue;
}
- value_check= memcached_value_fetch(ptr, key, key_length, value_length, flags,
- error, 1, ptr->cursor_server);
+ *error= memcached_value_fetch(ptr, result->key, &result->key_length,
+ &result->value,
+ &result->flags,
+ 1, ptr->cursor_server);
if (*error == MEMCACHED_NOTFOUND)
ptr->cursor_server++;
- else if (*error == MEMCACHED_END && *value_length == 0)
+ else if (*error == MEMCACHED_END && memcached_string_length((memcached_string_st *)(&result->value)) == 0)
return NULL;
else if (*error == MEMCACHED_END)
{
WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */
+ return NULL;
}
else if (*error != MEMCACHED_SUCCESS)
return NULL;
else
- return value_check;
+ return result;
}
- *value_length= 0;
return NULL;
}
-#endif
return MEMCACHED_SUCCESS;
}
+
+char *memcached_result_value(memcached_result_st *ptr)
+{
+ memcached_string_st *sptr= &ptr->value;
+ return memcached_string_value(sptr);
+}
+
+size_t memcached_result_length(memcached_result_st *ptr)
+{
+ memcached_string_st *sptr= &ptr->value;
+ return memcached_string_length(sptr);
+}
--- /dev/null
+/*
+ memcached_result_st are used to internally represent the return values from
+ memcached. We use a structure so that long term as identifiers are added
+ to memcached we will be able to absorb new attributes without having
+ to addjust the entire API.
+*/
+#include "common.h"
+
+memcached_result_st *memcached_result_create(memcached_st *memc,
+ memcached_result_st *ptr)
+{
+ /* Saving malloc calls :) */
+ if (ptr)
+ {
+ memset(ptr, 0, sizeof(memcached_result_st));
+ ptr->is_allocated= MEMCACHED_NOT_ALLOCATED;
+ }
+ else
+ {
+ ptr= (memcached_result_st *)malloc(sizeof(memcached_result_st));
+ if (!ptr)
+ return NULL;
+ memset(ptr, 0, sizeof(memcached_result_st));
+ ptr->is_allocated= MEMCACHED_ALLOCATED;
+ }
+
+ ptr->root= memc;
+ memcached_string_create(memc, &ptr->value, 0);
+ WATCHPOINT_ASSERT(ptr->value.string == NULL);
+ WATCHPOINT_ASSERT(ptr->value.is_allocated == MEMCACHED_NOT_ALLOCATED);
+
+ return ptr;
+}
+
+void memcached_result_free(memcached_result_st *ptr)
+{
+ memcached_string_free(&ptr->value);
+
+ if (ptr->is_allocated == MEMCACHED_ALLOCATED)
+ free(ptr);
+}
assert(rc == MEMCACHED_SUCCESS);
}
+void mget_result_test(memcached_st *memc)
+{
+ memcached_return rc;
+ char *keys[]= {"fudge", "son", "food"};
+ size_t key_length[]= {5, 3, 4};
+ unsigned int x;
+
+ memcached_result_st results_obj;
+ memcached_result_st *results;
+
+ results= memcached_result_create(memc, &results_obj);
+ assert(results);
+ assert(&results_obj == results);
+
+ /* We need to empty the server before continueing test */
+ rc= memcached_flush(memc, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ rc= memcached_mget(memc, keys, key_length, 3);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
+ {
+ assert(results);
+ }
+ while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
+ assert(!results);
+ assert(rc == MEMCACHED_NOTFOUND);
+
+ for (x= 0; x < 3; x++)
+ {
+ rc= memcached_set(memc, keys[x], key_length[x],
+ keys[x], key_length[x],
+ (time_t)50, (uint16_t)9);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ rc= memcached_mget(memc, keys, key_length, 3);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ while ((results= memcached_fetch_result(memc, &results_obj, &rc)))
+ {
+ assert(results);
+ assert(&results_obj == results);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(memcached_result_key_length(results) == memcached_result_length(results));
+ assert(!memcmp(memcached_result_key_value(results),
+ memcached_result_value(results),
+ memcached_result_length(results)));
+ }
+
+ WATCHPOINT;
+ memcached_result_free(&results_obj);
+ WATCHPOINT;
+}
+
+void mget_result_alloc_test(memcached_st *memc)
+{
+ memcached_return rc;
+ char *keys[]= {"fudge", "son", "food"};
+ size_t key_length[]= {5, 3, 4};
+ unsigned int x;
+
+ memcached_result_st *results;
+
+ /* We need to empty the server before continueing test */
+ rc= memcached_flush(memc, 0);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ rc= memcached_mget(memc, keys, key_length, 3);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ while ((results= memcached_fetch_result(memc, NULL, &rc)) != NULL)
+ {
+ assert(results);
+ }
+ assert(!results);
+ assert(rc == MEMCACHED_NOTFOUND);
+
+ for (x= 0; x < 3; x++)
+ {
+ rc= memcached_set(memc, keys[x], key_length[x],
+ keys[x], key_length[x],
+ (time_t)50, (uint16_t)9);
+ assert(rc == MEMCACHED_SUCCESS);
+ }
+
+ rc= memcached_mget(memc, keys, key_length, 3);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ x= 0;
+ while ((results= memcached_fetch_result(memc, NULL, &rc)))
+ {
+ assert(results);
+ assert(rc == MEMCACHED_SUCCESS);
+ assert(memcached_result_key_length(results) == memcached_result_length(results));
+ assert(!memcmp(memcached_result_key_value(results),
+ memcached_result_value(results),
+ memcached_result_length(results)));
+ memcached_result_free(results);
+ x++;
+ }
+}
+
void mget_test(memcached_st *memc)
{
memcached_return rc;
{"increment", 0, increment_test },
{"decrement", 0, decrement_test },
{"quit", 0, quit_test },
- {"mget", 0, mget_test },
+ {"mget", 1, mget_test },
+ {"mget_result", 1, mget_result_test },
+ {"mget_result_alloc", 1, mget_result_alloc_test },
{"get_stats", 0, get_stats },
{"add_host_test", 0, add_host_test },
{"get_stats_keys", 0, get_stats_keys },