Parsing record with ldt


#1

Hello, im writting a ruby api for aerospike-c-client, and I found a problem that is little confusing for me…

Im creating large list, adding values, removing, everything is fine. But then i wanted to check what exactly exists in record and i found that:

{"LDTCONTROLBIN"=>nil, "llist_bin"=>nil}

I know its ruby syntax so let me explain that. I think the ruby is not important there at all. Its a result of:

aerospike_key_get(as, &err, policy, k, &rec)

parsed by:

// ----------------------------------------------------------------------------------
//
// convert as_record to ruby hash
//
VALUE record2hash(as_record * rec) {
  VALUE hash = rb_hash_new();

  as_record_iterator it;
  as_record_iterator_init(&it, rec);

  while ( as_record_iterator_has_next(&it) ) {
    as_bin * bin   = as_record_iterator_next(&it);
    as_val * value = (as_val *) as_bin_get_value(bin);

    VALUE name = rb_str_new2( as_bin_get_name(bin) );

    rb_hash_aset(hash, name, as_val2rb_val(value));
  }

  return hash;
}
// ----------------------------------------------------------------------------------
//
// as_val -> VALUE
//
VALUE as_val2rb_val(as_val * value) {
  switch ( as_val_type(value) ) {
    case AS_NIL:
      return Qnil;
      break;

    case AS_INTEGER:
      return as_val_int_2_val(value);
      break;

    case AS_STRING:
      return as_val_str_2_val(value);
      break;

    case AS_LIST:
      return as_list2array(value);
      break;

    case AS_MAP:
      return as_hashmap2hash(value);
      break;

    case AS_DOUBLE:
      return as_val_dbl_2_val(value);
      break;
  }

  rb_raise(rb_eRuntimeError, "[as_val2rb_val] Unsupported value type: %s", as_val_type_as_str(value));
}

As far as I understand the code I wrote, everything works fine but LDTCONTROLBIN and llist_bin returns AS_NIL type. I checked it, changing Qnil (ruby nil), to 1, {"LDTCONTROLBIN"=>1, "llist_bin"=>1}. Is that a expected behavior? It will be nice to know that record has a ldt on some bin with name that i can obtain this way. To perform operations on ldt i use methods form documentation: http://www.aerospike.com/apidocs/c/df/d4e/group__ldt__operations.html


#2

Hi, there has been a change in as_scan.include_ldt flag’s polarity. To get the LDT data in scan results, you should set this flag to true.


#3

Can you explain where can i find it and change? aerospike_key_get is using as_policy_read and I cant see it in documentation also in global as_config. Im using: aerospike - 3.6.2 aerospike-c-client - 3.1.24


#4

Sorry, my bad! I just noticed you were using aerospike_key_get. You need to use Large List API (LDT) to access all elements in that List, which means you’ll have to hit the DB more than just once.

Out of curiosity, what’s missing in our Ruby client that you’re writing a wrapper for the C client?


#5

Many thanks for answer!

About ruby client:

  1. missing aggregation(issue on github added Mar 1)
  2. missing background scans
  3. float values support was added like 2 weeks ago(when i currently had it in my wrapper)
  4. iritating symbol bin names, its common practice to write in ruby {:symbol => “some_bin_val”}, but your client throws errors
  5. not well documented, I found easier to write wrapper with C client documentation than reading ruby code.

yes… I know that 4. and 5. is personal :smile:

Now after i did some simple benchmarks my wrapper seems to be like 2-3 times faster. This, of course, for the price of possible memory leaks(if anything spoiled) and having to use the C client, but I’m not using JRuby.

Next problem is about response types, most of the time I need like simple hash with information, and ruby client is building Record objects. This hits performance(like in Active Record for many records) and from such fast database like aerospike I want as much speed as possible.


#6

By the way… just found a topic with some more explanation: Got Bin type AS_NIL, I haven’t found it earlier sorry!