fef62f03a2
Now that HHVM is the default runtime, this namespace doesn't mean anything.
687 linhas
22 KiB
C++
687 linhas
22 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
|
|
| Copyright (c) 1997-2010 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#include <runtime/ext/ext_memcache.h>
|
|
#include <runtime/base/util/request_local.h>
|
|
#include <runtime/base/ini_setting.h>
|
|
|
|
#include <system/lib/systemlib.h>
|
|
|
|
#define MMC_SERIALIZED 1
|
|
#define MMC_COMPRESSED 2
|
|
|
|
namespace HPHP {
|
|
IMPLEMENT_DEFAULT_EXTENSION(memcache);
|
|
|
|
bool ini_on_update_hash_strategy(CStrRef value, void *p);
|
|
bool ini_on_update_hash_function(CStrRef value, void *p);
|
|
|
|
class MEMCACHEGlobals : public RequestEventHandler {
|
|
public:
|
|
std::string hash_strategy;
|
|
std::string hash_function;
|
|
|
|
MEMCACHEGlobals() {}
|
|
|
|
virtual void requestInit() {
|
|
hash_strategy = "standard";
|
|
hash_function = "crc32";
|
|
|
|
IniSetting::Bind("memcache.hash_strategy", "standard",
|
|
ini_on_update_hash_strategy, &hash_strategy);
|
|
IniSetting::Bind("memcache.hash_function", "crc32",
|
|
ini_on_update_hash_function, &hash_function);
|
|
}
|
|
|
|
virtual void requestShutdown() {
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_STATIC_REQUEST_LOCAL(MEMCACHEGlobals, s_memcache_globals);
|
|
#define MEMCACHEG(name) s_memcache_globals->name
|
|
|
|
bool ini_on_update_hash_strategy(CStrRef value, void *p) {
|
|
if (!strncasecmp(value.data(), "standard", sizeof("standard"))) {
|
|
MEMCACHEG(hash_strategy) = "standard";
|
|
} else if (!strncasecmp(value.data(), "standard", sizeof("consistent"))) {
|
|
MEMCACHEG(hash_strategy) = "consistent";
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ini_on_update_hash_function(CStrRef value, void *p) {
|
|
if (!strncasecmp(value.data(), "crc32", sizeof("crc32"))) {
|
|
MEMCACHEG(hash_strategy) = "crc32";
|
|
} else if (!strncasecmp(value.data(), "fnv", sizeof("fnv"))) {
|
|
MEMCACHEG(hash_strategy) = "fnv";
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// methods
|
|
|
|
c_Memcache::c_Memcache(Class* cb) :
|
|
ExtObjectData(cb), m_memcache(), m_compress_threshold(0),
|
|
m_min_compress_savings(0.2) {
|
|
memcached_create(&m_memcache);
|
|
|
|
if (MEMCACHEG(hash_strategy) == "consistent") {
|
|
// need to hook up a global variable to set this
|
|
memcached_behavior_set(&m_memcache, MEMCACHED_BEHAVIOR_DISTRIBUTION,
|
|
MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA);
|
|
} else {
|
|
memcached_behavior_set(&m_memcache, MEMCACHED_BEHAVIOR_DISTRIBUTION,
|
|
MEMCACHED_DISTRIBUTION_MODULA);
|
|
}
|
|
|
|
if (MEMCACHEG(hash_function) == "fnv") {
|
|
memcached_behavior_set(&m_memcache, MEMCACHED_BEHAVIOR_HASH,
|
|
MEMCACHED_HASH_FNV1A_32);
|
|
} else {
|
|
memcached_behavior_set(&m_memcache, MEMCACHED_BEHAVIOR_HASH,
|
|
MEMCACHED_HASH_CRC);
|
|
}
|
|
}
|
|
|
|
c_Memcache::~c_Memcache() {
|
|
memcached_free(&m_memcache);
|
|
}
|
|
|
|
void c_Memcache::t___construct() {
|
|
return;
|
|
}
|
|
|
|
bool c_Memcache::t_connect(CStrRef host, int port /*= 0*/,
|
|
int timeout /*= 0*/,
|
|
int timeoutms /*= 0*/) {
|
|
memcached_return_t ret;
|
|
|
|
if (!host.empty() && host[0] == '/') {
|
|
ret = memcached_server_add_unix_socket(&m_memcache, host.c_str());
|
|
} else {
|
|
ret = memcached_server_add(&m_memcache, host.c_str(), port);
|
|
}
|
|
|
|
return (ret == MEMCACHED_SUCCESS);
|
|
}
|
|
|
|
bool c_Memcache::t_pconnect(CStrRef host, int port /*= 0*/,
|
|
int timeout /*= 0*/,
|
|
int timeoutms /*= 0*/) {
|
|
return t_connect(host, port, timeout, timeoutms);
|
|
}
|
|
|
|
String static memcache_prepare_for_storage(CVarRef var, int &flag) {
|
|
if (var.isString()) {
|
|
return var.toString();
|
|
} else if (var.isNumeric() || var.isBoolean()) {
|
|
return var.toString();
|
|
} else {
|
|
flag |= MMC_SERIALIZED;
|
|
return f_serialize(var);
|
|
}
|
|
}
|
|
|
|
Variant static memcache_fetch_from_storage(const char *payload,
|
|
size_t payload_len,
|
|
uint32_t flags) {
|
|
Variant ret = uninit_null();
|
|
|
|
if (flags & MMC_COMPRESSED) {
|
|
raise_warning("Unable to handle compressed values yet");
|
|
return uninit_null();
|
|
}
|
|
|
|
if (flags & MMC_SERIALIZED) {
|
|
ret = unserialize_from_buffer(payload, payload_len);
|
|
} else {
|
|
ret = String(payload, payload_len, CopyString);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool c_Memcache::t_add(CStrRef key, CVarRef var, int flag /*= 0*/,
|
|
int expire /*= 0*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
String serialized = memcache_prepare_for_storage(var, flag);
|
|
|
|
memcached_return_t ret = memcached_add(&m_memcache,
|
|
key.c_str(), key.length(),
|
|
serialized.c_str(),
|
|
serialized.length(),
|
|
expire, flag);
|
|
|
|
return (ret == MEMCACHED_SUCCESS);
|
|
}
|
|
|
|
bool c_Memcache::t_set(CStrRef key, CVarRef var, int flag /*= 0*/,
|
|
int expire /*= 0*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
String serialized = memcache_prepare_for_storage(var, flag);
|
|
|
|
memcached_return_t ret = memcached_set(&m_memcache,
|
|
key.c_str(), key.length(),
|
|
serialized.c_str(),
|
|
serialized.length(),
|
|
expire, flag);
|
|
|
|
if (ret == MEMCACHED_SUCCESS) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool c_Memcache::t_replace(CStrRef key, CVarRef var, int flag /*= 0*/,
|
|
int expire /*= 0*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
String serialized = memcache_prepare_for_storage(var, flag);
|
|
|
|
memcached_return_t ret = memcached_replace(&m_memcache,
|
|
key.c_str(), key.length(),
|
|
serialized.c_str(),
|
|
serialized.length(),
|
|
expire, flag);
|
|
return (ret == MEMCACHED_SUCCESS);
|
|
}
|
|
|
|
Variant c_Memcache::t_get(CVarRef key, VRefParam flags /*= null*/) {
|
|
if (key.is(KindOfArray)) {
|
|
std::vector<const char *> real_keys;
|
|
std::vector<size_t> key_len;
|
|
Array keyArr = key.toArray();
|
|
|
|
real_keys.reserve(keyArr.size());
|
|
key_len.reserve(keyArr.size());
|
|
|
|
for (ArrayIter iter(keyArr); iter; ++iter) {
|
|
real_keys.push_back(const_cast<char *>(iter.second().toString().c_str()));
|
|
key_len.push_back(iter.second().toString().length());
|
|
}
|
|
|
|
if (!real_keys.empty()) {
|
|
const char *payload = NULL;
|
|
size_t payload_len = 0;
|
|
uint32_t flags = 0;
|
|
const char *res_key = NULL;
|
|
size_t res_key_len = 0;
|
|
|
|
memcached_result_st result;
|
|
|
|
memcached_return_t ret = memcached_mget(&m_memcache, &real_keys[0],
|
|
&key_len[0], real_keys.size());
|
|
memcached_result_create(&m_memcache, &result);
|
|
Array return_val;
|
|
|
|
while ((memcached_fetch_result(&m_memcache, &result, &ret)) != NULL) {
|
|
if (ret != MEMCACHED_SUCCESS) {
|
|
// should probably notify about errors
|
|
continue;
|
|
}
|
|
|
|
payload = memcached_result_value(&result);
|
|
payload_len = memcached_result_length(&result);
|
|
flags = memcached_result_flags(&result);
|
|
res_key = memcached_result_key_value(&result);
|
|
res_key_len = memcached_result_key_length(&result);
|
|
|
|
return_val.set(String(res_key, res_key_len, CopyString),
|
|
memcache_fetch_from_storage(payload,
|
|
payload_len, flags));
|
|
}
|
|
memcached_result_free(&result);
|
|
|
|
return return_val;
|
|
}
|
|
} else {
|
|
char *payload = NULL;
|
|
size_t payload_len = 0;
|
|
uint32_t flags = 0;
|
|
|
|
memcached_return_t ret;
|
|
String skey = key.toString();
|
|
|
|
if (skey.length() == 0) {
|
|
return false;
|
|
}
|
|
|
|
payload = memcached_get(&m_memcache, skey.c_str(), skey.length(),
|
|
&payload_len, &flags, &ret);
|
|
|
|
/* This is for historical reasons from libmemcached*/
|
|
if (ret == MEMCACHED_END) {
|
|
ret = MEMCACHED_NOTFOUND;
|
|
}
|
|
|
|
if (ret == MEMCACHED_NOTFOUND) {
|
|
return false;
|
|
}
|
|
|
|
Variant retval = memcache_fetch_from_storage(payload, payload_len, flags);
|
|
free(payload);
|
|
|
|
return retval;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool c_Memcache::t_delete(CStrRef key, int expire /*= 0*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
memcached_return_t ret = memcached_delete(&m_memcache,
|
|
key.c_str(), key.length(),
|
|
expire);
|
|
return (ret == MEMCACHED_SUCCESS);
|
|
}
|
|
|
|
int64_t c_Memcache::t_increment(CStrRef key, int offset /*= 1*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
uint64_t value;
|
|
memcached_return_t ret = memcached_increment(&m_memcache, key.c_str(),
|
|
key.length(), offset, &value);
|
|
|
|
if (ret == MEMCACHED_SUCCESS) {
|
|
return (int64_t)value;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int64_t c_Memcache::t_decrement(CStrRef key, int offset /*= 1*/) {
|
|
if (key.empty()) {
|
|
raise_warning("Key cannot be empty");
|
|
return false;
|
|
}
|
|
|
|
uint64_t value;
|
|
memcached_return_t ret = memcached_decrement(&m_memcache, key.c_str(),
|
|
key.length(), offset, &value);
|
|
|
|
if (ret == MEMCACHED_SUCCESS) {
|
|
return (int64_t)value;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool c_Memcache::t_close() {
|
|
memcached_quit(&m_memcache);
|
|
return true;
|
|
}
|
|
|
|
Variant c_Memcache::t_getversion() {
|
|
int server_count = memcached_server_count(&m_memcache);
|
|
char version[16];
|
|
int version_len = 0;
|
|
|
|
if (memcached_version(&m_memcache) != MEMCACHED_SUCCESS) {
|
|
return false;
|
|
}
|
|
|
|
for (int x = 0; x < server_count; x++) {
|
|
memcached_server_instance_st instance =
|
|
memcached_server_instance_by_position(&m_memcache, x);
|
|
|
|
if (!instance->major_version) {
|
|
continue;
|
|
}
|
|
|
|
version_len = snprintf(version, sizeof(version), "%d.%d.%d",
|
|
instance->major_version, instance->minor_version,
|
|
instance->micro_version);
|
|
return String(version, version_len, CopyString);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool c_Memcache::t_flush(int expire /*= 0*/) {
|
|
return memcached_flush(&m_memcache, expire) == MEMCACHED_SUCCESS;
|
|
}
|
|
|
|
bool c_Memcache::t_setoptimeout(int64_t timeoutms) {
|
|
if (timeoutms < 1) {
|
|
timeoutms = 1000; // make default
|
|
}
|
|
|
|
/* intentionally doing nothing for now */
|
|
|
|
return true;
|
|
}
|
|
|
|
int64_t c_Memcache::t_getserverstatus(CStrRef host, int port /* = 0 */) {
|
|
/* intentionally doing nothing for now */
|
|
return 1;
|
|
}
|
|
|
|
bool c_Memcache::t_setcompressthreshold(int threshold,
|
|
double min_savings /* = 0.2 */) {
|
|
if (threshold < 0) {
|
|
raise_warning("threshold must be a positive integer");
|
|
return false;
|
|
}
|
|
|
|
if (min_savings < 0 || min_savings > 1) {
|
|
raise_warning("min_savings must be a float in the 0..1 range");
|
|
return false;
|
|
}
|
|
|
|
m_compress_threshold = threshold;
|
|
m_min_compress_savings = min_savings;
|
|
|
|
return true;
|
|
}
|
|
|
|
Array static memcache_build_stats(const memcached_st *ptr,
|
|
memcached_stat_st *memc_stat,
|
|
memcached_return_t *ret) {
|
|
char **curr_key;
|
|
char **stat_keys = memcached_stat_get_keys(const_cast<memcached_st*>(ptr),
|
|
memc_stat, ret);
|
|
|
|
if (*ret != MEMCACHED_SUCCESS) {
|
|
if (stat_keys) {
|
|
free(stat_keys);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Array return_val = Array::Create();
|
|
|
|
for (curr_key = stat_keys; *curr_key; curr_key++) {
|
|
char *mc_val;
|
|
mc_val = memcached_stat_get_value(ptr, memc_stat, *curr_key, ret);
|
|
if (*ret != MEMCACHED_SUCCESS) {
|
|
break;
|
|
}
|
|
return_val.set(String(*curr_key, CopyString),
|
|
String(mc_val, CopyString));
|
|
free(mc_val);
|
|
}
|
|
|
|
free(stat_keys);
|
|
return return_val;
|
|
}
|
|
|
|
|
|
Array c_Memcache::t_getstats(CStrRef type /* = null_string */,
|
|
int slabid /* = 0 */, int limit /* = 100 */) {
|
|
if (!memcached_server_count(&m_memcache)) {
|
|
return NULL;
|
|
}
|
|
|
|
char extra_args[30] = {0};
|
|
|
|
if (slabid) {
|
|
snprintf(extra_args, sizeof(extra_args), "%s %d %d", type.c_str(),
|
|
slabid, limit);
|
|
} else if (!type.empty()) {
|
|
snprintf(extra_args, sizeof(extra_args), "%s", type.c_str());
|
|
}
|
|
|
|
memcached_server_instance_st instance =
|
|
memcached_server_instance_by_position(&m_memcache, 0);
|
|
|
|
memcached_stat_st stats;
|
|
if (memcached_stat_servername(&stats, extra_args, instance->hostname,
|
|
instance->port) != MEMCACHED_SUCCESS) {
|
|
return NULL;
|
|
}
|
|
|
|
memcached_return_t ret;
|
|
return memcache_build_stats(&m_memcache, &stats, &ret);
|
|
}
|
|
|
|
Array c_Memcache::t_getextendedstats(CStrRef type /* = null_string */,
|
|
int slabid /* = 0 */,
|
|
int limit /* = 100 */) {
|
|
memcached_return_t ret;
|
|
memcached_stat_st *stats;
|
|
|
|
stats = memcached_stat(&m_memcache, NULL, &ret);
|
|
if (ret != MEMCACHED_SUCCESS) {
|
|
return NULL;
|
|
}
|
|
|
|
int server_count = memcached_server_count(&m_memcache);
|
|
|
|
Array return_val;
|
|
|
|
for (int server_id = 0; server_id < server_count; server_id++) {
|
|
memcached_server_instance_st server;
|
|
memcached_stat_st *stat;
|
|
char stats_key[30] = {0};
|
|
size_t key_len;
|
|
|
|
server = memcached_server_instance_by_position(&m_memcache, server_id);
|
|
stat = stats + server_id;
|
|
|
|
Array server_stats = memcache_build_stats(&m_memcache, stat, &ret);
|
|
if (ret != MEMCACHED_SUCCESS) {
|
|
continue;
|
|
}
|
|
|
|
key_len = snprintf(stats_key, sizeof(stats_key),
|
|
"%s:%d", server->hostname, server->port);
|
|
|
|
return_val.set(String(stats_key, key_len, CopyString), server_stats);
|
|
}
|
|
|
|
free(stats);
|
|
return return_val;
|
|
}
|
|
|
|
bool c_Memcache::t_setserverparams(CStrRef host, int port /* = 11211 */,
|
|
int timeout /* = 0 */,
|
|
int retry_interval /* = 0 */,
|
|
bool status /* = true */,
|
|
CVarRef failure_callback /* = null_variant */) {
|
|
/* intentionally doing nothing for now */
|
|
return true;
|
|
}
|
|
|
|
bool c_Memcache::t_addserver(CStrRef host, int port /* = 11211 */,
|
|
bool persistent /* = false */,
|
|
int weight /* = 0 */, int timeout /* = 0 */,
|
|
int retry_interval /* = 0 */,
|
|
bool status /* = true */,
|
|
CVarRef failure_callback /* = null_variant */,
|
|
int timeoutms /* = 0 */) {
|
|
memcached_return_t ret;
|
|
|
|
if (!host.empty() && host[0] == '/') {
|
|
ret = memcached_server_add_unix_socket_with_weight(&m_memcache,
|
|
host.c_str(), weight);
|
|
} else {
|
|
ret = memcached_server_add_with_weight(&m_memcache, host.c_str(),
|
|
port, weight);
|
|
}
|
|
|
|
if (ret == MEMCACHED_SUCCESS) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Variant c_Memcache::t___destruct() {
|
|
t_close();
|
|
return uninit_null();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// these all pass to their OO equivalents
|
|
|
|
Object f_memcache_connect(CStrRef host, int port /* = 0 */,
|
|
int timeout /* = 0 */, int timeoutms /* = 0 */) {
|
|
c_Memcache *memcache_obj = NEWOBJ(c_Memcache)();
|
|
Object ret(memcache_obj);
|
|
memcache_obj->t_connect(host, port, timeout, timeoutms);
|
|
return ret;
|
|
}
|
|
|
|
Object f_memcache_pconnect(CStrRef host, int port /* = 0 */,
|
|
int timeout /* = 0 */, int timeoutms /* = 0 */) {
|
|
return f_memcache_connect(host, port, timeout, timeoutms);
|
|
}
|
|
|
|
bool f_memcache_add(CObjRef memcache, CStrRef key, CVarRef var,
|
|
int flag /* = 0 */, int expire /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_add(key, var, flag, expire);
|
|
}
|
|
|
|
bool f_memcache_set(CObjRef memcache, CStrRef key, CVarRef var,
|
|
int flag /* = 0 */, int expire /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_set(key, var, flag, expire);
|
|
}
|
|
|
|
bool f_memcache_replace(CObjRef memcache, CStrRef key, CVarRef var,
|
|
int flag /* = 0 */, int expire /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_replace(key, var, flag, expire);
|
|
}
|
|
|
|
Variant f_memcache_get(CObjRef memcache, CVarRef key,
|
|
VRefParam flags /* = null */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_get(key, flags);
|
|
}
|
|
|
|
bool f_memcache_delete(CObjRef memcache, CStrRef key, int expire /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_delete(key, expire);
|
|
}
|
|
|
|
int64_t f_memcache_increment(CObjRef memcache, CStrRef key,
|
|
int offset /* = 1 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_increment(key, offset);
|
|
}
|
|
|
|
int64_t f_memcache_decrement(CObjRef memcache, CStrRef key,
|
|
int offset /* = 1 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_decrement(key, offset);
|
|
}
|
|
|
|
bool f_memcache_close(CObjRef memcache) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_close();
|
|
}
|
|
|
|
bool f_memcache_debug(bool onoff) {
|
|
throw NotImplementedException(__func__);
|
|
}
|
|
|
|
Variant f_memcache_get_version(CObjRef memcache) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_getversion();
|
|
}
|
|
|
|
bool f_memcache_flush(CObjRef memcache, int timestamp /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_flush(timestamp);
|
|
}
|
|
|
|
bool f_memcache_setoptimeout(CObjRef memcache, int timeoutms) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_setoptimeout(timeoutms);
|
|
}
|
|
|
|
int64_t f_memcache_get_server_status(CObjRef memcache, CStrRef host,
|
|
int port /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_getserverstatus(host, port);
|
|
}
|
|
|
|
bool f_memcache_set_compress_threshold(CObjRef memcache, int threshold,
|
|
double min_savings /* = 0.2 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_setcompressthreshold(threshold, min_savings);
|
|
}
|
|
|
|
Array f_memcache_get_stats(CObjRef memcache, CStrRef type /* = null_string */,
|
|
int slabid /* = 0 */, int limit /* = 100 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_getstats(type, slabid, limit);
|
|
}
|
|
|
|
Array f_memcache_get_extended_stats(CObjRef memcache,
|
|
CStrRef type /* = null_string */,
|
|
int slabid /* = 0 */,
|
|
int limit /* = 100 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_getextendedstats(type, slabid, limit);
|
|
}
|
|
|
|
bool f_memcache_set_server_params(CObjRef memcache, CStrRef host,
|
|
int port /* = 11211 */,
|
|
int timeout /* = 0 */,
|
|
int retry_interval /* = 0 */,
|
|
bool status /* = true */,
|
|
CVarRef failure_callback /* = null_variant */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_setserverparams(host, port, timeout, retry_interval,
|
|
status, failure_callback);
|
|
}
|
|
|
|
bool f_memcache_add_server(CObjRef memcache, CStrRef host,
|
|
int port /* = 11211 */,
|
|
bool persistent /* = false */,
|
|
int weight /* = 0 */,
|
|
int timeout /* = 0 */,
|
|
int retry_interval /* = 0 */,
|
|
bool status /* = true */,
|
|
CVarRef failure_callback /* = null_variant */,
|
|
int timeoutms /* = 0 */) {
|
|
c_Memcache *memcache_obj = memcache.getTyped<c_Memcache>();
|
|
return memcache_obj->t_addserver(host, port, persistent, weight, timeout,
|
|
retry_interval, status, failure_callback,
|
|
timeoutms);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
}
|