2)used
used表示data[DYN_ARRAY_DATA_SIZE]字段中已经使用的字节的数量,假设需要申请len字节的长度,在使用之前需要判断的是,尾 block中的可用空间是否够用。也就是判断判断下used+len是否满足used+len<= DYN_ARRAY_DATA_SIZE,如果满足就可以放进该block,并将已使用的字节数used加上len。
如果,该block空间不够,那么就会申请一个新的block,这里我们就可以明白了,为什么需要满足len的长度小于等于DYN_ARRAY_DATA_SIZE。
好,我们下面先看下分配空间的函数。
/*************************************************************************
Makes room on top of a dyn array and returns a pointer to the added element.
The caller must copy the element to the pointer returned. */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
/* out: pointer to the element */
dyn_array_t* arr, /* in: dynamic array */
ulint size) /* in: size in bytes of the element */
{
dyn_block_t* block;
ulint used;
slot->object = object; //对返回的指针进行操作
slot->type = type; //对返回的指针进行操作
}
通过上文的描述,我们可以使用dyn进行操作。分配一个元素,然后进行赋值。那么我们再思考下,有没有优化的可能?
假设现在一个应用场景:
我们需要插入三个元素,我们插入一个元素,就需要修改一次used,再插入,又得调用push函数进行操作。频繁的对dyn的数据结构进行操作。这样的效率是很低的。
这时候我们,会想到,为什么不直接一次申请大小长度为三个需要使用的总长度。假设这个总长度为len,那么我们是否就直接通过mtr_memo_push进行分配长度为len的空间?
好,这是可以的,但是,我们再假想一种情况,这三个元素的长度是变长的,我们没法预先知道这样的一个长度。假设可能需要10个字节,也可能需要12个字节,如果是分配了12个字节给它,那么就会多余两个。所以,我们可以事先通过一个新函数dyn_array_open来分配足够大的字节数,然后通过dyn_array_close进行重设used。
/*************************************************************************
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
dyn_array_close. */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
/* out: pointer to the buffer */
dyn_array_t* arr, /* in: dynamic array */
ulint size) /* in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_block_t* block;
ulint used;
arr->buf_end = used + size;
#endif
return((block->data) + used);
}
留意下,函数的英文注释“After copying the elements”,说明是赋值多元组的。而且和dyn_array_push函数相比,函数体里面没有对used进行重新赋值。这个重新赋值的工作留给了dyn_array_close函数,我们看下该函数的实现。
/*************************************************************************
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
dyn_array_t* arr, /* in: dynamic array */
byte* ptr) /* in: buffer space from ptr up was not used */
{
dyn_block_t* block;