Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
  }
}