NEw code for the memcached_fetch_execute() function.
authorBrian Aker <brian@tangent.org>
Sat, 22 Dec 2007 01:00:28 +0000 (17:00 -0800)
committerBrian Aker <brian@tangent.org>
Sat, 22 Dec 2007 01:00:28 +0000 (17:00 -0800)
Callbacks are in the house :)

ChangeLog
docs/Makefile.am
docs/libmemcached.pod
docs/memcached_get.pod
include/memcached.h
lib/Makefile.am
lib/memcached_fetch.c
lib/memcached_fetch_execute.c [new file with mode: 0644]
support/libmemcached.spec.in
tests/function.c

index 094b807db4975ce4d5029ca0fd4239bd88ce8293..68671ae4b0896c9c445e29f25d9befc663fd7cb4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,7 +6,8 @@
   * Added multi delete functions.
   * All get key returns have C style null termination
   * If memcached_server_list_append is passed NULLs instead of pointers it
-    returns NULL.
+    returns NULL.  
+  * Added memcached_fetch_execute() method
 
 0.12 Tue Dec 11 15:20:55 PST 2007
   * Updates for consistent hashing
index bfcf66eeac8ae259799cc71dbc28cf6d79b52cfe..f92f77f95caa37b7de07d509806eeda4f6eb1bb1 100644 (file)
@@ -46,6 +46,7 @@ man_MANS = libmemcached.3\
        memcached_delete.3\\r
        memcached_delete_by_key.3\\r
        memcached_fetch.3\\r
+       memcached_fetch_execute.3\\r
        memcached_fetch_result.3\\r
        memcached_free.3\\r
        memcached_get.3\\r
@@ -150,6 +151,9 @@ memcached_get_by_key.3: memcached_get.pod
 memcached_fetch_result.3: memcached_get.pod\r
        pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_fetch_result.3\r
 \r
+memcached_fetch_execute.3: memcached_get.pod\r
+       pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_fetch_execute.3\r
+\r
 memcached_mget.3: memcached_get.pod\r
        pod2man -c "libmemcached" -r "" -s 3 memcached_get.pod > memcached_mget.3\r
 \r
index c46ad1579c789cc61d78b0e572aafb82443ed9b8..9a0626d190b5a3bab398f2dcbaeae2864693b41d 100755 (executable)
@@ -73,7 +73,7 @@ Brian Aker, E<lt>brian@tangent.orgE<gt>
 
 =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) 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) memcached_append(3) memcached_prepend(3) memcached_fetch_result(3) memerror(1) memcached_get_by_key(3) memcached_mget_by_key(3) memcached_delete_by_key(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) memcached_append(3) memcached_prepend(3) memcached_fetch_result(3) memerror(1) memcached_get_by_key(3) memcached_mget_by_key(3) memcached_delete_by_key(3) memcached_fetch_execute(3)
 
 =cut
 
index 111a3b614d381234ea0527aefb4da701d7222433..f2f2033c33f0e9018af348c89c49d07ea08c6611 100755 (executable)
@@ -44,6 +44,12 @@ C Client Library for memcached (libmemcached, -lmemcached)
                          size_t *value_length,
                          uint16_t *flags, 
                          memcached_return *error);
+  memcached_return 
+  memcached_fetch_execute(memcached_st *ptr, 
+                          unsigned int (*callback[])(memcached_st *ptr, memcached_result_st *result, void *context),
+                          void *context,
+                          unsigned int number_of_callbacks
+                         )
 
 =head1 DESCRIPTION
 
@@ -80,6 +86,14 @@ 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.
 
+memcached_fetch_execute() is a callback function for result sets. Instead
+of returning the results to you for processing, it passes each of the
+result sets to the list of functions you provide. It passes to the function
+a memcached_st that can be cloned for use in called the cluster (it can not 
+be used directly). It also passed a result set which does not need to be freed.
+Finally it passes a "context". This is just a pointer to a memory reference
+you supply the calling function. 
+
 memcached_get_by_key() and memcached_mget_by_key() behave in a similar nature
 as memcached_get() and memcached_mget(). The difference is that they take
 a master key that is used for determining which server an object was stored
index 666e9e6b9898223d051fadbe75eeb1b2ce02cdb2..1cbdcf683ae1e0e298d0a25d249078f5f2e38303 100644 (file)
@@ -373,6 +373,12 @@ memcached_return memcached_mdelete_by_key(memcached_st *ptr,
                                           unsigned int number_of_keys,
                                           time_t expiration);
 
