static Variant HHVM_METHOD(Memcache, get, const Variant& key, VRefParam flags /*= null*/) { auto data = Native::data<MemcacheData>(this_); 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) { auto key = iter.second().toString(); String serializedKey = memcache_prepare_key(key); char *k = new char[serializedKey.length()+1]; std::strcpy(k, serializedKey.c_str()); real_keys.push_back(k); key_len.push_back(serializedKey.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(&data->m_memcache, &real_keys[0], &key_len[0], real_keys.size()); memcached_result_create(&data->m_memcache, &result); Array return_val; while ((memcached_fetch_result(&data->m_memcache, &result, &ret)) != nullptr) { 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); for ( size_t i = 0 ; i < real_keys.size() ; i++ ) { delete [] real_keys[i]; } return return_val; } } else { char *payload = NULL; size_t payload_len = 0; uint32_t flags = 0; memcached_return_t ret; String serializedKey = memcache_prepare_key(key.toString()); if (serializedKey.length() == 0) { return false; } payload = memcached_get(&data->m_memcache, serializedKey.c_str(), serializedKey.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; }
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; }
static VALUE mc_get(int argc, VALUE *argv, VALUE self) { memcached_st *mc; VALUE cas, keys, results, key, result; VALUE scalar_key = Qnil; memcached_return status; Data_Get_Struct(self, memcached_st, mc); rb_scan_args(argc, argv, "11", &keys, &cas); memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, RTEST(cas) ? 1 : 0); if (RTEST(cas) && TYPE(keys) != T_ARRAY) { scalar_key = keys; keys = rb_ary_new4(1, &keys); } if (TYPE(keys) != T_ARRAY) { char* str; size_t len; uint32_t flags; key = use_binary(mc) ? keys : escape_key(keys, NULL); str = memcached_get(mc, RSTRING_PTR(key), RSTRING_LEN(key), &len, &flags, &status); if (str == NULL) return Qnil; if (status == MEMCACHED_SUCCESS) { result = rb_hash_new(); rb_hash_aset(result, sym_value, rb_str_new(str, len)); rb_hash_aset(result, sym_flags, INT2NUM(flags)); free(str); return result; } else { printf("Memcache read error: %s %u\n", memcached_strerror(mc, status), status); return Qnil; } } else { memcached_result_st* mc_result; size_t num_keys, i; const char** key_strings; size_t* key_lengths; bool escaped; results = rb_hash_new(); num_keys = RARRAY_LEN(keys); if (num_keys == 0) return results; key_strings = (const char**) malloc(num_keys * sizeof(char *)); key_lengths = (size_t *) malloc(num_keys * sizeof(size_t)); for (i = 0; i < RARRAY_LEN(keys); i++) { key = RARRAY_PTR(keys)[i]; if (!use_binary(mc)) key = escape_key(key, &escaped); key_lengths[i] = RSTRING_LEN(key); key_strings[i] = RSTRING_PTR(key); } memcached_mget(mc, key_strings, key_lengths, num_keys); while ((mc_result = memcached_fetch_result(mc, NULL, &status))) { if (escaped) { key = unescape_key(memcached_result_key_value(mc_result), memcached_result_key_length(mc_result)); } else { key = rb_str_new(memcached_result_key_value(mc_result), memcached_result_key_length(mc_result)); } if (status == MEMCACHED_SUCCESS) { result = rb_hash_new(); rb_hash_aset(result, sym_value, rb_str_new(memcached_result_value(mc_result), memcached_result_length(mc_result))); rb_hash_aset(result, sym_flags, INT2NUM(memcached_result_flags(mc_result))); if (RTEST(cas)) rb_hash_aset(result, sym_cas, ULL2NUM(memcached_result_cas(mc_result))); memcached_result_free(mc_result); rb_hash_aset(results, key, result); } else { printf("Memcache read error: %s %u\n", memcached_strerror(mc, status), status); } } free(key_strings); free(key_lengths); if (!NIL_P(scalar_key)) return rb_hash_aref(results, scalar_key); return results; } }