libmemcached的执行流程

一、测试程序

// libmemcached_test.c
 
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libmemcached/memcached.h>
 
int main(void) {
  memcached_st *memc;
  memcached_server_st *servers = NULL;
  memcached_return rc;
  const char* server_list = "localhost:11211";
  const char* key= "key";
  const char* value= "value";
  char* retval = NULL;
  size_t len = 0;
  time_t expire = 0;
  uint32_t flags = 0;
 

  memc = memcached_create(NULL);
  servers = memcached_servers_parse(server_list);
  rc = memcached_server_push(memc, servers);
  memcached_server_list_free(servers);  
  if(rc == MEMCACHED_SUCCESS) {
    printf("added server successfully\n");
  } else {
    printf("couldn't add server: %s\n", memcached_strerror(memc, rc));
  }
 
  // set
  rc = memcached_set(memc, key, strlen(key), value, strlen(value), expire, flags);
  if(rc == MEMCACHED_SUCCESS) {
    printf("key stored successfully\n");
  } else {
    printf("couldn't store key: %s\n", memcached_strerror(memc, rc));
  }
 
  // get
  retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
  if(rc == MEMCACHED_SUCCESS) {
    printf("key got successfully\n");
    printf("value: %s\n", retval);
  } else {
    printf("couldn't get key: %s\n", memcached_strerror(memc, rc));
  }
  free(retval); 
 
  // delete
  rc = memcached_delete(memc, key, strlen(key), expire);
  if(rc == MEMCACHED_SUCCESS) {
    printf("key deleted successfully\n");
  } else {
    printf("couldn't delete key: %s\n", memcached_strerror(memc, rc));
  }
 
  // get
  retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
  if(rc == MEMCACHED_SUCCESS) {
    printf("key got successfully\n");
    printf("value: %s\n", retval);
  } else if(rc == MEMCACHED_NOTFOUND) {  
    printf("couldn't get key (not found): %s\n", memcached_strerror(memc, rc));
  } else if(rc == MEMCACHED_FAILURE) {  
    printf("couldn't get key (failure): %s\n", memcached_strerror(memc, rc));
  }
  free(retval);
 
  
  memcached_free(memc);
  return 0;
}

二、执行流程

1、memcached_st *memcached_create(memcached_st *ptr)

定义于libmemcached/memcached.cc。struct memcached_st定义于libmemcached-1.0/struct/memcached.h。

memcached_st *memcached_create(memcached_st *ptr)
{
  if (ptr)
  {
    ptr->options.is_allocated= false;
  } else {
    ptr= (memcached_st *)malloc(sizeof(memcached_st));

    if (ptr == NULL)
    {
      return NULL; /*  MEMCACHED_MEMORY_ALLOCATION_FAILURE */
    }

    ptr->options.is_allocated= true;
  }

  if (_memcached_init(ptr) == false)
  {
    memcached_free(ptr);
    return NULL;
  }

  if (memcached_result_create(ptr, &ptr->result) == NULL)  //设置memcached_result_st的root为memcached_st memc
  {                                                 //之后调用memcached_string_create()初始化memcached_result_st的value元素(类型为memcached_string_st)
    memcached_free(ptr);                          //同时设置memcached_string_st value的root为memcached_st *memc
    return NULL;
  }

  return ptr;
}
static inline bool _memcached_init(memcached_st *self)
{    //唯一没有对self->result(struct memcached_result_st)初始化,它由memcached_result_create()初始化
  self->state.is_purging= false;
  self->state.is_processing_input= false;
  self->state.is_time_for_rebuild= false;

  self->flags.auto_eject_hosts= false;
  self->flags.binary_protocol= false;
  self->flags.buffer_requests= false;
  self->flags.hash_with_namespace= false;
  self->flags.no_block= false;
  self->flags.reply= true;
  self->flags.randomize_replica_read= false;
  self->flags.support_cas= false;
  self->flags.tcp_nodelay= false;
  self->flags.use_sort_hosts= false;
  self->flags.use_udp= false;
  self->flags.verify_key= false;
  self->flags.tcp_keepalive= false;

  self->virtual_bucket= NULL;

  self->distribution= MEMCACHED_DISTRIBUTION_MODULA;

  if (hashkit_create(&self->hashkit) == NULL)  //调用_hashkit_create()和_hashkit_init()
  {                                       //_hashkit_init()设置哈希函数为hashkit_one_ta_a_time()。
    return false;
  }

  self->server_info.version= 0;

  self->ketama.continuum= NULL;
  self->ketama.continuum_count= 0;
  self->ketama.continuum_points_counter= 0;
  self->ketama.next_distribution_rebuild= 0;
  self->ketama.weighted= false;

  self->number_of_hosts= 0;
  self->servers= NULL;
  self->last_disconnected_server= NULL;

  self->snd_timeout= 0;
  self->rcv_timeout= 0;
  self->server_failure_limit= MEMCACHED_SERVER_FAILURE_LIMIT;
  self->query_id= 1; // 0 is considered invalid

  /* TODO, Document why we picked these defaults */
  self->io_msg_watermark= 500;
  self->io_bytes_watermark= 65 * 1024;

  self->tcp_keepidle= 0;

  self->io_key_prefetch= 0;
  self->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
  self->connect_timeout= MEMCACHED_DEFAULT_CONNECT_TIMEOUT;
  self->retry_timeout= MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT;
  self->dead_timeout= MEMCACHED_SERVER_FAILURE_DEAD_TIMEOUT;

  self->send_size= -1;
  self->recv_size= -1;

  self->user_data= NULL;
  self->number_of_replicas= 0;

  self->allocators= memcached_allocators_return_default(); //设置为struct memcached_allocator_t global_default_allocator
                                     //即{ _libmemcached_calloc, _libmemcached_free, _libmemcached_malloc, _libmemcached_realloc, 0 }。
  self->on_clone= NULL;
  self->on_cleanup= NULL;
  self->get_key_failure= NULL;
  self->delete_trigger= NULL;
  self->callbacks= NULL;
  self->sasl.callbacks= NULL;
  self->sasl.is_allocated= false;

  self->error_messages= NULL;
  self->_namespace= NULL;
  self->configure.initial_pool_size= 1;
  self->configure.max_pool_size= 1;
  self->configure.version= -1;
  self->configure.filename= NULL;

  return true;
}
可以看出, memcached_st 中有个memcached_result_st result, memcached_result_st中有个 memcached_string_st value,并逐步初始化。


