class Memcache::NativeServer

Public Class Methods

new(p1) click to toggle source
static VALUE mc_initialize(VALUE self, VALUE opts) {
  memcached_st *mc;
  VALUE servers_aryv, prefixv, hashv, distributionv;

  Data_Get_Struct(self, memcached_st, mc);
  hashv         = rb_hash_aref(opts, sym_hash);
  distributionv = rb_hash_aref(opts, sym_distribution);
  prefixv       = rb_hash_aref(opts, sym_prefix);
  servers_aryv  = rb_hash_aref(opts, sym_servers);

  if (!NIL_P(hashv)) {
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH,        hash_behavior(hashv));
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_HASH, hash_behavior(hashv));
  }

  if (!NIL_P(distributionv))
    memcached_behavior_set_distribution(mc, distribution_behavior(distributionv));

  if (RTEST( rb_hash_aref(opts, sym_ketama) ))
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA, true);

  if (RTEST( rb_hash_aref(opts, sym_ketama_weighted) ))
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true);

  if (RTEST( rb_hash_aref(opts, sym_hash_with_prefix) ))
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY, true);

  if (RTEST( rb_hash_aref(opts, sym_binary) ))
    memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true);

  if (!NIL_P(prefixv))
    memcached_callback_set(mc, MEMCACHED_CALLBACK_PREFIX_KEY, StringValuePtr(prefixv));

  if (!NIL_P(servers_aryv)) {
    char* server;
    int i;

    for (i = 0; i < RARRAY_LEN(servers_aryv); i++) {
      server    = StringValuePtr(RARRAY_PTR(servers_aryv)[i]);
      memcached_server_push(mc, memcached_servers_parse(server));
    }
  } else {
    VALUE hostv, portv, weightv;
    char* host;
    int   port, weight;

    hostv   = rb_hash_aref(opts, sym_host);
    portv   = rb_hash_aref(opts, sym_port);
    weightv = rb_hash_aref(opts, sym_weight);
    host    = StringValuePtr(hostv);
    port    = NIL_P(portv) ? MEMCACHED_DEFAULT_PORT : NUM2INT(portv);
    weight  = NIL_P(weightv) ? 0 : NUM2INT(weightv);

    memcached_server_add_with_weight(mc, StringValuePtr(hostv), port, weight);
  }

  return self;
}

Public Instance Methods

add(p1, p2, p3 = v3, p4 = v4) click to toggle source
VALUE mc_add(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, value, expiry, flags;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "22", &key, &value, &expiry, &flags);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_add(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value),
                         RTEST(expiry) ? NUM2UINT(expiry) : 0,
                         RTEST(flags)  ? NUM2UINT(flags)  : 0);

  if (result == MEMCACHED_SUCCESS) {
    return value;
  } else if(result == MEMCACHED_NOTSTORED) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
append(p1, p2) click to toggle source
VALUE mc_append(VALUE self, VALUE key, VALUE value) {
  memcached_st *mc;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_append(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value), 0, 0);

  if (result == MEMCACHED_SUCCESS) {
    return Qtrue;
  } else if(result == MEMCACHED_NOTSTORED) {
    return Qfalse;
  } else {
    return throw_error(&result);
  }
}
cas(p1, p2, p3, p4 = v4, p5 = v5) click to toggle source
static VALUE mc_cas(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, value, cas, expiry, flags;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "32", &key, &value, &cas, &expiry, &flags);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_cas(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value),
                        RTEST(expiry) ? NUM2UINT(expiry) : 0,
                        RTEST(flags)  ? NUM2UINT(flags)  : 0,
                        NUM2ULL(cas));

  if (result == MEMCACHED_SUCCESS) {
    return value;
  } else if (result == MEMCACHED_NOTFOUND || result == MEMCACHED_DATA_EXISTS) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
close() click to toggle source
VALUE mc_close(VALUE self) {
  memcached_st *mc;
  Data_Get_Struct(self, memcached_st, mc);
  memcached_quit(mc);
  return Qnil;
}
decr(p1, p2 = v2) click to toggle source
VALUE mc_decr(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, amount;
  static memcached_return_t result;
  unsigned int offset;
  uint64_t value;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "11", &key, &amount);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  offset = RTEST(amount) ? NUM2INT(amount) : 1;

  result = memcached_decrement(mc, RSTRING_PTR(key), RSTRING_LEN(key), offset, &value);

  if (result == MEMCACHED_SUCCESS) {
    return LONG2NUM(value);
  } else if (result == MEMCACHED_NOTFOUND) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