+memcached_return memcached_fetch_execute(memcached_st *ptr, 
+                                             unsigned int (*callback[])(memcached_st *ptr, memcached_result_st *result, void *context),
+                                             void *context,
+                                             unsigned int number_of_callbacks
+                                             );
+
 /* Result Struct */
 void memcached_result_free(memcached_result_st *result);
 memcached_result_st *memcached_result_create(memcached_st *ptr, 
index 0c632f0d09caa14920bf6343039cca2a98ef14c4..38c6e8f4e255fc6cd2378602b7495722b0a6cfe2 100644 (file)
@@ -34,6 +34,7 @@ libmemcached_la_SOURCES = crc.c \
                          memcached_delete.c \
                          memcached_do.c \
                          memcached_fetch.c \
+                         memcached_fetch_execute.c \
                          memcached_flush.c \
                          memcached_get.c \
                          memcached_hash.c \
index 257bfbc45245119d7bdbb0a25712089a10712e44..f88ff02b83b6f5de3ba5b02b058fe81afa67cbf1 100644 (file)
@@ -6,7 +6,7 @@ memcached_return value_fetch(memcached_st *ptr,
                              memcached_result_st *result,
                              unsigned int server_key)
 {
-  memcached_return rc;
+  memcached_return rc= MEMCACHED_SUCCESS;
   char *string_ptr;
   char *end_ptr;
   char *next_ptr;
diff --git a/lib/memcached_fetch_execute.c b/lib/memcached_fetch_execute.c
new file mode 100644 (file)
index 0000000..c1245d4
--- /dev/null
@@ -0,0 +1,48 @@
+#include "common.h"
+
+memcached_return memcached_fetch_execute(memcached_st *ptr, 
+                                             unsigned int (*callback[])(memcached_st *ptr, memcached_result_st *result, void *context),
+                                             void *context,
+                                             unsigned int number_of_callbacks
+                                             )
+{
+  memcached_result_st *result= &ptr->result;
+
+  while (ptr->cursor_server < ptr->number_of_hosts)
+  {
+    memcached_return rc;
+
+    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+    if (memcached_server_response_count(ptr, ptr->cursor_server) == 0)
+    {
+      ptr->cursor_server++;
+      continue;
+    }
+
+    rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, result, ptr->cursor_server);
+
+    if (rc == MEMCACHED_END) /* END means that we move on to the next */
+    {
+      memcached_server_response_reset(ptr, ptr->cursor_server);
+      ptr->cursor_server++;
+      continue;
+    }
+    else if (rc == MEMCACHED_SUCCESS)
+    {
+      unsigned int x;
+
+      for (x= 0; x < number_of_callbacks; x++)
+      {
+        unsigned int iferror;
+
+        iferror= (*callback[x])(ptr, result, context);
+
+        if (iferror)
+          continue;
+      }
+    }
+  }
+
+  return MEMCACHED_SUCCESS;
+}
index 13340f42945d41ec90b69f4f6c4368a5674c9153..1d72454c4b4c06694928185cd6a33cb861a991d7 100644 (file)
@@ -81,6 +81,7 @@ memerror - Creates human readable messages from libmemecached error codes.
 %{_mandir}/man3/memcached_delete_by_key.3.gz
 %{_mandir}/man3/memcached_fetch.3.gz
 %{_mandir}/man3/memcached_fetch_result.3.gz
+%{_mandir}/man3/memcached_fetch_execute.3.gz
 %{_mandir}/man3/memcached_free.3.gz
 %{_mandir}/man3/memcached_get.3.gz
 %{_mandir}/man3/memcached_get_by_key.3.gz
index 3b1e6d450feafcf0457c2065b94a7eb811c8881b..54bbceaabc409d355841f034d631834aa92e9bd7 100644 (file)
@@ -777,6 +777,47 @@ uint8_t mget_result_alloc_test(memcached_st *memc)
   return 0;
 }
 
+/* Count the results */
+unsigned int callback_counter(memcached_st *ptr, memcached_result_st *result, void *context)
+{
+  unsigned int *counter= (unsigned int *)context;
+
+  *counter= *counter + 1;
+
+  return 0;
+}
+
+uint8_t mget_result_function(memcached_st *memc)
+{
+  memcached_return rc;
+  char *keys[]= {"fudge", "son", "food"};
+  size_t key_length[]= {5, 3, 4};
+  unsigned int x;
+  unsigned int counter;
+  unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+
+  /* We need to empty the server before continueing test */
+  rc= memcached_flush(memc, 0);
+  for (x= 0; x < 3; x++)
+  {
+    rc= memcached_set(memc, keys[x], key_length[x], 
+                      keys[x], key_length[x],
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS);
+  }
+
+  rc= memcached_mget(memc, keys, key_length, 3);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  callbacks[0]= &callback_counter;
+  counter= 0;
+  rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1); 
+
+  assert(counter == 3);
+
+  return 0;
+}
+
 uint8_t mget_test(memcached_st *memc)
 {
   memcached_return rc;
@@ -1645,6 +1686,7 @@ uint8_t generate_data(memcached_st *memc)
   return 0;
 }
 
+#ifdef NOT_DONE
 uint8_t mset_data(memcached_st *memc)
 {
   unsigned long long x;
@@ -1660,6 +1702,7 @@ uint8_t mset_data(memcached_st *memc)
 
   return 0;
 }
+#endif
 
 uint8_t get_read(memcached_st *memc)
 {
@@ -1738,6 +1781,22 @@ uint8_t mget_read_result(memcached_st *memc)
   return 0;
 }
 
+uint8_t mget_read_function(memcached_st *memc)
+{
+  memcached_return rc;
+  unsigned int counter;
+  unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+
+  rc= memcached_mget(memc, global_keys, global_keys_length, GLOBAL_COUNT);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  callbacks[0]= &callback_counter;
+  counter= 0;
+  rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1); 
+
+  return 0;
+}
+
 uint8_t delete_generate(memcached_st *memc)
 {
   unsigned int x;
@@ -1999,6 +2058,7 @@ test_st tests[] ={
   {"mget", 1, mget_test },
   {"mget_result", 1, mget_result_test },
   {"mget_result_alloc", 1, mget_result_alloc_test },
+  {"mget_result_function", 1, mget_result_function },
   {"get_stats", 0, get_stats },
   {"add_host_test", 0, add_host_test },
   {"get_stats_keys", 0, get_stats_keys },
@@ -2058,6 +2118,7 @@ test_st generate_tests[] ={
   {"generate_data", 0, generate_data },
   {"mget_read", 0, mget_read },
   {"mget_read_result", 0, mget_read_result },
+  {"mget_read_function", 0, mget_read_function },
   {"mdelete_generate", 0, mdelete_generate },
   {"cleanup", 0, cleanup_pairs },
   {0, 0, 0}