2、memcached_server_list_st memcached_servers_parse(const char *server_strings)

定义于libmemcached/parse.cc中;memcached_server_list_st即struct memcached_server_st *,后者定义于libmemcached-1.0/struct/server.h中。

分析字符串,来初始化服务器列表。memcached_server_st *servers= memcached_server_list_append_with_weight(...)(此处传入的memcached_st *memc为空)。其中调用__server_create_with(),进一步_server_init()来初始化memcached_server_st(设置其状态为MEMCACHED_SERVER_STATE_NEW)。


3、memcached_return_t memcached_server_push(memcached_st *memc, const memcached_server_list_st list)

作用是将list中的server加到memc->servers中(list实际上是一个数组,数组元素为memcached_server_st)。

这里和上一步相似,依旧调用__server_create_with(),只是传入参数memcached_st *memc不为空。因此多调用了ser_hostinfo(memcached_server_st *server)(初始化server->address_info),并设置server的状态server->state= MEMCACHED_SERVER_STATE_ADDRINFO

最后,run_distribution(memcached_st *)。该函数根据memcached_st * ptr->distribution的类型,如果是MEMCACHED_DISTRIBUTION_CONSISTENT(一致性哈希算法的实现),则调用update_continuum(ptr);本次执行时是MEMCACHED_DISTRIBUTION_MODULA,则直接退出。


4、memcached_server_list_free(memcached_server_list_st servers)

循环调用__server_free()释放掉servers数组中的各个服务器,其中调用memcached_quit_server()、memcached_error_free();最后释放掉这个数组。

实际上这里的servers数组只是一个临时存储服务器的数组,当其内容已经通过上一步加入到memcached_st *memc中之后,当然就没有继续存在的理由了。


5、memcached_set

由于内部涉及memcached的连接等,下一节讨论。


6、void memcached_free(memcached_st *ptr)

只是调用_free():

static void _free(memcached_st *ptr, bool release_st)
{
  /* If we have anything open, lets close it now */
  send_quit(ptr);                          //循环调用memcached_quit_server()对每个服务器发送quit
  memcached_server_list_free(memcached_server_list(ptr));   //执行完之后ptr->servers已free
  memcached_result_free(&ptr->result);

  memcached_virtual_bucket_free(ptr);        //free(self->virtual_bucket)

  memcached_server_free(ptr->last_disconnected_server);

  if (ptr->on_cleanup)
  {
    ptr->on_cleanup(ptr);
  }

  libmemcached_free(ptr, ptr->ketama.continuum);   //本例未使用ketama一致性哈希算法

  memcached_array_free(ptr->_namespace);
  ptr->_namespace= NULL;

  memcached_error_free(*ptr);

  if (LIBMEMCACHED_WITH_SASL_SUPPORT and ptr->sasl.callbacks)
  {
    memcached_destroy_sasl_auth_data(ptr);
  }

  if (release_st)
  {
    memcached_array_free(ptr->configure.filename);
    ptr->configure.filename= NULL;
  }

  if (memcached_is_allocated(ptr) && release_st)
  {
    libmemcached_free(ptr, ptr);   //最后释放掉memcached_st
  }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值