delete(p1) click to toggle source
VALUE mc_delete(VALUE self, VALUE key) {
  memcached_st *mc;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  result = memcached_delete(mc, RSTRING_PTR(key), RSTRING_LEN(key), 0);

  if (result == MEMCACHED_SUCCESS) {
    return Qtrue;
  } else if(result == MEMCACHED_NOTFOUND) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
flush_all(p1 = v1) click to toggle source
VALUE mc_flush_all(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE delay;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "01", &delay);

  result = memcached_flush(mc, RTEST(delay) ? NUM2UINT(delay) : 0);

  if (result == MEMCACHED_SUCCESS) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
get(p1, p2 = v2) click to toggle source
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;
  }
}
incr(p1, p2 = v2) click to toggle source
VALUE mc_incr(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, amount;
  static memcached_return_t result;
  unsigned int offset;
  uint64_t value;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "11", &key, &amount);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  offset = RTEST(amount) ? NUM2INT(amount) : 1;

  result = memcached_increment(mc, RSTRING_PTR(key), RSTRING_LEN(key), offset, &value);

  if (result == MEMCACHED_SUCCESS) {
    return LONG2NUM(value);
  } else if (result == MEMCACHED_NOTFOUND) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
prefix() click to toggle source
VALUE mc_get_prefix(VALUE self) {
  memcached_st *mc;
  static memcached_return_t result;
  char* prefix;

  Data_Get_Struct(self, memcached_st, mc);
  prefix = (char*) memcached_callback_get(mc, MEMCACHED_CALLBACK_PREFIX_KEY, &result);

  return prefix ? rb_str_new2(prefix) : Qnil;
}
prefix=(p1) click to toggle source
VALUE mc_set_prefix(VALUE self, VALUE prefix) {
  memcached_st *mc;
  static memcached_return_t result;
  Data_Get_Struct(self, memcached_st, mc);

  if (NIL_P(prefix)) {
    result = memcached_callback_set(mc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
  } else {
    prefix = StringValue(prefix);
    result = memcached_callback_set(mc, MEMCACHED_CALLBACK_PREFIX_KEY, StringValuePtr(prefix));
  }
  return prefix;
}
prepend(p1, p2) click to toggle source
VALUE mc_prepend(VALUE self, VALUE key, VALUE value) {
  memcached_st *mc;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_prepend(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value), 0, 0);

  if (result == MEMCACHED_SUCCESS) {
    return Qtrue;
  } else if(result == MEMCACHED_NOTSTORED) {
    return Qfalse;
  } else {
    return throw_error(&result);
  }
}
replace(p1, p2, p3 = v3, p4 = v4) click to toggle source
VALUE mc_replace(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, value, expiry, flags;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "22", &key, &value, &expiry, &flags);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_replace(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value),
                         RTEST(expiry) ? NUM2UINT(expiry) : 0,
                         RTEST(flags)  ? NUM2UINT(flags)  : 0);

  if (result == MEMCACHED_SUCCESS) {
    return value;
  } else if(result == MEMCACHED_NOTSTORED) {
    return Qnil;
  } else {
    return throw_error(&result);
  }
}
set(p1, p2, p3 = v3, p4 = v4) click to toggle source
VALUE mc_set(int argc, VALUE *argv, VALUE self) {
  memcached_st *mc;
  VALUE key, value, expiry, flags;
  static memcached_return_t result;

  Data_Get_Struct(self, memcached_st, mc);
  rb_scan_args(argc, argv, "22", &key, &value, &expiry, &flags);

  key = StringValue(key);
  if (!use_binary(mc)) key = escape_key(key, NULL);
  value = StringValue(value);

  result = memcached_set(mc, RSTRING_PTR(key), RSTRING_LEN(key), RSTRING_PTR(value), RSTRING_LEN(value),
                        RTEST(expiry) ? NUM2UINT(expiry) : 0,
                        RTEST(flags)  ? NUM2UINT(flags)  : 0);

  if (result == MEMCACHED_SUCCESS) {
    return value;
  } else {
    return throw_error(&result);
  }
}