動態數組涉及的文件是innodb存儲引擎的三個文件:dyn0dyn.h、dyn0dyn.ic以及dyn0dyn.c。
這是一個基本的組件功能,是作為一個動態的虛擬線性數組。數組的基本元素是byte。動態數組dyn主要用來存放mtr的鎖定信息以及log。Dyn在實現上,如果block需要分裂節點,則會使用一個內存堆。每個blok塊存儲數據的數據字段的長度是固定的(默認值是512),但是不一定會完全用完。假設需要存儲的數據項的尺寸大於數據塊時,該數據項被分拆,這種情況主要用於log的緩沖。
2. 數據結構
typedef struct dyn_block_struct dyn_block_t;
typedef dyn_block_t dyn_array_t;
#defineDYN_ARRAY_DATA_SIZE 512
struct dyn_block_struct{
mem_heap_t* heap;
ulint used;
byte data[DYN_ARRAY_DATA_SIZE];
UT_LIST_BASE_NODE_T(dyn_block_t) base;
UT_LIST_NODE_T(dyn_block_t) list;
#ifdef UNIV_DEBUG
ulint buf_end;
ulint magic_n;
#endif
};
//下面兩個是公共宏定義,見ut0lst.h
#define UT_LIST_BASE_NODE_T(TYPE)
struct {
ulintcount;/* count of nodes in list */
TYPE *start;/* pointer to list start, NULL if empty */
TYPE *end;/* pointer to list end, NULL if empty */
}
#define UT_LIST_NODE_T(TYPE)
struct {
TYPE *prev;/* pointer to the previous node,
NULL if start of list */
TYPE *next;/* pointer to next node, NULL if end of list */
}
字段解釋:
1) heap
從字面上理解,heap是內存堆的意思。從上面的結構體中,我們可以看出,dyn_array_t就是dyn_block_struct。這個結構體裡面的字段date用來存放數據,used顯示已經使用的字節數量,假設這時候還要存儲一個大小為長度為x的數據,這時候data裡面已經存儲不了,所以就需要再分配一個新的block節點。那麼分配結構所需要的內存從哪裡來了,就從第一個節點裡面的heap裡面分配。
這裡面,我們還需要主意一點。雖然數據結構用的是同一個dyn_block_struct,但是我們稱第一個節點為arr,表明這個是動態數據的頭節點。其它的節點,我們稱為block節點。
我們這裡面先來看看,剛開始創立dyn的函數是怎麼實現的:
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
/* out: initialized dyn array */
dyn_array_t*arr)/* in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG);
arr->heap = NULL;
arr->used = 0;
#ifdef UNIV_DEBUG
arr->buf_end = 0;
arr->magic_n = DYN_BLOCK_MAGIC_N;
#endif
return(arr);
}
其中的ud_ad是屬於紅判斷,相當於assert。這個我們暫時不表。這個函數是在mtr創建的時候來調用的,在調用的時候已經分配了arr指針。
在dyn_array_create函數中,系統將heap字段設置為NULL,Used設置為0。Buf_end和magic_n是調試的時候使用的,每個結構體定義都會唯一的對應一個magic_n值。這樣在調試的時候,就可以快速進行問題的跟蹤。
下面一個問題是,既然heap在起初的設置為NULL,那麼什麼時候分配給它值?是第一次分配block成員的時候?還是每次分配block成員的時候?
我們這裡暫不分析如何插入,我們先看看,當dyn數組已經數據不夠用的時候,我們怎麼給這個arr增加一個新的block。代碼如下:
dyn_block_t*
dyn_array_add_block(
/*================*/
/* out: created block */
dyn_array_t*arr)/* in: dyn array */
{
mem_heap_t*heap;
dyn_block_t*block;
ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
if (arr->heap == NULL) {
UT_LIST_INIT(arr->base);
UT_LIST_ADD_FIRST(list, arr->base, arr);
ar
[1] [2] [3] [4] 下一頁