MySQL内核:innodb动态数组内部实现
2008-12-03 11:15:15 来源:WEB开发网假设现在一个应用场景:
我们需要插入三个元素,我们插入一个元素,就需要修改一次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;
ut_ad(arr);
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
ut_ad(size <= DYN_ARRAY_DATA_SIZE);
ut_ad(size);
block = arr;
used = block->used;
if (used + size > DYN_ARRAY_DATA_SIZE) {
/* Get the last array block */
block = dyn_array_get_last_block(arr);
used = block->used;
if (used + size > DYN_ARRAY_DATA_SIZE) {
block = dyn_array_add_block(arr);
used = block->used;
ut_a(size <= DYN_ARRAY_DATA_SIZE);
}
}
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
#ifdef UNIV_DEBUG
ut_ad(arr->buf_end == 0);
arr->buf_end = used + size;
#endif
return((block->data) + used);
}
留意下,函数的英文注释“After copying the elements”,说明是赋值多元组的。而且和dyn_array_push函数相比,函数体里面没有对used进行重新赋值。这个重新赋值的工作留给了dyn_array_close函数,我们看下该函数的实现。
更多精彩
赞助商链接