/* Copyright (C) 2008 Patrick Galbraith, Brian Aker
See COPYING file found with distribution for license.
*/
#include <mysql.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include "common.h"
#define BRIAN_LIKES_LOOP 1;
pthread_mutex_t memc_servers_mutex= PTHREAD_MUTEX_INITIALIZER;
/*
select memc_servers_set("hostname:23,hostname2:44");
*/
static memcached_st *master_memc= NULL;
my_bool memc_servers_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
long long memc_servers_set(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
/*void memc_servers_set_deinit(UDF_INIT *initid);*/
my_bool memc_server_count_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
long long memc_server_count(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
my_bool memc_servers_behavior_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
long long memc_servers_behavior_set(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
/*void memc_servers_behavior_set_deinit(UDF_INIT *initid);*/
my_bool memc_behavior_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
long long memc_behavior_set(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
my_bool memc_servers_behavior_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *memc_servers_behavior_get(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error);
my_bool memc_behavior_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *memc_behavior_get(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error);
my_bool memc_list_behaviors_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *memc_list_behaviors(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error);
void memc_list_behaviors_deinit(UDF_INIT *initid);
my_bool memc_list_hash_types_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *memc_list_hash_types(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error);
my_bool memc_list_distribution_types_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
char *memc_list_distribution_types(UDF_INIT *initid, UDF_ARGS *args, char *result,
unsigned long *length, char *is_null, char *error);
my_bool memc_servers_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
/* this is how to fail */
if (args->arg_count != 1)
{
strncpy(message, "String of memcached servers.", MYSQL_ERRMSG_SIZE);
return 1;
}
args->arg_type[0]= STRING_RESULT;
/* initid->ptr keeps state for between memc_get_init and memc_get_deinit */
initid->ptr= NULL;
return 0;
}
/*
memc_servers_set
get cached object, takes hash-key arg
*/
long long memc_servers_set(__attribute__ ((unused)) UDF_INIT *initid,
UDF_ARGS *args,
__attribute__ ((unused)) char *result,
__attribute__ ((unused)) unsigned long *length,
char *is_null,
__attribute__ ((unused)) char *error)
{
uint64_t set= 1;
memcached_return rc= 0;
memcached_server_st *servers;
uint version;
pthread_mutex_lock(&memc_servers_mutex);
if (master_memc == NULL)
master_memc= memcached_create(NULL);
if (master_memc == NULL)
{
*is_null= 1;
return 0;
}
servers= memcached_servers_parse(args->args[0]);
if (servers == NULL)
{
*is_null= 1;
return 0;
}
rc= memcached_server_push(master_memc, servers);
if (rc != MEMCACHED_SUCCESS)
{
*is_null= 1;
return 0;
}
/*
enable cas by default. This can be undonw with
memc_behavior_set
*/
memcached_version(master_memc);
version= master_memc->servers[0].major_version * 100 +
master_memc->servers[0].minor_version * 10 +
master_memc->servers[0].micro_version;
if (version >= 124)
memcached_behavior_set(master_memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
memcached_server_list_free(servers);
pthread_mutex_unlock(&memc_servers_mutex);
fprintf(stderr, "rc %d\n", rc);
return ((long long) rc == MEMCACHED_SUCCESS ? 0 : rc);
}
my_bool memc_server_count_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
/* this is how to fail */
if (args->arg_count > 0)
{
strncpy(message, "This UDF takes no arguments: memc_server_count()", MYSQL_ERRMSG_SIZE);
return 1;
}
/* initid->ptr keeps state for between memc_server_count_init and memc_server_count_deinit*/
initid->ptr= NULL;
return 0;
}
/*
memc_server_count
get cached object, takes hash-key arg
*/
long long memc_server_count(__attribute__ ((unused)) UDF_INIT *initid,
__attribute__ ((unused)) UDF_ARGS *args,
__attribute__ ((unused)) char *result,
__attribute__ ((unused)) unsigned long *length,
__attribute__ ((unused)) char *is_null,
__attribute__ ((unused)) char *error)
{
unsigned int count;
pthread_mutex_lock(&memc_servers_mutex);
if (master_memc == NULL)
master_memc= memcached_create(NULL);
count= memcached_server_count(master_memc);
pthread_mutex_unlock(&memc_servers_mutex);
return ((long long) count);
}
/* memc_servers_behavior_set_init */
my_bool memc_servers_behavior_set_init(__attribute__ ((unused)) UDF_INIT *initid,
UDF_ARGS *args,
char *message)
{
uint64_t setting;
unsigned int count;
/* Fail if not two args */
if (args->arg_count != 2)
{
strncpy(message,
"2 arguments must be supplied: memc_servers_behavior_set('<behavior type>', '<value>')",
MYSQL_ERRMSG_SIZE);
return 1;
}
pthread_mutex_lock(&memc_servers_mutex);
if (master_memc == NULL)
master_memc= memcached_create(NULL);
count= memcached_server_count(master_memc);
pthread_mutex_unlock(&memc_servers_mutex);
if (!count) {
strncpy(message,
"Servers not set! memc_servers_set('server:port,...')",
MYSQL_ERRMSG_SIZE);
return 1;
}
args->arg_type[0]= STRING_RESULT;
if (args->arg_type[1] == INT_RESULT)
setting= *(uint64_t*) args->args[1];
else if (args->arg_type[1] == STRING_RESULT)
setting= (uint64_t)atoi(args->args[1]);
/*
Do some checking of supplied behavior and setting
If a 1|0 value, check. Print error if not. We need some sort of
check for the other non 1|0 behaviors
*/
if (! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_SUPPORT_CAS") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_NO_BLOCK") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_BUFFER_REQUESTS") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_USER_DATA") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_SORT_HOSTS") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_VERIFY_KEY") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_TCP_NODELAY") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_KETAMA") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_CACHE_LOOKUPS") ||
! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_BUFFER_REQUESTS"))
{
if (setting != 1 && setting != 0) {
strncpy(message, "INALID VALUE FOR BEHAVIOR - MUST BE 1 OR 0 !\n", MYSQL_ERRMSG_SIZE);
return 1;
}
}
else if ( ! strcasecmp(args->args[0], "MEMCACHED_BEHAVIOR_DISTRIBUTION"))
{
if (strcasecmp(args->args[1], "MEMCACHED_DISTRIBUTION_MODULA") &&
strcasecmp(args->args[1], "MEMCACHED_DISTRIBUTION_CONSISTEN
- 1
- 2
- 3
前往页