程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> AerospikeC客戶端手冊———最佳實踐—記錄使用

AerospikeC客戶端手冊———最佳實踐—記錄使用

編輯:DB2教程

AerospikeC客戶端手冊———最佳實踐—記錄使用




記錄使用

記錄是Aerospike表示存儲在數據庫中數據的形式。記錄由元數據和多個bin組成。這些bin保存記錄的數據。每個bin有一個名稱與一個值。元數據是關於記錄的附加信息。在數據庫中使用鍵(key)查找記錄。

初始化記錄

通過下列函數之一可初始化一條記錄:
as_record_inita() — 在棧上初始化一條記錄及其bin。
as_record_init() — 在棧上初始化一條記錄,但在堆上分配bin。
as_record_new() — 在堆上分配一條記錄及其bin並初始化。

無論何時初始化的記錄,不再使用時應通過as_record_destroy()釋放資源。

棧上分配記錄

as_record_inita()與as_record_init()都在棧上分配且初始化一個記錄,但它們分配記錄bin的行為不同。

as_record_inita() 在棧上分配bin。
as_record_init() 在堆上分配bin。

下面是一個簡單的as_record_inita()例子。在使用上沒有區別,只是在如何分配空間上存在不同。

as_record rec;
as_record_inita(&rec, 3);
as_record_set_int64(&rec, 1);
as_record_set_int64(&rec, 2);
as_record_set_int64(&rec, 3);

as_record_destroy(&rec);

即使記錄和bin都是在棧上分配,bin值所用空間還是可能會從堆上分配。因此,應使用as_record_destroy()安全地釋放記錄及其相關資源。

堆上分配記錄

使用as_record_new()將在堆上分配記錄。

as_record *rec = as_record_new(10);
as_record_set_int64(rec, 1);
as_record_set_int64(rec, 2);
as_record_set_int64(rec, 3);

as_record_destroy(rec);

當不再需要此記錄時,應使用as_record_destroy()安全地釋放記錄及其相關資源。

訪問記錄的bin

API提供多種方法來訪問記錄的bin。

為訪問記錄的bin,首先需要初始化一條記錄並以bin數據填充。有兩種獲取記錄數據的方法:

初始化並填充記錄的bin。請參見【填充記錄的bin】。
從讀取操作的返回中獲取記錄數據。請參見【記錄與讀操作】。

一旦有個初始化完成的記錄,就可使用這些功能之一,讀取記錄的bin數據。

獲取Bin

API提供了一系列getter函數,從記錄中取出指定數據類型的bin數值。getter函數要求一個記錄對象與bin名稱做為參數。

下面的getter函數用於獲取bin的原生類型(native-type)數值:

as_record_get_int64()
as_record_get_str()

更詳細內容在【API文檔】。

以下是getter函數使用示例:

int64_t ibin = as_record_get_int64(rec, "ibin", 123);
char *sbin   = as_record_get_str(rec, "sbin");

下面的getter函數返回非原生類型數值的指針:

as_record_get_integer()
as_record_get_string()
as_record_get_bytes()
as_record_get_list()
as_record_get_map()

若應用保存這些getter函數返回的數值指針,然後銷毀了這條記錄,那麼指針將指向無效數據。為防止出現這種情況,可通過as_val_reserve()增加這些getter函數返回值的引用計數。

as_list *lbin = (as_list*)as_val_reserve(as_record_get_list(&rec, "lbin"));

as_record_destroy(&rec);

int64_t i1 = as_arraylist_get_int64(lbin, 1);
int64_t i2 = as_arraylist_get_int64(lbin, 2);
int64_t i3 = as_arraylist_get_int64(lbin, 3);

as_list_destroy(lbin);

上面代碼中的5-7行會有效地讀取數據。若as_val_reserve()沒被調用,就會引起無效讀取,可能導致數據損壞。完成數據讀取後,應使用相應的銷毀函數釋放它。

填充記錄的bin

在能填充一條記錄數據前,必須先初始化它。有三個初始化記錄的方法。

as_record_inita() — 在棧上初始化一條記錄及其bin。
as_record_init() — 在棧上初始化一條記錄,但在堆上分配bin。
as_record_new() — 在堆上分配一條記錄及其bin並初始化。

這些函數都接受一個參數指明需分配bin的個數,初始化完成的記錄能用來填充數據。

設置Bin值

有一系列的setter函數,用來設置不同數據類型的bin。每個setter函數要求一個記錄對象、一個bin名稱和一個bin值做為參數,操作成功返回true。

下面是設置原生類型bin數據的setter函數:

as_record_set_int64() — 設置一個int64_t類型的值。
as_record_set_str() — 設置值為一個以空字符(NULL)結束的字符串。
as_record_set_strp() — 設置值為一個以空字符(NULL)結束的字符串,指定在記錄銷毀時是否釋放原值所占用的空間。
as_record_set_raw() — 設置一個字節數組類型的值
as_record_set_rawp() — 設置一個字節數組類型的值,指明在記錄銷毀時是否釋放原值所占用的空間。

具體細節請參見【API文檔】。

下面是一些使用setter函數的例子:

as_record_set_int64(rec, "ibin", 123);
as_record_set_str(rec, "sbin", "abc");
as_record_set_strp(rec, "spbin", strdup("ijk"), true);
as_record_set_raw(rec, "rbin", (uint8_t*)"xyz", 3);

下列setter函數保持對非原生類型數據的指針引用:

as_record_set_integer() — Sets an as_integer value.
as_record_set_string() — Sets an as_string value.
as_record_set_bytes() — Sets an as_bytes value.
as_record_set_list() — Sets an as_list value.
as_record_set_map() — Sets an as_map value.

當通過as_record_destroy()釋放一個記錄,使用這些調用設置的值也將被釋放。若在其它地方使用這些值,在向記錄設置這些值時應用通過as_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_inita() — 在棧上初始化一條記錄及其bin。
as_record_init() — 在棧上初始化一條記錄,但在堆上分配bin。
as_record_new() — 在堆上分配一條記錄及其bin並初始化。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved