val_reserver()增加其引用计数,防止它们在释放记录时被同时释放。
下面是在将值增加到记录前增加其引用计数的示例,当记录被销毁时,list将不受影响。若引用计数未被增加,那么list将被销毁,其内包含的数据也不再存在。
as_arraylist list; as_arraylist_init(&list, 3); as_arraylist_append_int64(&list, 1); as_arraylist_append_int64(&list, 2); as_arraylist_append_int64(&list, 3); as_record rec; as_record_inita(&rec, 1); as_record_set_list(&rec, "lbin", (as_list*)as_val_reserve(&list)); as_record_destroy(&rec); int64_t i1 = as_arraylist_get_int64(&list, 1); int64_t i2 = as_arraylist_get_int64(&list, 2); int64_t i3 = as_arraylist_get_int64(&list, 3); as_arraylist_destroy(&list);
上面代码中的13-15行会有效地读取数据。若as_val_reserver()未被 调用,就会是无效的读取,可能导致数据损坏。
设置分代编号
分代编号即一条记录的版本号。每次对记录的修改都会增加分代编号的值。可设置一条记录的分代编号,但通常用来提示记录所在的服务器一个期望的分代编号。
rec->gen = 0
设置生存时间
每条记录还有一个生存时间(TTL),指定记录何时过期或从数据库中驱逐。此值定义从当前开始的秒数。
rec->ttl = 3600 * 24;
?
遍历记录的全部bin
?
你可能需要遍历一条记录的所有bin,Aerospike C客户端提供两个方法:
as_record_foreach() — 迭代一条记录的每一个bin,并为每个bin调用一函数。
as_record_iterator() — 记录全部bin的迭代器。
as_record_foreach
函数as_record_foreach()迭代一条记录的每一个bin,并为每个bin调用一函数。此函数还接受一个用户数据参数,可以是用户提供的、在回调函数内使用的任何数据。
下面的例子填充一个记录的数据,然后迭代遍历它的全部bin。
as_record rec; as_record_inita(&rec, 3); as_record_set_int64(&rec, "a", 1); as_record_set_int64(&rec, "b", 2); as_record_set_int64(&rec, "c", 3); as_record_foreach(&rec, callback, NULL);
这个例子使用的回调函数打印bin的名称和数值:
bool callback(const char *name, const as_val *value, void *udata) { as_integer *ivalue = as_integer_fromval(value); if (ivalue) { printf("%s = %d\n", name, as_integer_get(ivalue)); } else { printf("%s is not an integer?!\n", name); } return true; }
若回调函数返回true,继续迭代下一个bin,否则迭代中止。
as_record_iterator
as_record_iterator是一数据结构,提供迭代一条记录全部bin的能力。为使用as_record_iterator,首先需要初始化它:
as_record_iterator_init() — 初始化一个栈上分配的迭代器。
as_record_iterator_new() — 分配和初始化一个堆上分配的迭代器。
一旦迭代器初始化完成,就能使用下面的函数完成迭代器遍历:
as_record_iterator_has_next() — 检测是否还有更多的bin可遍历。
as_record_iterator_next() — 将迭代器移动到下一个bin,并返回此bin。
下面的示例,是前面foreach示例的迭代器实现方式:
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); char *name = as_bin_get_name(bin); as_val *value = (as_val*)as_bin_get_value(bin); as_integer *ivalue = as_integer_fromval(value); if (ivalue) { printf("%s = %d\n", name, as_integer_get(ivalue)); } else { printf("%s is not an integer?!\n", name); } }
记录与读取操作
读取操作从服务器取回数据并填充记录对象。下面是一些从服务器上读取记录数据的操作。
aerospike_key_get() — 读取一条记录的全部bin。在【读取记录】章节进一步讨论。
aerospike_key_select() — 读取一条记录的指定bin。在【读取记录】章节进一步讨论。
aerospike_key_operate() — 在一条记录上执行操作,包括读取指定bin。在【读取记录】章节进一步讨论。
每个操作接受一个记录对象作为参数(as_record **),用来接收从服务器读取的数据来。
下面解释一个记录对象如何被读取操作所填充。
空指针(NULL)记录
若记录对象参数是一个空指针(NULL),则读取操作会从堆上分配记录的空间,并且用足够多的bin个数初始化它,以容纳服务器返回的全部bin数据。
as_record *rec = NULL; aerospike_key_get(&as, &err, NULL, &key, &rec) as_record_destroy(rec);
当不再需要此记录对象时,必须通过as_record_destroy()释放其资源。
初始化完成的记录
初始化完成的记录被用作读取操作的参数。
若记录对象是以非零的bin个数初始化,读操作尝试以记录可用的bin尽可能多地填充它。作为一个例子,比如说初始化10个bin的一个记录对象,若服务器返回3个bin的数据,那么对象记录只有3个bin会被填充值;若服务器返回20个bin的数据,那么只有前10个bin数据会被填充到记录对象中。或者,若记录对象的10个bin只有5个bin可用,将它传送给读操作,那么只有这5个bin被来自服务器的数据填写。
若记录对象被初始化成没有bin,那读取操作将尝试从堆上分配足够多的bin空间,以容纳服务器端返回的全部bin数据。
在初始化记录对象时,可选择在栈上或堆上初始化它:
as_record